4908
Fix CI. a) Update canonical binaries. b) Fix an out-of-bounds access in `clear-stream`. This also required supporting a new instruction in `subx run` to load an imm8 into rm8.
This commit is contained in:
parent
aa96ac23a6
commit
2eb174d697
|
@ -48,7 +48,7 @@ put_new(Name, "88", "copy r8 to r8/m8-at-r32");
|
|||
88 18 # copy BL to the byte at *EAX
|
||||
# ModR/M in binary: 00 (indirect mode) 011 (src BL) 000 (dest EAX)
|
||||
== 0x2000
|
||||
f0 cc bb aa # 0xf0 with more data in following bytes
|
||||
f0 cc bb aa
|
||||
+run: copy BL to r8/m8-at-r32
|
||||
+run: effective address is 0x00002000 (EAX)
|
||||
+run: storing 0xab
|
||||
|
@ -114,3 +114,39 @@ case 0x8a: { // copy r/m8 to r8
|
|||
+run: storing 0x44
|
||||
# ensure ESI is unchanged
|
||||
% CHECK_EQ(Reg[ESI].u, 0xaabbccdd);
|
||||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "c6", "copy imm8 to r8/m8-at-r32 (mov)");
|
||||
|
||||
:(scenario copy_imm8_to_mem_at_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
== 0x1
|
||||
# op ModR/M SIB displacement immediate
|
||||
c6 00 dd # copy to the byte at *EAX
|
||||
# ModR/M in binary: 00 (indirect mode) 000 (unused) 000 (dest EAX)
|
||||
== 0x2000
|
||||
f0 cc bb aa
|
||||
+run: copy imm8 to r8/m8-at-r32
|
||||
+run: effective address is 0x00002000 (EAX)
|
||||
+run: storing 0xdd
|
||||
% CHECK_EQ(0xaabbccdd, read_mem_u32(0x2000));
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0xc6: { // copy imm8 to r/m8
|
||||
const uint8_t modrm = next();
|
||||
const uint8_t src = next();
|
||||
trace(90, "run") << "copy imm8 to r8/m8-at-r32" << end();
|
||||
trace(90, "run") << "imm8 is 0x" << HEXWORD << src << end();
|
||||
const uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits
|
||||
if (subop != 0) {
|
||||
cerr << "unrecognized subop for opcode c6: " << NUM(subop) << " (only 0/copy currently implemented)\n";
|
||||
exit(1);
|
||||
}
|
||||
// use unsigned to zero-extend 8-bit value to 32 bits
|
||||
uint8_t* dest = reinterpret_cast<uint8_t*>(effective_byte_address(modrm));
|
||||
*dest = src;
|
||||
trace(90, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -228,6 +228,7 @@ void init_permitted_operands() {
|
|||
// imm32 imm8 disp32 |disp16 disp8 subop modrm
|
||||
// 0 1 0 |0 0 1 1
|
||||
put(Permitted_operands, "c1", 0x23); // combine
|
||||
put(Permitted_operands, "c6", 0x23); // copy
|
||||
|
||||
//// Class P: op, ModR/M, subop (not r32) and imm32
|
||||
// imm32 imm8 disp32 |disp16 disp8 subop modrm
|
||||
|
|
|
@ -107,9 +107,9 @@ $clear-stream:loop:
|
|||
39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX with ECX
|
||||
7d/jump-if-greater-or-equal $clear-stream:end/disp8
|
||||
# *EAX = 0
|
||||
c7 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm32 # copy to *EAX
|
||||
# EAX += 4
|
||||
81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 4/imm32 # add to EAX
|
||||
c6 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm8 # copy byte to *EAX
|
||||
# ++EAX
|
||||
40/increment-EAX
|
||||
eb/jump $clear-stream:loop/disp8
|
||||
$clear-stream:end:
|
||||
# . restore registers
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
subx/apps/handle
BIN
subx/apps/handle
Binary file not shown.
BIN
subx/apps/hex
BIN
subx/apps/hex
Binary file not shown.
Loading…
Reference in New Issue