我正在用野牛编写一个编译器,并尝试实现过程。我在网上找到了"global intpow"示例,它工作得很好,我根据它进行了自己的过程调用。此代码片段中的函数"bar"仅接受一个整数参数,并打印它。当我编译的程序运行并执行时:
-intpow 将按预期运行,到正常的程序终止,声明为"bar"的函数将按其预期运行,到正常的函数终止,但是如果我调用 bar(因此添加注释的三行说 bar 调用唯一),程序将完全按照它应该的方式运行,直到最后, 当它会分段错误。
GDB表示,这是__bar_end年最后的流行音乐EBP...为什么会出现这种段错误?
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
问题是sub esp, -4
.它将堆栈指针向上移动(减去负数是加法)。并不是说您根本不需要分配任何空间,因为您没有使用它。现在去清理剩下的烂摊子;)