2

I'm trying to work with arrays in GNU assembly. In my opinion the following code must exit with value 3. But it exits with 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

In my opinion movw inArr(%rip, %rcx, 2), %di command is equivalent to something like %di = inArr[%rcx]. Unfortunately I can't find any examples with array in GAS.

What's wrong with that code? And how shall I address n-th element of array?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Roman Pavlov
  • 119
  • 1
  • 11
  • If you don't need position-independent code, you can use `movzwl inArr( ,%rcx, 2), %edi`. But you probably *do* need PIC for OS X – Peter Cordes Oct 26 '17 at 04:28
  • Thank you! That gives following error `error: 32-bit absolute addressing is not supported in 64-bit mode`. I can't find what is PIC for OS X. Can you clarify this? – Roman Pavlov Oct 26 '17 at 08:33
  • 1
    PIC = position-independent code. You can't use absolute addressing on OS X in x86-64 code on OS X at all. ([Unlike Linux.](https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-linux)) – Peter Cordes Oct 26 '17 at 08:35

1 Answers1

3

There is no such thing as indexed RIP-relative addressing mode. Your assembler should give an error. Use this instead:

    lea inArr(%rip), %rdi
    movzwl (%rdi, %rcx, 2), %edi
prl
  • 11,716
  • 2
  • 13
  • 31
  • 2
    You can use `%rdi` for the pointer to avoid needing a tmp register. (Unless the OP really did want to merge the word into the low 16 bits of RDI). – Peter Cordes Oct 26 '17 at 04:29
  • @Peter, yes, I used rax because the original code reloaded it in the next line. But the exit system call only uses the low 8 bits of rdi, so it was equally safe, and more likely to be the best choice without the context. – prl Oct 26 '17 at 07:11
  • Thank you! It works. But it still very weird for me. In my opinion your code is working in the same way. I'm using GAS on OS X and it doesn't give me any error, just ignoring indexing. Maybe you can give me some links about arrays in GAS? – Roman Pavlov Oct 26 '17 at 08:54
  • Documentation on the syntax: https://sourceware.org/binutils/docs/as/i386_002dMemory.html - also [How do RIP-relative variable references like "\[RIP + \_a\]" in x86-64 GAS Intel-syntax work?](https://stackoverflow.com/q/54745872) – Peter Cordes Apr 18 '22 at 03:40