Yasm有64位指令

时间:2018-01-04 15:48:39

标签: assembly 64-bit x86-64 yasm

我正在尝试为使用 64位寄存器的英特尔语法编写的x86_64汇编一些汇编源代码。我使用以下命令行标志:

yasm foo.asm -a x86 -m amd64

我一直收到如下错误:

warning: `rbp' is a register in 64-bit mode
foo.asm:23: error: undefined symbol `rbp' (first use)

所以,我在stackoverflow上看到了similar question,以及网络上的numerous resources,表明可以通过指定" BITS"来解决这个问题。指令,特别是:

BITS 64

问题是,我甚至不清楚这是什么意思。我不明白什么是"指令"是。这似乎是你需要在汇编代码中指定的东西。但在这种情况下,我无法控制代码,所以我只是想找到一个命令行标志来组装它。

有没有办法在我可以传递给yasm的命令行标志中指定BITS指令?

2 个答案:

答案 0 :(得分:1)

使用-felf64将x86-64代码汇编成64位ELF .o

如果要制作平面二进制文件(不是.o.obj),请在文件顶部使用BITS 64。否则避免这种情况,您通常不希望将64位机器代码放入32位.o中。生成时错误更好。


尽管有文档in the manual,YASM的-a x86 -m amd64选项不要覆盖默认的-fbin平面二进制输出格式的默认设置,即假设代码将在16位模式下执行,则进行汇编。 (就像NASM一样。)

使用-m x86 确实防止文件中的-felf64BITS 64工作。它是YASM的CPU功能限制支持的一部分,可以帮助您避免意外使用目标CPU不支持的ISA功能。 (例如,CPU Conroe AMD启用SSSE3之前的所有功能以及syscall之类的AMD64指令,同时禁用SSE4和AVX。默认值为无限制。)


BITS 16-fbin的默认模式。

汇编器必须知道CPU将在哪种模式下执行您的代码。例如,在32位模式下,mov eax,ecx89 C8,但是{{ 1}}在16位模式下(操作数大小的覆盖前缀,然后是与32位模式相同的操作码+ modrm)。

64位操作数大小和地址大小以及通常的64位寄存器只能在64位模式下进行编码,因此在汇编器进行编译时尝试使用66 89 C8汇编代码时出错将在16位模式下执行的代码。

以16位模式启动的引导加载程序可能会切换到32位和/或64位模式,因此您需要在跳转目标前面的rbpBITS 32指令BITS 64切换到32位或64位模式。

是BITS指令的常规用例。不幸的是,像NASM一样,似乎没有命令行选项可以在您选择的模式下汇编平面二进制文件。如果您可以将jmp far放入文件中并仅使用命令行选项而无需编辑文件就获得inc eax66 4040,那就太好了,但是我们不能。

答案 1 :(得分:0)

如果我正确理解,您的问题是: 如何“激活” 64位模式?

这很简单。

如果您的代码是:

mov rax, [rbp - 2]
mov rbx, rax
syscall  ;just to call some or for end of code

然后将其更改为:

bits 64

mov rax, [rbp - 2]
mov rbx, rax
syscall  ;just to call some or for end of code

简单地将 64位放在代码的开头!