【问题标题】:Unable to move variables in .data to registers with Mac x86 Assembly无法将 .data 中的变量移动到使用 Mac x86 程序集的寄存器
【发布时间】:2021-02-05 18:09:57
【问题描述】:

我用 AT&T 语法编写了一小段程序集,目前在 .data 部分中声明了三个变量。但是,当我尝试将这些变量中的任何一个移动到寄存器(例如%eax)时,会引发来自gcc 的错误。代码和错误信息如下:

.data
  x:.int 14
  y:.int 4
  str: .string "some string\n"

.globl _main

_main:
  pushq %rbp
  movq %rsp, %rbp
  subq $16, %rsp
  movl x, %eax; #attempting to move the value of x to %eax;
  leave
  ret

引发的错误是:

call_function.s:14:3: 错误:64 位模式不支持 32 位绝对寻址

movl x, %eax;

^

我还尝试通过首先在x 前面添加$ 字符来移动值,但是会引发clang 错误:

clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

有谁知道x中存储的值如何成功移动到%eax?我在 Mac OSX 上使用 x86 程序集并使用 gcc 进行编译。

【问题讨论】:

  • 使用movl x(%rip), %eax
  • @Jester 谢谢,x(%rip) 工作!如果你能写一个带有解释的答案,我会接受。
  • 错误信息略显不诚实。是的,movl x, %eax 受架构支持,但您不应该使用它。
  • @fuz:在 AT&T 语法中,moffs 形式的 mov(具有 64 位绝对地址)使用 movabs 助记符,所以简单的 mov 意味着你想要 @ 987654339@ 带有 ModR/M 字节的操作码。 MachO64 输出格式根本不支持 32 位绝对重定位,并且图像基地址在 OS X 上高于 2^32,因此[disp32] 寻址模式无法工作。因此对于mov,RIP-relative 是唯一的选择。

标签: macos assembly x86 x86-64 att


【解决方案1】:

相对于 RIP 的寻址模式是在 MacOS 上寻址静态数据的唯一好选择;图像基地址高于 2^32,因此即使在与位置相关的代码中也不能使用 32 位绝对地址(与 x86-64 Linux 不同)。静态数据的 RIP 相对寻址与位置无关,因此它甚至可以在与位置无关的可执行文件 (ASLR) 和库中工作。

movl x(%rip), %eax 是 RIP-relative 的 AT&T 语法。

mov eax, dword ptr [rip+x] 在 GAS 中 .intel_syntax noprefix

或者,要将符号的地址存入寄存器,lea x(%rip), %rdi


NASM 语法:mov eax, [rel x],或使用 default rel,因此 [x] 是 RIP 相关的。

请参阅Mach-O 64-bit format does not support 32-bit absolute addresses. NASM Accessing Array 了解更多关于您可以在 OS X 上做什么的背景信息,例如movabs x, %eax 是可能的,因为目标寄存器是 AL/AX/EAX/RAX。 (64 位绝对地址,但不要这样做,因为它比 RIP 相对加载更大且不快。)

另见http://felixcloutier.com/x86/MOV.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多