From 551bd2c3f4268679dc4553685e4da5bd0badedbf Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Tue, 10 Mar 2020 12:18:31 -0400 Subject: [PATCH] Add initial register states to meta section; remove entry directive It makes sense to allow users to set the initial register values. This allows someone to e.g. enable interrupts once the VM has started, or set the initial stack pointer value. Signed-off-by: Alek Ratzloff --- src/libvm/examples/deadbeef.asm | 11 +++++-- src/libvm/examples/factorial.asm | 2 +- src/libvm/examples/strings.asm | 2 +- src/libvm/src/state.rs | 39 ++++++++++++++++++++++-- tests/test_arithmetic.asm | 4 +-- tests/test_bitwise.asm | 2 +- tests/test_call.asm | 2 +- tests/test_interrupts.asm | 52 ++++++++++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 tests/test_interrupts.asm diff --git a/src/libvm/examples/deadbeef.asm b/src/libvm/examples/deadbeef.asm index c959627..d403574 100644 --- a/src/libvm/examples/deadbeef.asm +++ b/src/libvm/examples/deadbeef.asm @@ -40,6 +40,13 @@ .export ivt } -.meta { - entry: main +.section stack $0x4000 .. $0x5000 { + stack_base: + .export stack_base +} + +.meta { + ip: main + sp: stack_base + ivt: ivt } diff --git a/src/libvm/examples/factorial.asm b/src/libvm/examples/factorial.asm index 9444081..983b42e 100644 --- a/src/libvm/examples/factorial.asm +++ b/src/libvm/examples/factorial.asm @@ -24,5 +24,5 @@ } .meta { - entry: main + ip: main } diff --git a/src/libvm/examples/strings.asm b/src/libvm/examples/strings.asm index 11f8d2f..708ea20 100644 --- a/src/libvm/examples/strings.asm +++ b/src/libvm/examples/strings.asm @@ -26,5 +26,5 @@ } .meta { - entry: main + ip: main } diff --git a/src/libvm/src/state.rs b/src/libvm/src/state.rs index c2cd5e0..64e58bc 100644 --- a/src/libvm/src/state.rs +++ b/src/libvm/src/state.rs @@ -1,4 +1,13 @@ -use crate::{addr::*, error::*, flags::*, inst::*, interrupt::*, mem::*, obj::obj::*, reg::*}; +use crate::{ + addr::*, + error::*, + flags::*, + inst::*, + interrupt::*, + mem::*, + obj::{obj::*, syn::parser}, + reg::*, +}; use std::mem; pub struct State { @@ -37,8 +46,32 @@ impl State { } } Section::Meta(MetaSection { entries }) => { - if let Some(addr) = entries.get("entry") { - self.set_reg_unchecked(IP, *addr); + macro_rules! meta_addr { + ($($name:expr, $reg:expr);* $(;)?) => {{ + $( + if let Some(value) = entries.get($name) { + self.set_reg_unchecked($reg, *value); + } + )* + }}; + } + + meta_addr!("ip", IP); + meta_addr!("sp", SP); + meta_addr!("flags", FLAGS); + meta_addr!("status", STATUS); + meta_addr!("ivt", IVT); + + if let Some(value) = entries.get("fp") { + self.set_reg_unchecked(FP, *value); + } else { + self.set_reg_unchecked(FP, self.get_reg_unchecked(SP)); + } + + for (reg, value) in entries.iter() { + if let Some(reg) = parser::parse_reg(reg) { + self.set_reg_unchecked(reg, *value); + } } } } diff --git a/tests/test_arithmetic.asm b/tests/test_arithmetic.asm index b3e6115..831493f 100644 --- a/tests/test_arithmetic.asm +++ b/tests/test_arithmetic.asm @@ -1,4 +1,4 @@ -.section data $0x0 { +.section data $0x1000 { number: .u8 $10 main: @@ -109,6 +109,6 @@ } .meta { - entry: main + ip: main } diff --git a/tests/test_bitwise.asm b/tests/test_bitwise.asm index 1ff86bb..3be68c5 100644 --- a/tests/test_bitwise.asm +++ b/tests/test_bitwise.asm @@ -74,7 +74,7 @@ } .meta { - entry: main + ip: main } diff --git a/tests/test_call.asm b/tests/test_call.asm index 2855513..fc45650 100644 --- a/tests/test_call.asm +++ b/tests/test_call.asm @@ -31,6 +31,6 @@ } .meta { - entry: main + ip: main } diff --git a/tests/test_interrupts.asm b/tests/test_interrupts.asm new file mode 100644 index 0000000..4730b89 --- /dev/null +++ b/tests/test_interrupts.asm @@ -0,0 +1,52 @@ +.section code $0x0 { + main: + ; Test divide by zero interrupts + + ; div + mov %status, $1 + mov %r0, $1 + div %r0, $0 + cmpeq (count), $1 + jz end + + ; idiv + mov %status, $2 + idiv %r0, $0 + cmpeq (count), $2 + jz end + + mov %status, $0 + end: + halt + + .align u64 + divide_by_zero: + add (count), $1 + iret + + .export main + .export divide_by_zero +} + +.section ivt $0x1000 { + ivt: + .interrupt $1, divide_by_zero + .export ivt +} + +.section shared $0x2000 { + count: .u64 $0 + .export count +} + +.section stack $0x4000 .. $0x5000 { + stack_base: + .export stack_base +} + +.meta { + ip: main + flags: $0b100 + sp: stack_base + ivt: ivt +}