【问题标题】:EQU directive in GAS assemblyGAS 组件中的 EQUI 指令
【发布时间】:2017-01-29 01:48:11
【问题描述】:

为什么.equ 指令不能以这种方式在gas中工作:

.equ Mark64, 8(%rsi)

虽然它在此工作(注意:Mark32 所在的.text 部分在这种情况下设置为 r/w):

Mark32 EQU DWORD PTR [ESI + 4]

如何让Mark64 在 GAS 中工作(.set 也不起作用)?

提前致谢!

【问题讨论】:

  • 使用预处理程序集和#define。或者,只定义偏移量,例如.equ Mark64, 8,然后你可以做movl Mark64(%rsp), %eax
  • @fuz 你有吗?它不起作用,因为.equ 定义了一个符号,而不是文本替换,并且8(%rsp) 不是符号的有效值。
  • @fuz,是的,我试过了。逗号在这里是一个拼写错误。还是不行

标签: assembly gnu-assembler


【解决方案1】:

在某些汇编语言(例如 MASM)中,equ 是文本替换。

但在 GAS 中,.equ 是一个数字常量,就像 MASM 中的 foo = 3。对于文本替换,请使用 C 预处理器 #define Mark64 8(%rsi)。将您的文件命名为foo.S,以便 gcc 在组装之前通过 CPP 运行它。

NASM 中的equ 还定义了一个数字汇编时间常数,并使用%define 进行文本替换。


顺便说一句,将 Mark64 定义为 8(%rsi) 似乎是一个糟糕/令人困惑的想法。人们不希望看起来像符号名称的东西实际上包含寄存器引用。不过,将数字魔术常量 8 定义为有意义的名称可能会很好。

【讨论】:

    【解决方案2】:

    数据部分:

    MarksTable:
        .quad Mark64_1
        .quad Mark64_2
        .quad Mark64_3
    

    Mark64_x 只是代码部分中的一个标签。

    然后我刚刚将我的MarksTable 放入 reg:

    movq MarksTable, %rsi
    

    毕竟我可以像这样从rsi 访问Mark64_2

    callq   *0x8(%rsi)
    

    【讨论】:

    • movq MarksTable, %rsi 是第一个元素的负载。使用lea MarksTable(%rip), %rsimov $MarksTable, %esi。或者更好,call *8+MarksTable(%rip).
    猜你喜欢
    • 2011-02-01
    • 2012-12-29
    • 1970-01-01
    • 2018-05-11
    • 2013-05-31
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    相关资源
    最近更新 更多