用于-felf64
将 x86-64 代码组装成 64 位 ELF .o
。
如果您正在制作一个平面二进制文件(不是 a .o
or .obj
)BITS 64
,请在文件顶部使用。否则避免它,您通常不希望将 64 位机器代码放入 32 位.o
;构建时错误更好。
尽管手册中有文档,但YASM 的-a x86 -m amd64
选项不会覆盖默认-fbin
平面二进制输出格式的默认值,即在假设代码将以 16 位模式执行的情况下进行汇编。(就像 NASM 一样)。
使用-m x86
确实会阻止-felf64
或BITS 64
在文件内工作。它是 YASM 的 CPU 功能限制支持的一部分,可以帮助防止您意外使用目标 CPU 不支持的 ISA 功能。(例如CPU Conroe AMD
,启用 SSSE3 和 AMD64 等指令syscall
,同时禁用 SSE4 和 AVX。默认为无限制。)
BITS 16
是默认模式-fbin
。
汇编器必须知道 CPU 将在什么模式下执行您的代码。 例如,mov eax,ecx
处于89 C8
32 位模式,但66 89 C8
处于 16 位模式(操作数大小覆盖前缀,然后是与 32- 相同的操作码 + modrm位模式)。
64 位操作数大小和地址大小,以及一般的 64 位寄存器,只能在 64 位模式下编码,因此当rbp
汇编器正在制作将以 16 位执行的代码时尝试汇编代码时会出错模式。
以 16 位模式启动的引导加载程序可能会切换到 32 和/或 64 位模式,因此您需要在跳转目标前面添加一个BITS 32
or指令才能切换到 32 位或 64 位模式。BITS 64
jmp far
这是 BITS 指令的正常用例。不幸的是,像 NASM 一样,似乎没有一个命令行选项可以在您选择的模式下组装一个平面二进制文件。inc eax
如果您可以放入一个文件并获取66 40
, 40
,或者不编辑文件,只使用命令行选项,那会很酷FF C0
,但我们不能。