【问题标题】:too many references for 'mov' when using two 64-bit registers?使用两个 64 位寄存器时对“mov”的引用过多?
【发布时间】:2021-06-26 20:50:06
【问题描述】:

我正在尝试编译一个非常简单的程序,但出现了 2 个无法修复的错误:

1.s:13:Error: too many memory references for 'mov'
1.s:15:Error: too many memory references for 'lea'

这是我的代码,希望有人看到我的错误。

.intel_syntax noprefix
.data
message: .asciz "Hello World\n"
.text
.global main
main:
    push rbp
    mov rbp, rsp
    lea rdi, message
    call printf
    mov rax, 0
    pop rbp
    ret
    

【问题讨论】:

  • rpbrbp 的拼写错误,但这应该只是作为该符号名称的存储区。你确定你是在 64 位模式下组装的吗?在 32 位模式下,rdirsp 只是符号名称,而不是寄存器。 gcc -c foo.s 在我的 x86-64 GNU/Linux 桌面上没有给出任何错误。
  • (因为那个错字,代码当然不会链接,如果你不打算使用像 lea rdi, [RIP + message] 这样的 RIP 相对寻址,lea 毫无意义。还有你的代码位于 .data 部分,而不是 .text。)
  • @PeterCordes 我纠正了那个错字并添加了 .text 部分,但它是一样的
  • 是的,就像我说的,错字没有解释错误信息。您可能正在 32 位模式下组装,例如 gcc -m32,这只是 32 位系统上的默认设置。

标签: assembly gcc x86-64 gnu-assembler intel-syntax


【解决方案1】:

在我的 x86-64 Arch GNU/Linux 系统上,该代码组合 + 链接对我来说很好:
gcc -no-pie foo.S

这些错误消息与我收到的 gcc -c -m32 foo.S 相符,因此您可能使用的是 32 位系统,其中 -m32 是 GCC 的默认值。如果 gcc -m64 -no-pie 有效,您可以组装+链接它,否则您必须将系统升级到64位。

在 32 位模式下,RBP 等不是寄存器名称,因此 GAS 只是将它们视为未知符号名称。当然还有x86 doesn't allow instructions with two explicit memory operands,比如mov mem2, mem1。 (并且lea 需要一个寄存器目标,mov rax, 0 也会在存储的不明确操作数大小上出错。)

(我不得不使用-no-pie,因为你写了lea rdi, message而不是lea rdi, [rip+message]来使用RIP相对寻址instead of 32-bit absoluteHow to load address of function or label into register

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 2019-04-21
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2014-11-05
    相关资源
    最近更新 更多