0

Hope all is well.

I am trying to loop over each element of an array and printing each element but cannot find the right way. I have been searching for multiple hours now.

So far I have this code:

    .section .data

array:
    .quad 1,2,3,4,5
    .section .text
    
    .globl main
    
main:
    leaq array(%rip), %rcx
    movq $0, %rsi
    jmp test

body:
    
    movq (%rcx, %rsi, 8), %rdi
    callq print_int
    incq %rsi
    jmp test

test:
    cmpq $5, %rsi
    jne body
    je exit

exit:
    movq $3, %rdi
    callq print_int
    
    

But I get a segmentation fault. The closest I have gotten is printing 13:


    .section .data

array:
    .quad 1,2,3,4,5
    .section .text
    
    .globl main
    
main:
    leaq array(%rip), %rcx
    movq $0, %rsi

loop:
    movq (%rcx, %rsi, 8), %rax
    movq %rax, %rdi
    callq print_int
    addq $1, %rsi
    cmpq $5, %rsi
    je loop
    jmp exit

exit:
    movq $3, %rdi
    callq print_int
    

print_int is a function I am using from a compiler runtime.

I am compiling with gcc: gcc -g runtime.o program.s.

Any help will be appeaciated. thanks

The duplicate question doesn’t answer my question because I’m not asking about functional calls. I want to print the elements of an array

chez93
  • 131
  • 6
  • Can you provide *any* details about this segmentation fault? – Scott Hunter May 10 '23 at 18:49
  • Presumably `print_int` follows the normal calling convention, so it doesn't preserve RCX or RSI. Use call-preserved regs like RBX and R15 for your loop variables. – Peter Cordes May 10 '23 at 18:51
  • @PeterCordes thanks. So the my first example looks right except for the registers? Thanks a lot – chez93 May 10 '23 at 20:04
  • Yes, correct but clunky. The `jmp test` is a no-op, execution will already go to the next instruction regardless of labels *unless* you jump. Same for the `je exit`, the `jne body` already fell through, so you don't need a jump to go anywhere else. I'd recommend looking at optimized compiler output for a loop that calls a function on every element of an array, e.g. on https://godbolt.org/ (and see [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)) – Peter Cordes May 10 '23 at 20:07
  • Your question is a duplicate because you're assuming RCX and RSI will still have the same values after `call print_int`. And the problem is that they won't, like that Q&A explains. If you're not familiar with the concept of call-clobbered registers, see [What are callee and caller saved registers?](https://stackoverflow.com/a/56178078) – Peter Cordes May 10 '23 at 20:08
  • There are tons of duplicates of your exact problem, of loops that break because function calls clobber registers. e.g. [Segment fault Assembly NASM on print array values](https://stackoverflow.com/q/63548836) / [Assembly infinite loop with printf function](https://stackoverflow.com/q/39254931) / [Is function call messing with other registers than %rax?](https://stackoverflow.com/q/52460450) (most of the "linked questions" from the Linux function-call Q&A) – Peter Cordes May 10 '23 at 20:11
  • @PeterCordes oh ok I see. But yea I used those registers you told me and it worked; thank you so much! One quick question. what does it mean "..normal calling convention, so it doesnt preserve rcx or rsi"? what are call-preserved regs? thanks – chez93 May 10 '23 at 20:13
  • The normal calling convention (on non-Windows) is the one documented in the x86-64 System V ABI. In hand-written asm, some functions might use a custom calling convention, like preserving all registers. As for call-preserved regs, like I wrote 2 comments ago, if you aren't familiar with the term and concept, see [What are callee and caller saved registers?](https://stackoverflow.com/a/56178078) – Peter Cordes May 10 '23 at 20:18

0 Answers0