我正在尝试为使用x86_64 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)
因此,我看到了堆栈溢出上的相似问题,以及web上的众多资源,它们表明可以通过指定"BITS“指令来解决这个问题,具体如下:
BITS 64
问题是,我不清楚这意味着什么。我不明白什么是“指令”。它似乎是您需要在程序集代码本身中指定的。但是在这种情况下,我并不控制代码,所以我只是试图找到一个命令行标志来组装它。
是否有一种方法可以在命令行标志中指定BITS
指令,我可以传递给yasm?
发布于 2019-02-22 19:11:29
使用-felf64
将x86-64代码组装成64位ELF .o
.
如果您正在生成一个平面二进制文件(而不是.o
或.obj
),请在文件顶部使用BITS 64
。否则,您通常不希望将64位机器代码放入32位.o
中;构建时错误更好。
尽管使用了在手册中文档,但YASM的-a x86 -m amd64
选项并不覆盖默认的--默认的平面二进制输出格式,即在假定代码以16位模式执行的情况下进行组装。(与NASM完全一样).
使用-m x86
确实会阻止文件中的-felf64
或BITS 64
工作。这是YASM的CPU特性限制支持的一部分,它可以帮助您防止意外地使用目标CPU不支持的ISA特性。(例如,CPU Conroe AMD
支持SSSE3和AMD64指令(如syscall
),同时禁用SSE4和AVX。默认值是无限制的。)
BITS 16
是-fbin
的默认模式。
汇编程序必须知道CPU将以何种模式执行代码。例如,是32位模式下的89 C8
,而66 89 C8
是16位模式(操作数大小覆盖前缀,然后是与32位模式相同的操作码+ modrm )。
64位操作数大小和地址大小以及64位寄存器一般只能在64位模式下编码,因此当汇编程序生成以16位模式执行的代码时,尝试使用rbp
汇编代码时会出错。
以16位模式启动的引导加载程序可能切换到32位和/或64位模式,因此您需要在跳转目标前面为切换到32位或64位模式的BITS 32
或BITS 64
指令。
这是位指令的正常用例。不幸的是,像NASM一样,似乎没有命令行选项可以在您选择的模式中组装一个平面二进制文件。如果只使用命令行选项,不编辑文件就可以将inc eax
放入文件中并获取66 40
、40
或FF C0
,这将是很酷的,但我们做不到。
发布于 2019-02-22 18:32:30
如果我正确理解,你的问题是:如何“激活”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”放在代码的开头!
https://stackoverflow.com/questions/48098816
复制相似问题