diff --git a/userprog/argument_parsing.h b/userprog/argument_parsing.h
index 78f4e0eca38b95a4c16e3963d9944105bc1906ef..d5cef69f63d1e20c7ab9ee15d643ee9390064401 100644
--- a/userprog/argument_parsing.h
+++ b/userprog/argument_parsing.h
@@ -3,12 +3,11 @@
 
 /*
  * Given a string containing the command invoking the program `command_line`
- * and a pointer to an array of C strings (pointer to `char* argv[]`), parse
- * `command_line` into individual arguments, populate `argv` with these and
- * return the number of arguments that were parsed (this is the value that can
- * be used for `argc`).
+ * and an array of C strings (pointer to `char* argv[]`), parse `command_line`
+ * into individual arguments, populate `argv` with these and return the number
+ * of arguments that were parsed (this is the value that can be used for `argc`).
  */
-int parse_arguments(const char* command_line, char***argv);
+int parse_arguments(const char* command_line, char**argv);
 
 /*
  * Given stack pointer `esp`, argument count `argc` and arguments array `argv`,
diff --git a/userprog/parse_arguments.c b/userprog/parse_arguments.c
index aeaefd0778156808a54f8c2b1da7b1197886efbc..c86364fdd2408b978f019f9df3d7c09a48b0ec31 100644
--- a/userprog/parse_arguments.c
+++ b/userprog/parse_arguments.c
@@ -1,6 +1,11 @@
 #include "userprog/argument_parsing.h"
 
 
-int parse_arguments(const char* command_line, char***argv) {
-    #warning "Implement me"
+int parse_arguments(const char* command_line, char**argv) {
+    /*
+     * XXX: Dummy implementation which sets argv[0] to "echo" so at least there's
+     * a filename to load.
+     */
+    argv[0] = "echo";
+    return 1;
 }
diff --git a/userprog/process.c b/userprog/process.c
index 7aa158189374917306d5021e01bc54caea8b38fe..87fd42a738663bdcfd7c5d2e1da8f92bc950bee4 100644
--- a/userprog/process.c
+++ b/userprog/process.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "userprog/argument_parsing.h"
 #include "userprog/gdt.h"
 #include "userprog/pagedir.h"
 #include "userprog/tss.h"
@@ -19,7 +20,7 @@
 #include "threads/vaddr.h"
 
 static thread_func start_process NO_RETURN;
-static bool load (const char *cmdline, void (**eip) (void), void **esp);
+static bool load (const char *command, void (**eip) (void), void **esp);
 
 /* Starts a new thread running a user program loaded by parsing
    COMMAND. The new thread may be scheduled (and may even exit)
@@ -29,24 +30,22 @@ tid_t
 process_execute (const char *command)
 {
   char *command_copy;
-  tid_t tid;
-
   /* Make a copy of COMMAND.
      Otherwise there's a race between the caller and load(). */
   command_copy = palloc_get_page (0);
   if (command_copy == NULL)
     return TID_ERROR;
   strlcpy (command_copy, command, PGSIZE);
+  // we need to extract out the filename from the command string
+  char* file_name;
+  char* save_ptr; // this is the save pointer expected by strtok_r()
+  // file name is the first part of the command-line (space-delimited)
+  file_name = strtok_r(command, " ", &save_ptr);
+  tid_t tid;
+
 
   /* Create a new thread to execute COMMAND. */
-  /*
-   * FIXME: right now, COMMAND is assumed to be just the filename on its own
-   *
-   * If this is not the case (if the user passed a program name with arguments),
-   * then loading will fail.
-   * NOTE: remove this comment block when argument parsing is implemented.
-   */
-  tid = thread_create (command, PRI_DEFAULT, start_process, command_copy);
+  tid = thread_create (file_name, PRI_DEFAULT, start_process, command_copy);
 
   if (tid == TID_ERROR)
     palloc_free_page (command_copy);
@@ -212,18 +211,18 @@ struct Elf32_Phdr
 #define PF_W 2          /* Writable. */
 #define PF_R 4          /* Readable. */
 
-static bool setup_stack (void **esp);
+static bool setup_stack (void **esp, char **argv, int argc);
 static bool validate_segment (const struct Elf32_Phdr *, struct file *);
 static bool load_segment (struct file *file, off_t ofs, uint8_t *upage,
                           uint32_t read_bytes, uint32_t zero_bytes,
                           bool writable);
 
-/* Loads an ELF executable from FILE_NAME into the current thread.
+/* Loads an ELF executable from COMMAND into the current thread.
    Stores the executable's entry point into *EIP
    and its initial stack pointer into *ESP.
    Returns true if successful, false otherwise. */
 bool
-load (const char *file_name, void (**eip) (void), void **esp) 
+load (const char *command, void (**eip) (void), void **esp)
 {
   struct thread *t = thread_current ();
   struct Elf32_Ehdr ehdr;
@@ -232,6 +231,12 @@ load (const char *file_name, void (**eip) (void), void **esp)
   bool success = false;
   int i;
 
+  // extract arguments (including file name)
+  // NOTE: decide how many arguments we want --is 255 the standard number?
+  char* argv[255];
+  int argc = parse_arguments(command, argv);
+  char* file_name = argv[0]; // file name is always argument 0
+
   /* Allocate and activate page directory. */
   t->pagedir = pagedir_create ();
   if (t->pagedir == NULL) 
@@ -320,7 +325,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
     }
 
   /* Set up stack. */
-  if (!setup_stack (esp))
+  if (!setup_stack (esp, argv, argc))
     goto done;
 
   /* Start address. */
@@ -445,7 +450,7 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
 /* Create a minimal stack by mapping a zeroed page at the top of
    user virtual memory. */
 static bool
-setup_stack (void **esp) 
+setup_stack (void **esp, char **argv, int argc)
 {
   uint8_t *kpage;
   bool success = false;
@@ -456,6 +461,7 @@ setup_stack (void **esp)
       success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
       if (success) {
         *esp = PHYS_BASE - 12;
+        populate_stack(esp, argc, argv);
       } else
         palloc_free_page (kpage);
     }