【问题标题】:Yasm with 64-bit instructions带有 64 位指令的 Yasm
【发布时间】:2018-06-14 09:26:09
【问题描述】:

我正在尝试为 x86_64 汇编一些汇编源代码,这些源代码用 Intel 语法编写,使用 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 指令?

【问题讨论】:

  • bits 64 只是说假设代码将以 64 位模式运行,对指令进行编码。
  • -m amd64 根据manual
  • @Jester -m amd64 控制目标文件格式,OP已经包含它。但是,我不明白为什么他们不能简单地将BITS 64 和源添加到临时文件中。
  • @Jester :根据问题,他已经在使用-m amd64。我不知道这是否是 OSDev 问题,但我认为原因是您没有指定 -f 选项,它默认为 -fbin,默认情况下将假定 bits 16
  • 不知道我怎么错过了问题中的-m amd64,我在-a x86 停止阅读:D

标签: assembly 64-bit x86-64 yasm


【解决方案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 和 AMD64 指令(如 syscall),同时禁用 SSE4 和 AVX。默认没有限制。)


BITS 16-fbin 的默认模式。

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

64 位操作数大小和地址大小,以及一般的 64 位寄存器,只能在 64 位模式下编码,因此当汇编器正在编写代码时,尝试使用 rbp 汇编代码时会出错将以 16 位模式执行。

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

是 BITS 指令的正常用例。不幸的是,像 NASM 一样,似乎没有一个命令行选项可以在您选择的模式下组装一个平面二进制文件。如果您可以将inc eax 放入一个文件并获得66 4040FF C0,而无需编辑文件,只需使用命令行选项,那就太棒了,但我们不能。

【讨论】:

    【解决方案2】:

    如果我理解正确,您的问题是: 如何“激活”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”放在代码的开头!

    【讨论】:

    • 你得到的那些错误是因为:1.) rbp 是 64,通常它是 16-32。 2.)第二个错误的出现是因为第一个错误的警告,因为它无法生成 rbp
    猜你喜欢
    • 1970-01-01
    • 2016-08-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多