diff --git a/src/threads/thread.h b/src/threads/thread.h
index c1e7aabf2019e439c3433ecd8268c357a68ff7eb..f5988dacd053e53c60127da18d60d8655ebe8ca7 100644
--- a/src/threads/thread.h
+++ b/src/threads/thread.h
@@ -96,6 +96,9 @@ struct thread
 #ifdef USERPROG
     /* Owned by userprog/process.c. */
     uint32_t *pagedir;                  /* Page directory. */
+    uint8_t *current_esp;               /* The current value of the user program’s stack pointer.
+                                           A page fault might occur in the kernel, so we might
+                                           need to store esp on transition to kernel mode*/
 #endif
 
     /* Owned by thread.c. */
diff --git a/src/userprog/process.c b/src/userprog/process.c
index 859343107d05d4cc54dfa2101b6bb39c676941e7..e0f44086d4f4b6b53d10aafe4fae0993b4308a0d 100644
--- a/src/userprog/process.c
+++ b/src/userprog/process.c
@@ -45,7 +45,7 @@ process_execute(const char *file_name)
   /* Parse first argument as program name */
   strlcpy(program, file_name, file_name_length);
   strtok_r(program, " ", &ptr);
-  printf("\nProgram name: %s\n", program) ;
+  printf("\nProgram name: %s\n\n", program) ;
 
   /* Create a new thread to execute FILE_NAME. */
   tid = thread_create(file_name, PRI_DEFAULT, start_process, file_copy);
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 04635159d30520fa11296dc922e622f2ad2553d5..e32359c44826fcfd461f22eaa1c6298b568df68c 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -1,4 +1,5 @@
 #include "userprog/syscall.h"
+#include <stdbool.h>
 #include <stdio.h>
 #include <syscall-nr.h>
 #include "threads/interrupt.h"
@@ -6,16 +7,135 @@
 
 static void syscall_handler (struct intr_frame *);
 
+/*System call initializer*/
 void
 syscall_init (void) 
 {
   intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
 }
 
-
+/*Handler for system commands.*/
 static void
 syscall_handler (struct intr_frame *f UNUSED)
 {
-  printf ("system call!\n");
-  thread_exit ();
+  /* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 27/11/22]*/
+  int syscall_number;
+  ASSERT( sizeof(syscall_number) == 4 ); /*assuming x86*/
+
+  /*The system call number is in the 32-bit word at the caller's stack pointer.*/
+  read(f->esp, &syscall_number, sizeof(syscall_number));
+
+  /*Store the esp, which is needed in the page fault handler.*/
+  thread_current()->current_esp = f->esp;
+
+  switch (syscall_number) {
+  case SYS_HALT: // 0
+    {
+      /*Terminate PintOS*/
+      syscall_halt();
+      break;
+    }
+    case SYS_WAIT: // 2
+    {
+      tid_t tid;
+      /*Get argument*/
+      read(f->esp + 4, &tid, sizeof(tid_t));
+      /*Wait for child process*/
+      f->eax = syscall_wait(tid);
+      break;
+    }
+
+    case SYS_CREATE: // 3
+    {
+      const char* file_name;
+      unsigned initial_size;
+
+      /*Get file name and size*/
+      read(f->esp + 4, &file_name, sizeof(file_name));
+      read(f->esp + 8, &initial_size, sizeof(initial_size));
+
+      /*Create file*/
+      f->eax =  syscall_create(file_name, initial_size);
+      break;
+    }
+
+    case SYS_REMOVE: // 4
+    {
+      const char* file_name;
+      bool return_code;
+
+      /*Get file name*/
+      read(f->esp + 4, &file_name, sizeof(file_name));
+
+      /*Remove file*/
+      f->eax = syscall_remove(file_name);
+      break;
+    }
+    /* Unimplemented system calls */
+    default:
+        printf("ERROR: system call ( %d ) has not implemented!\n", syscall_number);
+
+    /* Terminate. */
+    syscall_exit(-1);
+    break;
+  }
+}
+
+
+/********SYSTEMCALLS********/
+
+/* Halt */
+void syscall_halt(void) {
+  shutdown_power_off(); /* From shutdown.h */
+}
+
+/* Exit */
+void syscall_exit(int status) {
+  struct thread *current_process=thread_current();
+  current_process->process_exit_status = status;
+
+  printf("%s: exit(%d)\n",current_process->name,status);
+
+  thread_exit();
+}
+
+/* Wait */
+int syscall_wait(tid_t tid)
+{
+  return process_wait(tid);
+}
+
+/* Create File */
+bool syscall_create(const char* file_name, unsigned initial_size) {
+  bool if_created = false;
+  if( filesys_create(file_name, initial_size)==true){
+    if_created = true;
+  }
+  return if_created;
+}
+
+/* Remove File */
+bool syscall_remove(const char* file_name) {
+  bool if_removed = false;
+  if( filesys_remove(file_name)==true){
+    if_removed = true;
+  }
+  return if_removed;
+}
+
+
+/****OTHER FUNCTIONS****/
+static int read(void *src, void *dst, size_t bytes)
+{
+  int32_t value;
+  size_t i;
+  for (i = 0; i < bytes; i++)
+  {
+    value = get_user(src + i);
+    if (value == -1) // segfault or invalid memory access
+      fail_invalid_access();
+
+    *(char *)(dst + i) = value & 0xff;
+  }
+  return (int)bytes;
 }
diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h
index 90590967a9f96f9ea359d15c672b815dfb4379cb..7289c248f8d431828c0ef068ade6c810cf1fb974 100644
--- a/src/userprog/syscall.h
+++ b/src/userprog/syscall.h
@@ -1,6 +1,17 @@
 #ifndef USERPROG_SYSCALL_H
 #define USERPROG_SYSCALL_H
+#include "threads/thread.h"
+#include <stdbool.h>
+#include <stddef.h>
 
 void syscall_init (void);
 
+void syscall_halt(void);
+void syscall_exit(int status);
+int syscall_wait(tid_t tid);
+bool syscall_create(const char* file_name, unsigned initial_size);
+bool syscall_remove(const char* file_name);
+
+static int read(void *src, void *dst, size_t bytes);
+
 #endif /* userprog/syscall.h */