From 665a4d70406a201bb8481fde0c9fbbead3477f00 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 8 Jul 2018 22:33:15 -0700 Subject: 4327 Encapsulate RAM management. --- subx/010core.cc | 51 +++++++++++++++++++++++++++++++++------ subx/011direct_addressing.cc | 8 +++---- subx/012indirect_addressing.cc | 52 ++++++++++++++++++++-------------------- subx/013immediate_addressing.cc | 20 ++++++++-------- subx/014index_addressing.cc | 10 ++++---- subx/017functions.cc | 4 ++-- subx/019syscalls.cc | 3 +-- subx/020elf.cc | 2 +- subx/021translate.cc | 2 +- subx/ex2 | Bin 10 files changed, 94 insertions(+), 58 deletions(-) mode change 100644 => 100755 subx/ex2 diff --git a/subx/010core.cc b/subx/010core.cc index 3b987ffb..a364f2f6 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -70,10 +70,47 @@ uint32_t End_of_program = 0; Mem.clear(); Mem.resize(1024); End_of_program = 0; -:(before "End Includes") -// depends on Mem being laid out contiguously (so you can't use a map, etc.) -// and on the host also being little-endian -#define SET_WORD_IN_MEM(addr, val) *reinterpret_cast(&Mem.at(addr)) = val; +:(code) +// These helpers depend on Mem being laid out contiguously (so you can't use a +// map, etc.) and on the host also being little-endian. +inline uint8_t read_mem_u8(uint32_t addr) { + return Mem.at(addr); +} +inline int8_t read_mem_i8(uint32_t addr) { + return static_cast(Mem.at(addr)); +} +inline uint32_t read_mem_u32(uint32_t addr) { + return *reinterpret_cast(&Mem.at(addr)); +} +inline int32_t read_mem_i32(uint32_t addr) { + return *reinterpret_cast(&Mem.at(addr)); +} + +inline uint8_t* mem_addr_u8(uint32_t addr) { + return &Mem.at(addr); +} +inline int8_t* mem_addr_i8(uint32_t addr) { + return reinterpret_cast(&Mem.at(addr)); +} +inline uint32_t* mem_addr_u32(uint32_t addr) { + return reinterpret_cast(&Mem.at(addr)); +} +inline int32_t* mem_addr_i32(uint32_t addr) { + return reinterpret_cast(&Mem.at(addr)); +} + +inline void write_mem_u8(uint32_t addr, uint8_t val) { + Mem.at(addr) = val; +} +inline void write_mem_i8(uint32_t addr, int8_t val) { + Mem.at(addr) = static_cast(val); +} +inline void write_mem_u32(uint32_t addr, uint32_t val) { + *reinterpret_cast(&Mem.at(addr)) = val; +} +inline void write_mem_i32(uint32_t addr, int32_t val) { + *reinterpret_cast(&Mem.at(addr)) = val; +} //:: core interpreter loop @@ -172,8 +209,8 @@ void load_program(istream& in, uint32_t addr) { raise << "input program truncated mid-byte\n" << end(); return; } - Mem.at(addr) = to_byte(c1, c2); - trace(99, "load") << addr << " -> " << HEXBYTE << NUM(Mem.at(addr)) << end(); + write_mem_u8(addr, to_byte(c1, c2)); + trace(99, "load") << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << end(); addr++; if (addr >= Mem.size()) Mem.resize(Mem.size()*2); } @@ -218,7 +255,7 @@ uint8_t to_hex_num(char c) { } inline uint8_t next() { - return Mem.at(EIP++); + return read_mem_u8(EIP++); } // read a 32-bit immediate in little-endian order from the instruction stream diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc index 5ce620ad..1e0375f6 100644 --- a/subx/011direct_addressing.cc +++ b/subx/011direct_addressing.cc @@ -42,7 +42,7 @@ int32_t* effective_address(uint8_t modrm) { //: other mods are indirect, and they'll set addr appropriately assert(addr > 0); assert(addr + sizeof(int32_t) <= Mem.size()); - return reinterpret_cast(&Mem.at(addr)); // rely on the host itself being in little-endian order + return mem_addr_i32(addr); } //:: subtract @@ -284,14 +284,14 @@ void push(uint32_t val) { Reg[ESP].u -= 4; trace(2, "run") << "decrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); trace(2, "run") << "pushing value 0x" << HEXWORD << val << end(); - *reinterpret_cast(&Mem.at(Reg[ESP].u)) = val; + write_mem_u32(Reg[ESP].u, val); } //:: pop :(scenario pop_r32) % Reg[ESP].u = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0000000a); +% write_mem_i32(0x60, 0x0000000a); # op ModR/M SIB displacement immediate 5b # pop stack to EBX +run: pop into EBX @@ -314,7 +314,7 @@ case 0x5f: { // pop stack into r32 } :(code) uint32_t pop() { - uint32_t result = *reinterpret_cast(&Mem.at(Reg[ESP].u)); + uint32_t result = read_mem_u32(Reg[ESP].u); trace(2, "run") << "popping value 0x" << HEXWORD << result << end(); Reg[ESP].u += 4; trace(2, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index 18ca6b5f..2901f8d5 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -3,7 +3,7 @@ :(scenario add_r32_to_mem_at_r32) % Reg[3].i = 0x10; % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 18 # add EBX to *EAX # ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) @@ -27,7 +27,7 @@ case 0: // indirect addressing :(scenario add_mem_at_r32_to_r32) % Reg[0].i = 0x60; % Reg[3].i = 0x10; -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 03 18 # add *EAX to EBX # ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) @@ -49,7 +49,7 @@ case 0x03: { // add r/m32 to r32 :(scenario subtract_r32_from_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 10); +% write_mem_i32(0x60, 10); % Reg[3].i = 1; # op ModR/M SIB displacement immediate 29 18 # subtract EBX from *EAX @@ -62,7 +62,7 @@ case 0x03: { // add r/m32 to r32 :(scenario subtract_mem_at_r32_from_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); % Reg[3].i = 10; # op ModR/M SIB displacement immediate 2b 18 # subtract *EAX from EBX @@ -85,7 +85,7 @@ case 0x2b: { // subtract r/m32 from r32 :(scenario and_r32_with_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0xff; # op ModR/M SIB displacement immediate 21 18 # and EBX with *EAX @@ -98,7 +98,7 @@ case 0x2b: { // subtract r/m32 from r32 :(scenario and_mem_at_r32_with_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x000000ff); +% write_mem_i32(0x60, 0x000000ff); % Reg[3].i = 0x0a0b0c0d; # op ModR/M SIB displacement immediate 23 18 # and *EAX with EBX @@ -121,7 +121,7 @@ case 0x23: { // and r/m32 with r32 :(scenario or_r32_with_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; # op ModR/M SIB displacement immediate 09 18 # or EBX with *EAX @@ -134,7 +134,7 @@ case 0x23: { // and r/m32 with r32 :(scenario or_mem_at_r32_with_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; # op ModR/M SIB displacement immediate 0b 18 # or *EAX with EBX @@ -157,7 +157,7 @@ case 0x0b: { // or r/m32 with r32 :(scenario xor_r32_with_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0xaabb0c0d); +% write_mem_i32(0x60, 0xaabb0c0d); % Reg[3].i = 0xa0b0c0d0; # op ModR/M SIB displacement immediate 31 18 # xor EBX with *EAX @@ -170,7 +170,7 @@ case 0x0b: { // or r/m32 with r32 :(scenario xor_mem_at_r32_with_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; # op ModR/M SIB displacement immediate 33 18 # xor *EAX with EBX @@ -194,7 +194,7 @@ case 0x33: { // xor r/m32 with r32 :(scenario not_r32_with_mem_at_r32) % Reg[3].i = 0x60; # word at 0x60 is 0x0f0f00ff -% SET_WORD_IN_MEM(0x60, 0x0f0f00ff); +% write_mem_i32(0x60, 0x0f0f00ff); # op ModR/M SIB displacement immediate f7 03 # negate *EBX # ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX) @@ -206,7 +206,7 @@ case 0x33: { // xor r/m32 with r32 :(scenario compare_mem_at_r32_with_r32_greater) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c07; # op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX @@ -217,7 +217,7 @@ case 0x33: { // xor r/m32 with r32 :(scenario compare_mem_at_r32_with_r32_lesser) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c07); +% write_mem_i32(0x60, 0x0a0b0c07); % Reg[3].i = 0x0a0b0c0d; # op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX @@ -228,7 +228,7 @@ case 0x33: { // xor r/m32 with r32 :(scenario compare_mem_at_r32_with_r32_equal) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c0d; # op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX @@ -241,7 +241,7 @@ case 0x33: { // xor r/m32 with r32 :(scenario compare_r32_with_mem_at_r32_greater) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c07); +% write_mem_i32(0x60, 0x0a0b0c07); % Reg[3].i = 0x0a0b0c0d; # op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX @@ -268,7 +268,7 @@ case 0x3b: { // set SF if r32 < r/m32 :(scenario compare_r32_with_mem_at_r32_lesser) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c07; # op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX @@ -279,7 +279,7 @@ case 0x3b: { // set SF if r32 < r/m32 :(scenario compare_r32_with_mem_at_r32_equal) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); +% write_mem_i32(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c0d; # op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX @@ -304,7 +304,7 @@ case 0x3b: { // set SF if r32 < r/m32 :(scenario copy_mem_at_r32_to_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x000000af); +% write_mem_i32(0x60, 0x000000af); # op ModR/M SIB displacement immediate 8b 18 # copy *EAX to EBX # ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) @@ -327,7 +327,7 @@ case 0x8b: { // copy r32 to r/m32 :(scenario jump_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 8); +% write_mem_i32(0x60, 8); # op ModR/M SIB displacement immediate ff 20 # jump to *EAX # ModR/M in binary: 00 (indirect mode) 100 (jump to r/m32) 000 (src EAX) @@ -361,7 +361,7 @@ case 0xff: { :(scenario push_mem_at_r32) % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x000000af); +% write_mem_i32(0x60, 0x000000af); % Reg[ESP].u = 0x14; # op ModR/M SIB displacement immediate ff 30 # push *EAX to stack @@ -384,7 +384,7 @@ case 6: { // push r/m32 to stack :(scenario pop_mem_at_r32) % Reg[0].i = 0x60; % Reg[ESP].u = 0x10; -% SET_WORD_IN_MEM(0x10, 0x00000030); +% write_mem_i32(0x10, 0x00000030); # op ModR/M SIB displacement immediate 8f 00 # pop stack into *EAX # ModR/M in binary: 00 (indirect mode) 000 (pop r/m32) 000 (dest EAX) @@ -412,7 +412,7 @@ case 0x8f: { // pop stack into r/m32 :(scenario add_r32_to_mem_at_displacement) % Reg[3].i = 0x10; // source -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 1d 60 00 00 00 # add EBX to *0x60 # ModR/M in binary: 00 (indirect mode) 011 (src EBX) 101 (dest in disp32) @@ -431,7 +431,7 @@ case 5: // exception: mod 0b00 rm 0b101 => incoming disp32 :(scenario add_r32_to_mem_at_r32_plus_disp8) % Reg[3].i = 0x10; // source % Reg[0].i = 0x5e; // dest -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 58 02 # add EBX to *(EAX+2) # ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 000 (dest EAX) @@ -458,7 +458,7 @@ case 1: // indirect + disp8 addressing :(scenario add_r32_to_mem_at_r32_plus_negative_disp8) % Reg[3].i = 0x10; // source % Reg[0].i = 0x61; // dest -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 58 ff # add EBX to *(EAX-1) # ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 000 (dest EAX) @@ -472,7 +472,7 @@ case 1: // indirect + disp8 addressing :(scenario add_r32_to_mem_at_r32_plus_disp32) % Reg[3].i = 0x10; // source % Reg[0].i = 0x5e; // dest -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 98 02 00 00 00 # add EBX to *(EAX+2) # ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 000 (dest EAX) @@ -499,7 +499,7 @@ case 2: // indirect + disp32 addressing :(scenario add_r32_to_mem_at_r32_plus_negative_disp32) % Reg[3].i = 0x10; // source % Reg[0].i = 0x61; // dest -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 98 ff ff ff ff # add EBX to *(EAX-1) # ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 000 (dest EAX) diff --git a/subx/013immediate_addressing.cc b/subx/013immediate_addressing.cc index beb6ad3a..78510535 100644 --- a/subx/013immediate_addressing.cc +++ b/subx/013immediate_addressing.cc @@ -34,7 +34,7 @@ case 0x81: { // combine imm32 with r/m32 :(scenario add_imm32_to_mem_at_r32) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 81 03 0a 0b 0c 0d # add 0x0d0c0b0a to *EBX # ModR/M in binary: 00 (indirect mode) 000 (add imm32) 011 (dest EBX) @@ -64,7 +64,7 @@ case 0x2d: { // subtract imm32 from EAX :(scenario subtract_imm32_from_mem_at_r32) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 10); +% write_mem_i32(0x60, 10); # op ModR/M SIB displacement immediate 81 2b 01 00 00 00 # subtract 1 from *EBX # ModR/M in binary: 00 (indirect mode) 101 (subtract imm32) 011 (dest EBX) @@ -113,7 +113,7 @@ case 0x25: { // and imm32 with EAX :(scenario and_imm32_with_mem_at_r32) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x000000ff); +% write_mem_i32(0x60, 0x000000ff); # op ModR/M SIB displacement immediate 81 23 0a 0b 0c 0d # and 0x0d0c0b0a with *EBX # ModR/M in binary: 00 (indirect mode) 100 (and imm32) 011 (dest EBX) @@ -162,7 +162,7 @@ case 0x0d: { // or imm32 with EAX :(scenario or_imm32_with_mem_at_r32) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0xd0c0b0a0); +% write_mem_i32(0x60, 0xd0c0b0a0); # op ModR/M SIB displacement immediate 81 0b 0a 0b 0c 0d # or 0x0d0c0b0a with *EBX # ModR/M in binary: 00 (indirect mode) 001 (or imm32) 011 (dest EBX) @@ -209,7 +209,7 @@ case 0x35: { // xor imm32 with EAX :(scenario xor_imm32_with_mem_at_r32) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0xd0c0b0a0); +% write_mem_i32(0x60, 0xd0c0b0a0); # op ModR/M SIB displacement immediate 81 33 0a 0b 0c 0d # xor 0x0d0c0b0a with *EBX # ModR/M in binary: 00 (indirect mode) 110 (xor imm32) 011 (dest EBX) @@ -315,7 +315,7 @@ case 7: { :(scenario compare_imm32_with_mem_at_r32_greater) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0d0c0b0a); +% write_mem_i32(0x60, 0x0d0c0b0a); # op ModR/M SIB displacement immediate 81 3b 07 0b 0c 0d # compare 0x0d0c0b07 with *EBX # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) @@ -325,7 +325,7 @@ case 7: { :(scenario compare_imm32_with_mem_at_r32_lesser) % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0d0c0b07); +% write_mem_i32(0x60, 0x0d0c0b07); # op ModR/M SIB displacement immediate 81 3b 0a 0b 0c 0d # compare 0x0d0c0b0a with *EBX # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) @@ -336,7 +336,7 @@ case 7: { :(scenario compare_imm32_with_mem_at_r32_equal) % Reg[3].i = 0x0d0c0b0a; % Reg[3].i = 0x60; -% SET_WORD_IN_MEM(0x60, 0x0d0c0b0a); +% write_mem_i32(0x60, 0x0d0c0b0a); # op ModR/M SIB displacement immediate 81 3b 0a 0b 0c 0d # compare 0x0d0c0b0a with *EBX # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) @@ -402,8 +402,8 @@ case 0x68: { int32_t val = imm32(); trace(2, "run") << "push imm32 0x" << HEXWORD << val << end(); Reg[ESP].u -= 4; - *reinterpret_cast(&Mem.at(Reg[ESP].u)) = val; + write_mem_i32(Reg[ESP].u, val); trace(2, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); - trace(2, "run") << "contents at ESP: 0x" << HEXWORD << *reinterpret_cast(&Mem.at(Reg[ESP].u)) << end(); + trace(2, "run") << "contents at ESP: 0x" << HEXWORD << read_mem_u32(Reg[ESP].u) << end(); break; } diff --git a/subx/014index_addressing.cc b/subx/014index_addressing.cc index e811290d..6b07436f 100644 --- a/subx/014index_addressing.cc +++ b/subx/014index_addressing.cc @@ -3,7 +3,7 @@ :(scenario add_r32_to_mem_at_r32_with_sib) % Reg[3].i = 0x10; % Reg[0].i = 0x60; -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 1c 20 # add EBX to *EAX # ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB) @@ -48,7 +48,7 @@ uint32_t effective_address_from_sib(uint8_t mod) { % Reg[3].i = 0x10; // source % Reg[0].i = 0x5e; // dest base % Reg[1].i = 0x2; // dest index -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 1c 08 # add EBX to *(EAX+ECX) # ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB) @@ -60,7 +60,7 @@ uint32_t effective_address_from_sib(uint8_t mod) { :(scenario add_r32_to_mem_at_displacement_using_sib) % Reg[3].i = 0x10; // source -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 1c 25 60 00 00 00 # add EBX to *0x60 # ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB) @@ -76,7 +76,7 @@ uint32_t effective_address_from_sib(uint8_t mod) { % Reg[3].i = 0x10; // source % Reg[0].i = 0x59; // dest base % Reg[1].i = 0x5; // dest index -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 5c 08 02 # add EBX to *(EAX+ECX+2) # ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 100 (dest in SIB) @@ -98,7 +98,7 @@ case 4: // exception: mod 0b01 rm 0b100 => incoming SIB (scale-index-base) byte % Reg[3].i = 0x10; // source % Reg[0].i = 0x59; // dest base % Reg[1].i = 0x5; // dest index -% SET_WORD_IN_MEM(0x60, 1); +% write_mem_i32(0x60, 1); # op ModR/M SIB displacement immediate 01 9c 08 02 00 00 00 # add EBX to *(EAX+ECX+2) # ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 100 (dest in SIB) diff --git a/subx/017functions.cc b/subx/017functions.cc index 08bfb793..13ac41d9 100644 --- a/subx/017functions.cc +++ b/subx/017functions.cc @@ -47,7 +47,7 @@ case 2: { // call function pointer at r/m32 :(scenario call_mem_at_r32) % Reg[ESP].u = 0x64; % Reg[EBX].u = 0x10; -% SET_WORD_IN_MEM(0x10, 0x000000a0); +% write_mem_i32(0x10, 0x000000a0); # op ModR/M SIB displacement immediate ff 13 # call function offset at *EBX # next EIP is 3 @@ -61,7 +61,7 @@ case 2: { // call function pointer at r/m32 :(scenario ret) % Reg[ESP].u = 0x60; -% SET_WORD_IN_MEM(0x60, 0x00000010); +% write_mem_i32(0x60, 0x00000010); # op ModR/M SIB displacement immediate c3 +run: return diff --git a/subx/019syscalls.cc b/subx/019syscalls.cc index b83b92db..a43e3b8f 100644 --- a/subx/019syscalls.cc +++ b/subx/019syscalls.cc @@ -14,11 +14,10 @@ case 0xcd: { // int imm8 (software interrupt) void process_int80() { switch (Reg[EAX].u) { case 1: - cerr << "result: " << NUM(Mem.at(0x08048000)) << '\n'; exit(Reg[EBX].u); break; case 3: - read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/&Mem.at(Reg[ECX].u), /*size*/Reg[EDX].u); + read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); break; } } diff --git a/subx/020elf.cc b/subx/020elf.cc index a67bfdfe..d5f1e109 100644 --- a/subx/020elf.cc +++ b/subx/020elf.cc @@ -85,7 +85,7 @@ void load_segment_from_program_header(uint8_t* elf_contents, size_t size, uint32 if (size > p_memsz) size = p_memsz; info << "blitting file offsets (" << p_offset << ", " << (p_offset+p_filesz) << ") to addresses (" << p_vaddr << ", " << (p_vaddr+p_memsz) << ")\n"; for (size_t i = 0; i < p_filesz; ++i) - Mem.at(p_vaddr + i) = elf_contents[p_offset + i]; + write_mem_u8(p_vaddr+i, elf_contents[p_offset+i]); if (End_of_program < p_vaddr+p_memsz) End_of_program = p_vaddr+p_memsz; } diff --git a/subx/021translate.cc b/subx/021translate.cc index b8e5159a..5757805e 100644 --- a/subx/021translate.cc +++ b/subx/021translate.cc @@ -43,7 +43,7 @@ void dump_elf(const string& program, const char* filename) { ofstream out(filename, ios::binary); dump_elf_header(out); for (size_t i = 1; i < End_of_program; ++i) { - char c = Mem.at(i); + char c = read_mem_u8(i); out.write(&c, sizeof(c)); } out.close(); diff --git a/subx/ex2 b/subx/ex2 old mode 100644 new mode 100755 -- cgit 1.4.1-2-gfad0