我正在学习汇编器(FASM),但我遇到奇怪的问题,每当我想调用gtk_main_quit()时,它总是以“分段错误”结尾。
为什么调用gtk_main_quit会导致分段错误?
format ELF
extrn gtk_init
extrn gtk_main
extrn gtk_main_quit
extrn gtk_window_new
extrn gtk_widget_show
extrn g_signal_connect_data
public main
on_window_close:
call gtk_main_quit ; <- segmentation fault
ret
main:
push 0
push 0
call gtk_init
add esp, 8
push 0
call gtk_window_new
add esp, 4
mov [window_handle], eax
push 0
push 0
push 0
push on_window_close
push on_close_signal
push [window_handle]
call g_signal_connect_data
add esp, 24
push [window_handle]
call gtk_widget_show
add esp, 8
call gtk_main
window_handle dd 0
on_close_signal db 'destroy', 0
all:
~/apps/fasm/fasm ./test.asm
gcc -o test test.o `pkg-config --cflags --libs gtk+-3.0`
进行函数调用时,请始终确保在调用后正确还原堆栈。您的代码执行此操作:
push [window_handle]
call gtk_widget_show
add esp, 8
您将一个DWORD作为正确的参数压入堆栈,但是在调用之后gtk_widget_show
将8添加到ESP。由于仅在堆栈上压入了4个字节,因此这不正确地还原了ESP。副作用是该函数的返回地址main
现在将放在错误的位置,这可能会在main
函数返回时产生分段错误。该代码应该是:
push [window_handle]
call gtk_widget_show
add esp, 4
这带来了第二个问题。您的代码:
call gtk_main
window_handle dd 0
on_close_signal db 'destroy', 0
gtk_main
返回后,它将开始执行此后出现在内存中的所有指令。在这种情况下,它恰好是一些变量以及内存中的其他变量。由于C运行时main
像其他任何函数一样调用您的函数,因此您应该使用它ret
来返回C运行时,并使其干净地关闭程序。
代码如下所示:
call gtk_main
ret
window_handle dd 0
on_close_signal db 'destroy', 0
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句