【问题标题】:Array addressing in AT&T GAS assembly. Register offset from RIP doesn't workAT&T GAS 组件中的数组寻址。 RIP 的寄存器偏移不起作用
【发布时间】:2018-04-07 06:02:30
【问题描述】:

我正在尝试在 GNU 程序集中使用数组。在我看来,以下代码必须以值 3 退出。但它以 13 退出。

.section __DATA,__data
  inArr:
    .word 13, 2, 3, 4, 5, 6, 7, 8, 9, 10

  outArr:
    .fill 10, 2
.section __TEXT,__text
.globl _main
_main:


  movq $3, %rcx

  movw inArr(%rip, %rcx, 2), %di  # load  *((rcx * 2)+ rip + &inArray) into %di, isn't it?
  movl $0x2000001, %eax           # exit
  syscall

在我看来movw inArr(%rip, %rcx, 2), %di 命令相当于%di = inArr[%rcx]。不幸的是,我在 GAS 中找不到任何带有数组的示例。

该代码有什么问题?我该如何处理数组的第 n 个元素?

【问题讨论】:

  • 如果不需要位置无关的代码,可以使用movzwl inArr( ,%rcx, 2), %edi。但你可能确实需要 PIC for OS X
  • 谢谢!这会产生以下错误error: 32-bit absolute addressing is not supported in 64-bit mode。我找不到 OS X 的 PIC。你能澄清一下吗?
  • PIC = 与位置无关的代码。您根本不能在 OS X 上的 x86-64 代码中使用 OS X 上的绝对寻址。 (Unlike Linux.)

标签: arrays assembly x86-64 gnu-assembler att


【解决方案1】:

没有索引 RIP 相对寻址模式这样的东西。你的汇编程序应该给出一个错误。改用这个:

    lea inArr(%rip), %rdi
    movzwl (%rdi, %rcx, 2), %edi

【讨论】:

  • 你可以使用%rdi作为指针来避免需要一个tmp寄存器。 (除非 OP 真的想将这个词合并到 RDI 的低 16 位中)。
  • @Peter,是的,我使用了 rax,因为原始代码在下一行重新加载了它。但是 exit 系统调用只使用了 rdi 的低 8 位,所以它同样安全,并且更有可能是没有上下文的最佳选择。
  • 谢谢!有用。但这对我来说仍然很奇怪。在我看来,您的代码以相同的方式工作。我在 OS X 上使用 GAS,它没有给我任何错误,只是忽略了索引。也许你可以给我一些关于 GAS 中数组的链接?
猜你喜欢
  • 2013-05-31
  • 1970-01-01
  • 2018-06-15
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多