Search code examples
linuxassemblyx86-64windows-subsystem-for-linux

segmentation fault when calling ret after a jump in assembly x86_64


I'm new to assembly x86_64 and trying to learn the jump conditions. In my code i get a segmentation fault when i use the jump if equal call, but no fault if I call the function and then return, why is this happening? I'm not pushing more on the stack than im popping, or is it only possible to exit the jump condition if I call another function f.e. an exit function?

    section .data
    success db "yeah"

section .text
    global _start

print_juhu:
    push rsi
    push rdx
    push rax
    push rdi

    mov rax,1
    mov rsi,success
    mov rdx,4
    syscall

    pop rdi
    pop rax
    pop rdx
    pop rsi

    ret

_start:
    mov r12,3
    mov r14,3
    cmp r12,r14
    je print_juhu

    ; Exit the program
    mov rax, 60
    mov rdi, 0
    syscall

Solution

  • You can only return from functions that you called, not from those you jumped to. A jump instruction does not store a return address on the stack, only a call instruction does.

    As you jumped to print_juhu instead of calling the function, the ret instruction pops some random junk off the stack instead of a return address, and proceeds to jump to some address, most likely causing a crash.

    To fix the code, use a call instruction to call print_juhu. As no conditional call instructions are available, you'll have to jump around the call instruction to conditionally call the function:

            jne     dont_call_print_juhu
            call    print_juhu
    
    dont_call_print_juhu:
            ...