From 1a48f95a870559112eb7d3a6ecf236c78db13f5b Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 10 Jul 2018 20:27:21 -0700 Subject: [PATCH] 4338 - preliminary support for data segments --- subx/010core.cc | 25 ++++++++++++++++++++----- subx/012indirect_addressing.cc | 5 ++++- subx/021translate.cc | 6 +++--- subx/022transform_immediate.cc | 11 +++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/subx/010core.cc b/subx/010core.cc index f6c79a78..c881c52b 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -140,7 +140,7 @@ inline void write_mem_i32(uint32_t addr, int32_t val) { void run(string text_bytes) { // Begin run() For Scenarios //? cerr << text_bytes << '\n'; - load_program(text_bytes, 1); // tests always assume a starting address of 1 + load_program(text_bytes); EIP = 1; // preserve null pointer while (EIP < End_of_program) run_one_instruction(); @@ -193,11 +193,13 @@ void run_one_instruction() { } } -void load_program(const string& text_bytes, uint32_t addr) { +void load_program(const string& text_bytes) { istringstream in(text_bytes); - load_program(in, addr); + load_program(in); } -void load_program(istream& in, uint32_t addr) { +void load_program(istream& in) { + uint32_t addr = 1; // preserve null pointer + int segment_index = 0; while (has_data(in)) { string line_data; getline(in, line_data); @@ -207,6 +209,18 @@ void load_program(istream& in, uint32_t addr) { string word; line >> word; if (word.empty()) continue; + if (word == "==") { + // assume the first segment contains code + if (segment_index == 1) End_of_program = addr; + ++segment_index; + // new segment + line >> std::hex >> addr; + break; // skip rest of line + } + if (word[0] == ':') { + // metadata + break; + } if (word[0] == '#') { // comment break; @@ -225,7 +239,8 @@ void load_program(istream& in, uint32_t addr) { addr++; } } - End_of_program = addr; + // convenience: allow zero segment headers; code then starts at address 1 + if (segment_index == 0) End_of_program = addr; } inline uint8_t next() { diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index 2901f8d5..304467f7 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -1,12 +1,15 @@ //: operating on memory at the address provided by some register +//: we'll now start providing data in a separate segment :(scenario add_r32_to_mem_at_r32) % Reg[3].i = 0x10; % Reg[0].i = 0x60; -% write_mem_i32(0x60, 1); +== 0x01 # code segment # 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) +== 0x60 # data segment +01 00 00 00 # 1 +run: add EBX to r/m32 +run: effective address is 0x60 (EAX) +run: storing 0x00000011 diff --git a/subx/021translate.cc b/subx/021translate.cc index 6d0fb899..f658f6db 100644 --- a/subx/021translate.cc +++ b/subx/021translate.cc @@ -34,9 +34,9 @@ void perform_all_transforms(string& program) { void dump_elf(const string& program, const char* filename) { initialize_mem(); // load program into memory, filtering out comments - load_program(program, 1); // Not where 'program' should be loaded for running. - // But we're not going to run it right now, so we - // can load it anywhere. + load_program(program); // Not where 'program' should be loaded for running. + // But we're not going to run it right now, so we + // can load it anywhere. // dump contents of memory into ELF binary ofstream out(filename, ios::binary); dump_elf_header(out); diff --git a/subx/022transform_immediate.cc b/subx/022transform_immediate.cc index 48f5dfa9..24539f10 100644 --- a/subx/022transform_immediate.cc +++ b/subx/022transform_immediate.cc @@ -32,6 +32,17 @@ void transform_immediate(const string& input, string& output) { string word; line >> word; if (word.empty()) continue; + if (word == "==") { + // new segment + uint32_t addr = 0; + line >> std::hex >> addr; + out << "== " << HEXWORD << addr; + break; // skip rest of line + } + if (word[0] == ':') { + // skip line metadata + break; + } if (word[0] == '#') { // skip comment break;