0

I coded the following function in assembly:

    .global my_pow
    .type my_pow, @function

    .data
format:
    .asciz "%d\n"

    .text
my_pow:
    
    // Variable
    pushq %rbp      # value to print
    pushq %rbx      # i

    movq $0x01, %rbp    # value = 1
    movl %edi, %ebx     # i = number of iteration (1st arg)

loop:

    movq $format, %rdi  # 1st arg of printf is the format : "%d\n"
    movq %rbp, %rsi     # 2nd arg of printf is the value
    xor %eax, %eax
    call printf

    cmp $0, %ebx        # break if (i == 0)
    je  quit

    addq %rbp, %rbp     # value += value    
    subq $0x1, %rbx     # i -= 1
    jmp loop

quit:
    // Deallocate stack
    popq %rbp
    popq %rbx
    nop
    ret

And when i run it with main. c:

#include <stdio.h>

extern int my_pow(int n);

int main(void) {
        int n = 5;
    my_pow(n);
    return 0;
}

I got this output:

1
2
4
8
16
32
zsh: segmentation fault (core dumped)  ./a.out

It seems that problem is in the quit section i dont why i get a segfault I use pop to deallocate the stack and then ret to return I compile with gcc -c my_pow.s and gcc my_pow.o main.c

Nicolas
  • 31
  • 5
  • 1
    Which instruction segfaults? Run it under a debugger to see. Oh, probably something in `main` since you swapped RBP and RBX when you restore them. Stack operations are LIFO, so you have to pop in opposite order to push. – Peter Cordes Jan 22 '23 at 15:52
  • 1
    Stack alignment is off as well. https://stackoverflow.com/questions/49391001/why-does-the-x86-64-amd64-system-v-abi-mandate-a-16-byte-stack-alignment. In short, you have to push/pop an *odd* number of registers. – Nate Eldredge Jan 22 '23 at 16:09
  • I looked for an existing duplicate, but could only find general questions about how the stack works, not another one where push order was mismatched with pop order leading to a crash. But I'm sure there have been such questions. Lol, as soon as I tabbed tack to my google results, a question on the 5th page of results jumped out at me: [Assembly- push'd register RAX is not the same when I pop it off the stack?](https://stackoverflow.com/q/12649211) – Peter Cordes Jan 22 '23 at 16:19
  • @NateEldredge You said "odd number of registers" but the post you linked says to maintain 16 byte alignment. Wouldn't that require an even number of registers? – puppydrum64 Jan 24 '23 at 10:58
  • @puppydrum64: The `call` instruction that got you here already pushed 8 bytes. – Nate Eldredge Jan 24 '23 at 14:21
  • Very true. I forgot about that! – puppydrum64 Jan 24 '23 at 17:55

0 Answers0