Skip to content

Commit

Permalink
Add memcmp syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Nov 18, 2023
1 parent f208896 commit 3f4826a
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 33 deletions.
62 changes: 43 additions & 19 deletions api/syscalls.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"description": "Core functionality provided by the VM that isn't related to any kind of I/O.",
"syscalls": [
{
"name": "memcpy",
"name": "memset",
"args": [
[
"u8*",
"dst"
],
[
"const u8*",
"src"
"u8",
"value"
],
[
"u64",
Expand All @@ -24,56 +24,80 @@
""
],
"permission": "default_allowed",
"const_idx": 3,
"description": "Copy a block of memory in the heap from a source address to a destination address."
"const_idx": 4,
"description": "Fill a block of bytes in the heap with a given value."
},
{
"name": "memset",
"name": "memset32",
"args": [
[
"u8*",
"u32*",
"dst"
],
[
"u8",
"value"
"u32",
"word"
],
[
"u64",
"num_bytes"
"num_words"
]
],
"returns": [
"void",
""
],
"permission": "default_allowed",
"const_idx": 4,
"description": "Fill a block of bytes in the heap with a given value."
"const_idx": 16,
"description": "Fill a region of memory with 32-bit values. This is useful for some graphics operations."
},
{
"name": "memset32",
"name": "memcpy",
"args": [
[
"u32*",
"u8*",
"dst"
],
[
"u32",
"word"
"const u8*",
"src"
],
[
"u64",
"num_words"
"num_bytes"
]
],
"returns": [
"void",
""
],
"permission": "default_allowed",
"const_idx": 16,
"description": "Fill a region of memory with 32-bit values. This is useful for some graphics operations."
"const_idx": 3,
"description": "Copy a block of memory in the heap from a source address to a destination address."
},
{
"name": "memcmp",
"args": [
[
"const u8*",
"p_a"
],
[
"const u8*",
"p_b"
],
[
"u64",
"num_bytes"
]
],
"returns": [
"u32",
"result"
],
"permission": "default_allowed",
"const_idx": 27,
"description": "Compare two sequences of bytes. Returns 0 if equal, -1 if the first mismatching byte has a lower value in p_a, 1 if greater."
},
{
"name": "vm_heap_size",
Expand Down
26 changes: 18 additions & 8 deletions doc/syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ The syscalls with a `void` return type do not output anything.

Core functionality provided by the VM that isn't related to any kind of I/O.

## memcpy

```
void memcpy(u8* dst, const u8* src, u64 num_bytes)
```

Copy a block of memory in the heap from a source address to a destination address.

## memset

```
Expand All @@ -38,6 +30,24 @@ void memset32(u32* dst, u32 word, u64 num_words)

Fill a region of memory with 32-bit values. This is useful for some graphics operations.

## memcpy

```
void memcpy(u8* dst, const u8* src, u64 num_bytes)
```

Copy a block of memory in the heap from a source address to a destination address.

## memcmp

```
u32 memcmp(const u8* p_a, const u8* p_b, u64 num_bytes)
```

**Returns:** `u32 result`

Compare two sequences of bytes. Returns 0 if equal, -1 if the first mismatching byte has a lower value in p_a, 1 if greater.

## vm_heap_size

```
Expand Down
12 changes: 8 additions & 4 deletions ncc/include/uvm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#ifndef __UVM_SYSCALLS__
#define __UVM_SYSCALLS__

// void memcpy(u8* dst, const u8* src, u64 num_bytes)
// Copy a block of memory in the heap from a source address to a destination address.
#define memcpy(__dst, __src, __num_bytes) asm (__dst, __src, __num_bytes) -> void { syscall memcpy; }

// void memset(u8* dst, u8 value, u64 num_bytes)
// Fill a block of bytes in the heap with a given value.
#define memset(__dst, __value, __num_bytes) asm (__dst, __value, __num_bytes) -> void { syscall memset; }
Expand All @@ -17,6 +13,14 @@
// Fill a region of memory with 32-bit values. This is useful for some graphics operations.
#define memset32(__dst, __word, __num_words) asm (__dst, __word, __num_words) -> void { syscall memset32; }

// void memcpy(u8* dst, const u8* src, u64 num_bytes)
// Copy a block of memory in the heap from a source address to a destination address.
#define memcpy(__dst, __src, __num_bytes) asm (__dst, __src, __num_bytes) -> void { syscall memcpy; }

// u32 memcmp(const u8* p_a, const u8* p_b, u64 num_bytes)
// Compare two sequences of bytes. Returns 0 if equal, -1 if the first mismatching byte has a lower value in p_a, 1 if greater.
#define memcmp(__p_a, __p_b, __num_bytes) asm (__p_a, __p_b, __num_bytes) -> u32 { syscall memcmp; }

// u64 vm_heap_size()
// Report the current heap size in bytes.
#define vm_heap_size() asm () -> u64 { syscall vm_heap_size; }
Expand Down
4 changes: 3 additions & 1 deletion vm/src/sys/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#![allow(unused)]

pub const SYSCALL_TBL_LEN: usize = 27;
pub const SYSCALL_TBL_LEN: usize = 28;

pub const TIME_CURRENT_MS: u16 = 0;
pub const WINDOW_CREATE: u16 = 1;
Expand Down Expand Up @@ -33,6 +33,7 @@ pub const NET_READ: u16 = 23;
pub const NET_WRITE: u16 = 24;
pub const NET_CLOSE: u16 = 25;
pub const PUTCHAR: u16 = 26;
pub const MEMCMP: u16 = 27;

pub struct SysCallDesc
{
Expand Down Expand Up @@ -70,6 +71,7 @@ pub const SYSCALL_DESCS: [Option<SysCallDesc>; SYSCALL_TBL_LEN] = [
Some(SysCallDesc { name: "net_write", const_idx: 24, argc: 3, has_ret: true }),
Some(SysCallDesc { name: "net_close", const_idx: 25, argc: 1, has_ret: false }),
Some(SysCallDesc { name: "putchar", const_idx: 26, argc: 1, has_ret: true }),
Some(SysCallDesc { name: "memcmp", const_idx: 27, argc: 3, has_ret: true }),
];

pub const KEY_BACKSPACE: u16 = 8;
Expand Down
16 changes: 15 additions & 1 deletion vm/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ impl SysState
self.reg_syscall(MEMSET, SysCallFn::Fn3_0(memset));
self.reg_syscall(MEMSET32, SysCallFn::Fn3_0(memset32));
self.reg_syscall(MEMCPY, SysCallFn::Fn3_0(memcpy));
self.reg_syscall(MEMCMP, SysCallFn::Fn3_1(memcmp));

self.reg_syscall(PRINT_I64, SysCallFn::Fn1_0(print_i64));
self.reg_syscall(PRINT_F32, SysCallFn::Fn1_0(print_f32));
Expand Down Expand Up @@ -252,6 +253,20 @@ fn memcpy(vm: &mut VM, dst_ptr: Value, src_ptr: Value, num_bytes: Value)
}
}

fn memcmp(vm: &mut VM, ptr_a: Value, ptr_b: Value, num_bytes: Value) -> Value
{
let num_bytes = num_bytes.as_usize();

unsafe {
let ptr_a: *const libc::c_void = vm.get_heap_ptr(ptr_a.as_usize());
let ptr_b: *const libc::c_void = vm.get_heap_ptr(ptr_b.as_usize());

let result = libc::memcmp(ptr_a, ptr_b, num_bytes);

Value::from(result as u64)
}
}

fn print_i64(vm: &mut VM, v: Value)
{
let v = v.as_i64();
Expand All @@ -277,7 +292,6 @@ fn print_endl(vm: &mut VM)
println!();
}


/// Write one byte of input to stdout.
/// Analogous to C's getchar
fn putchar(vm: &mut VM, byte: Value) -> Value
Expand Down

0 comments on commit 3f4826a

Please sign in to comment.