diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-10-15 01:59:11 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-10-15 01:59:11 -0700 |
commit | 95e5511ab8736f6fd9953fe66a05096b79afae16 (patch) | |
tree | a8602cedc6c70109c04d917fc111c845040d1e58 /subx | |
parent | 1ee02a2273a10cc30d5dd5e07be1e5ee6a392e55 (diff) | |
download | mu-95e5511ab8736f6fd9953fe66a05096b79afae16.tar.gz |
4069
subx: unconditional 'jump'
Diffstat (limited to 'subx')
-rw-r--r-- | subx/010core.cc | 2 | ||||
-rw-r--r-- | subx/012indirect_addressing.cc | 32 | ||||
-rw-r--r-- | subx/013immediate_addressing.cc | 46 |
3 files changed, 80 insertions, 0 deletions
diff --git a/subx/010core.cc b/subx/010core.cc index 42445afd..8040a645 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -106,6 +106,7 @@ void run(const string& text_bytes) { // skeleton of how x86 instructions are decoded void run_one_instruction() { uint8_t op=0, op2=0, op3=0; + trace(2, "run") << "inst: 0x" << HEXWORD << EIP << end(); switch (op = next()) { case 0xf4: // hlt EIP = End_of_program; @@ -185,6 +186,7 @@ char next_hex_byte(istream& in) { } } } + if (c == '\0') return c; if (c >= '0' && c <= '9') return c; if (c >= 'a' && c <= 'f') return c; if (c >= 'A' && c <= 'F') return tolower(c); diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index 3b2944b2..1bf5e378 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -305,3 +305,35 @@ case 0x8b: { // copy r32 to r/m32 trace(2, "run") << "storing 0x" << HEXWORD << *arg2 << end(); break; } + +//:: jump + +:(scenario jump_mem_at_r32) +% Reg[0].i = 0x60; +% SET_WORD_IN_MEM(0x60, 8); +# op ModRM SIB displacement immediate + ff 20 # jump to *EAX (reg 0) + 05 00 00 00 01 + 05 00 00 00 02 ++run: inst: 0x00000001 ++run: jump to effective address ++run: effective address is mem at address 0x60 (reg 0) ++run: jumping to 0x00000008 ++run: inst: 0x00000008 +-run: inst: 0x00000003 + +:(before "End Single-Byte Opcodes") +case 0xff: { // jump to r/m32 + uint8_t modrm = next(); + uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits + switch (subop) { + case 4: + trace(2, "run") << "jump to effective address" << end(); + int32_t* arg2 = effective_address(modrm); + EIP = *arg2; + trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end(); + break; + // End Op ff Subops + } + break; +} diff --git a/subx/013immediate_addressing.cc b/subx/013immediate_addressing.cc index dd1ce4c0..e97b9f6c 100644 --- a/subx/013immediate_addressing.cc +++ b/subx/013immediate_addressing.cc @@ -366,3 +366,49 @@ case 0xc7: { // copy imm32 to r32 *arg1 = arg2; break; } + +//:: jump + +:(scenario jump_rel8) +# op ModRM SIB displacement immediate + eb 05 # skip 1 instruction + 05 00 00 00 01 + 05 00 00 00 02 ++run: inst: 0x00000001 ++run: jump 5 ++run: inst: 0x00000008 +-run: inst: 0x00000003 + +:(before "End Single-Byte Opcodes") +case 0xeb: { // jump rel8 + int8_t offset = static_cast<int>(next()); + trace(2, "run") << "jump " << NUM(offset) << end(); + EIP += offset; + break; +} + +//: + +:(scenario jump_rel16) +# op ModRM SIB displacement immediate + e9 05 00 # skip 1 instruction + 05 00 00 00 01 + 05 00 00 00 02 ++run: inst: 0x00000001 ++run: jump 5 ++run: inst: 0x00000009 +-run: inst: 0x00000003 + +:(before "End Single-Byte Opcodes") +case 0xe9: { // jump rel8 + int16_t offset = imm16(); + trace(2, "run") << "jump " << offset << end(); + EIP += offset; + break; +} +:(code) +int16_t imm16() { + int16_t result = next(); + result |= (next()<<8); + return result; +} |