I'm learning to code in x86-64 assembly (AT&T) on Linux (gcc) and couldn't find a solution to my segmentation fault in this trivial code. I've seen some questions referring to stack alignment; however, this fails even when I try $8 or $16:
.global main
main:
#prologue
movq %rsp, %rbp #initialise base pointer
#reserve memory for subroutine
subq $8, %rsp #the line causing the segfault
exit:
movq $0, %rdi
call exit
My other programs I´ve written seem to work fine after a call to printf. What is wrong with the above code? The code fails with or without the call to exit. This and the code below is failing. I compile using:
gcc -o test test.s
The entire code:
.text
formatStr: .asciz "%ld"
resultStr: .asciz "The result is: %d\n"
q1: .asciz "Enter the base: "
q2: .asciz "Enter the exponent: "
#qTable2: #look up table for correct string during scanf
# .asciz q1
# .asciz q2
qTable: #alternative look up table
.quad base
.quad exponent
base:
movq $q1, %rdi
ret
exponent:
movq $q2, %rdi
ret
###################
# Subroutine: pow
# Function: Power an integer base to an exponent
# Inputs: uint base, int exponent(natural)
# Outputs: int result
##################
pow:
#prologue
pushq %rbp #store caller base pointer
movq %rsp, %rbp
movq $1, %rax #reset result
movq $0, %rbx #initialise loop
loop1:
imulq %rdi
incq %rbx
cmp %rsi, %rbx #compare loop interator to exponent
jle loop1
#epilogue
movq %rbp, %rsp #clear local variables from stack
pop %rbp #restore caller base pointer
ret
.global main
###################
# Subroutine: Main
# Function: Application entry point
###################
main:
#prologue
pushq %rbp
movq %rsp, %rbp #initialise base pointer
#reserve memory for subroutine
subq $8, %rsp
#Gather the inputs from the user
movq $0, %rbx #loop counter
#inputAcq:
#Call printf using correct question
movq %rax, %rsi #move result into argument 2
movq qTable(,%rbx,8), %rdi #format string as argument 1
call *%rdi
movq $0, %rax #no vector registers
call printf
leaq -16(%rbp,%rbx,8), %rsi #Argument 2
movq formatStr, %rdi #Argument 1
movq $0, %rax #no vector registers
call scanf
incq %rbx #increment loop counter
cmp $1, %rbx #check if more inputs are necessary else continue
jl inputAcq
#Call pow
movq -8(%rbp), %rsi #the exponent
movq -16(%rbp), %rdi #the base
call pow
#Call printf
movq %rax, %rsi #move result into argument 2
movq $resultStr, %rdi #format string as argument 1
movq $0, %rax #no vector registers
call printf
#exit program without errors
exit:
movq $0 , %rdi
call exit
The error for the main code when using (gdb) x/i $pc:
0x4004e5 <exit+7>: callq 0x4004de <exit>