【发布时间】:2012-11-10 07:31:31
【问题描述】:
我正在用 bison 编写编译器,并尝试实现程序。我在网上找到了“global intpow”示例,它工作得很好,并且我根据它进行了自己的过程调用。这段代码 sn-p 中的函数“bar”只接受一个整数参数,并打印它。当我编译的程序运行并执行时:
-intpow 将按预期运行,正常程序终止,声明“bar”的函数将按预期运行,正常函数终止,但如果我调用 bar(因此添加三个注释为 bar call 独有的行),程序将完全按照预期运行,直到最后,它会出现 Segmentation Fault。
gdb 说它在 __bar_end 的最后一个 pop 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
【问题讨论】:
-
为什么
__bar末尾有两条pop ebp指令?我认为其他混乱只是因为您正在尝试调试它;) -
糟糕。我会修复它。那只是复制和粘贴,只有1个。
标签: assembly segmentation-fault nasm calling-convention