diff --git a/syscall/mod.rs b/syscall/mod.rs
index cd71b7653f1dc26293824484f8c15181df29cf7f..c64caa7e85353ab229068f0bc855455f714849ed 100644
--- a/syscall/mod.rs
+++ b/syscall/mod.rs
@@ -24,6 +24,8 @@ pub enum Call {
     Open,
     /// Close syscall
     Close,
+    /// Execute syscall
+    Exec,
     /// Unknown syscall
     Unknown
 }
@@ -38,6 +40,7 @@ impl From<usize> for Call {
             4 => Call::Write,
             5 => Call::Open,
             6 => Call::Close,
+            11 => Call::Exec,
             _ => Call::Unknown
         }
     }
@@ -73,23 +76,24 @@ pub type Result<T> = ::core::result::Result<T, Error>;
 
 /// Convert a pointer and length to slice, if valid
 /// TODO: Check validity
-pub fn convert_slice(ptr: usize, len: usize) -> Result<&'static [u8]> {
-    Ok(unsafe { slice::from_raw_parts(ptr as *const u8, len) })
+pub fn convert_slice<T>(ptr: *const T, len: usize) -> Result<&'static [T]> {
+    Ok(unsafe { slice::from_raw_parts(ptr, len) })
 }
 
 /// Convert a pointer and length to slice, if valid
 /// TODO: Check validity
-pub fn convert_slice_mut(ptr: usize, len: usize) -> Result<&'static mut [u8]> {
-    Ok(unsafe { slice::from_raw_parts_mut(ptr as *mut u8, len) })
+pub fn convert_slice_mut<T>(ptr: *mut T, len: usize) -> Result<&'static mut [T]> {
+    Ok(unsafe { slice::from_raw_parts_mut(ptr, len) })
 }
 
-pub fn handle(a: usize, b: usize, c: usize, d: usize) -> ::core::result::Result<usize, usize> {
+pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> ::core::result::Result<usize, usize> {
     match Call::from(a) {
         Call::Exit => exit(b),
-        Call::Read => read(b, convert_slice_mut(c, d)?),
-        Call::Write => write(b, convert_slice(c, d)?),
-        Call::Open => open(convert_slice(b, c)?, d),
+        Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?),
+        Call::Write => write(b, convert_slice(c as *const u8, d)?),
+        Call::Open => open(convert_slice(b as *const u8, c)?, d),
         Call::Close => close(b),
+        Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?),
         Call::Unknown => Err(Error::NoCall)
     }.map_err(|err| err.into())
 }
diff --git a/syscall/process.rs b/syscall/process.rs
index 6cbe1ec74dc3347b4991a6171fb1dcd45654ad30..6daf73af21b49b4e474e348af86942b123bf1b1c 100644
--- a/syscall/process.rs
+++ b/syscall/process.rs
@@ -2,9 +2,20 @@
 
 use arch::interrupt::halt;
 
+use super::{convert_slice, Result};
+
 pub fn exit(status: usize) -> ! {
     println!("Exit {}", status);
     loop {
         unsafe { halt() };
     }
 }
+
+pub fn exec(path: &[u8], args: &[[usize; 2]]) -> Result<usize> {
+    print!("Exec {:?}", ::core::str::from_utf8(path));
+    for arg in args {
+        print!(" {:?}", ::core::str::from_utf8(convert_slice(arg[0] as *const u8, arg[1])?));
+    }
+    println!("");
+    Ok(0)
+}