I'm writing a compiler with bison, and trying to implement procedures. I found the "global intpow" example online, and that works totally fine, and I made my own procedure calls modelled after it. The function "bar" in this code snippet only takes one integer parameter, and prints it. When my compiled program is run and executed:
-intpow will run just as it's supposed to, to normal program termination, a function with the declaration of "bar" will run as its supposed to, to normal function termination, but If I call bar (And therefore add the three lines that are commented saying unique to bar call), The program will run exactly as it's supposed to until the very end, when it will Segmentation Fault.
gdb says it is at the final pop ebp in __bar_end...why is this segfaulting?
extern printf
extern scanf
extern pow
SECTION .data
printf_int:
db "%d", 10, 0
printf_float:
db "%lf", 10, 0
printf_str:
db "%s", 10, 0
scan_int:
db "%d", 0
scan_float:
db "%lf", 0
esp_tmp:
dd 0
SECTION .text
global intpow
intpow:
push ebp
mov ebp,esp
mov eax,[ebp+12]
mov ebx,[ebp+12]
mov ecx,[ebp+8]
loop:
cmp ecx,1
cmp ecx,1
jle finish
dec ecx
imul eax,ebx
jmp loop
finish:
mov esp,ebp
pop ebp
ret
global main
main:
push ebp
mov ebp,esp
jmp __bar_END
global __bar
__bar:
push ebp
mov ebp,esp
sub esp,-4
push DWORD [ebp + 8]
push DWORD printf_int
mov [esp_tmp], esp
add DWORD [esp_tmp], 8
call printf
mov esp, DWORD [esp_tmp]
mov esp,ebp
pop ebp
ret
__bar_END:
push DWORD 12 #Unique to bar call
call __bar #unique to bar call
add esp,4 #unique to bar call
push DWORD str0
push DWORD printf_str
mov [esp_tmp], esp
add DWORD [esp_tmp],8
call printf
mov esp, DWORD [esp_tmp]
mov esp, ebp
pop ebp
ret
SECTION .data
global_vars: times 0 db 0
true: db "true",0
false: db "false",0
str0: db "hello world",0
The problem is the sub esp, -4
. It moves stack pointer up (subtracting a negative number is adding). Not that you need to allocate any space at all, since you are not using it. Now go clean up the rest of the mess ;)