Skip to content

Commit

Permalink
[x86-64] Add disassembler support for some one-byte opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Jul 22, 2024
1 parent 6027bc1 commit bf75393
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
17 changes: 14 additions & 3 deletions lib/asm/x86-64/X86_64Disassembler.v3
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,23 @@ class X86_64Disassembler(v: X86_64DisVisitor) {
// Decode main instructions.
//--------------------------------------------------------------------------------
match (current) {
0xCC => return do_b("int", 3);
0xCD => return do_b("int", r.read1());
0x90 => return do_none("nop");
0x99 => return do_none("cdq");
0x9C => return do_none("pushfq");
0xAE => return do_none("scasb");
0xC3 => return do_none("ret");
0xCC => return do_imm_b("int", 3);
0xCD => return do_imm_b("int", r.read1());
0xCF => return do_none("iret");
}
return do_illegal();
}
def do_b(name: string, p: byte) -> bool {
def do_none(name: string) -> bool {
if (!r.ok) return do_illegal();
v.visit_none(prefixes, name);
return true;
}
def do_imm_b(name: string, p: byte) -> bool {
if (!r.ok) return do_illegal();
v.visit_imm_b(prefixes, name, p);
return true;
Expand Down
22 changes: 20 additions & 2 deletions test/asm/x86-64/X86_64DisassemblerTest.v3
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ def data = DataWriter.new();
def T = UnitTests.registerT("disass:", _, X86_64DisassemblerTester.new, _);
def X_ = [
T("intK", test_intK),
T("cdq", test_none(_, "cdq", X86_64Assembler.cdq)),
T("iret", test_none(_, "iret", X86_64Assembler.iret)),
T("pushfq", test_none(_, "pushfq", X86_64Assembler.pushfq)),
T("nop", test_none(_, "nop", X86_64Assembler.nop1)),
T("ret", test_none(_, "ret", X86_64Assembler.ret)),
T("scasb", test_none(_, "scasb", X86_64Assembler.scasb)),

()
];

Expand All @@ -28,6 +35,15 @@ class X86_64DisassemblerTester(t: Tester) extends X86_64DisVisitor {
dis = X86_64Disassembler.new(this);
}

def assert0<R>(name: string, mode: X86_64AddrMode, f: X86_64Assembler -> R) {
expected_name = name;
expected_mode = mode;
pos = asm.pos();
f(asm);
dis.reset(asm.w.data[pos ... asm.pos()]);
var ok = dis.disassemble();
if (!ok) t.fail("disassembler reported an error");
}
def assert1<P, R>(name: string, mode: X86_64AddrMode, f: (X86_64Assembler, P) -> R, p: P) {
expected_name = name;
expected_mode = mode;
Expand Down Expand Up @@ -64,15 +80,17 @@ class X86_64DisassemblerTester(t: Tester) extends X86_64DisVisitor {
}

def test_intK(t: X86_64DisassemblerTester) {
t.expected_name = "int";

var dis = X86_64Disassembler.new(t);
for (i < 256) {
if (!t.t.ok) break;
var b = byte.view(i);
t.assert1("int", X86_64AddrMode.imm_b(b), X86_64Assembler.intK, (b));
}
}
def test_none<R>(t: X86_64DisassemblerTester, name: string, fun: X86_64Assembler -> R) {
t.assert0(name, X86_64AddrMode.none, fun);
}


def main(args: Array<string>) -> int {
return UnitTests.run(args);
Expand Down

0 comments on commit bf75393

Please sign in to comment.