【问题标题】:Can someone annotate this machine code?有人可以注释这个机器代码吗?
【发布时间】:2014-05-16 04:06:54
【问题描述】:

我正在尝试开始学习 x86(-64) 机器代码,因为将来某个时候我想编写一个编译器或 JIT 编译器(可能是后者首先)。我已经编写了一段时间的程序集,所以我不会盲目,我只是想学习 x86 指令编码/格式,因为它似乎很复杂。我看过表格并阅读文章和资料(以及一些英特尔手册(我读过的最不人道的文件))。

所以我有点开始理解它,所以我决定尝试分解一组基本指令及其产生的机器代码。该代码创建了一个(Linux/Posix)系统调用(sys_exit),因为我认为它很容易测试(继续阅读)。这是 x86-64 代码:

mov rax, 60
mov rdi, 0
syscall

我用 nasm 组装了这个:

nasm test.asm -fbin

我使用了-fbin,所以它会输出我可以轻松检查的原始二进制文件。

它输出以下字节序列:

0xB8 0x3C 0x00 0x00 0x00 0xBF 0x00 0x00 0x00 0x00 0x0F 0x05

我和几个朋友试图剖析这个以找出每个字节的含义,我们认为如下:

  • 0xB8 是第一条mov 指令。
  • 0x3C (60) 是第一个参数,移到 rax 中。
  • 0x00 表示 rax? (这是我们变得模糊的地方)
  • 接下来的两个0x00 只是多余的nasm 输出? xD
  • 0xBF 是下一个 mov
  • 0x00 是第一个参数,0
  • 对剩下的0x00一无所知
  • 0x0F 系统调用?
  • 0x05 无能。

我是一个初学者(显然),希望能帮助我分析这个机器代码。任何帮助将不胜感激,因为理解这将有助于理解 x86 指令格式,在此先感谢!

编辑:寄存器是否有可能由指令操作码指定?

【问题讨论】:

    标签: x86 x86-64


    【解决方案1】:

    我不是专家,但以http://ref.x86asm.net/coder64.html#x05为参考,整理如下说明:

    0xB8 - first mov
    0x3C 0x00 0x00 0x00 - 32bit argument (60), little endian byte order
    0xBF - second mov
    0x00 0x00 0x00 0x00 - 32bit argument (0)
    0x0F - 0x0F instruction prefix
    0x05 - syscall in the "0x0F space"
    

    是的,操作码字节值会根据寄存器和参数类型而变化。某些类型的 movs 和 jmps 也需要 0x0F 前缀。

    【讨论】:

    • 感谢您的回答!这很有意义,我没有考虑 32 位参数……这是否意味着寄存器与操作码配对?我会再调查一下。再次感谢 m8 的帮助。
    • x86 设计本身一开始就很混乱。如果我没记错的话,英特尔的文档非常擅长解释操作码以及在指定参数类型时必须处理的所有问题。 ref.x86asm.net 假设您已经知道所有这些。
    • 哦,我明白了...谢谢。在表中进一步检查后,指定了操作码使用的寄存器,因此有很大帮助。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多