私はbisonを使用してコンパイラを作成し、プロシージャを実装しようとしています。オンラインで「globalintpow」の例を見つけましたが、これはまったく問題なく機能し、それをモデルにした独自のプロシージャ呼び出しを行いました。このコードスニペットの関数「bar」は、1つの整数パラメーターのみを受け取り、それを出力します。コンパイルしたプログラムを実行して実行すると、次のようになります。
-intpowは想定どおりに実行され、通常のプログラム終了では、「bar」が宣言された関数は想定どおりに実行され、通常の関数終了になりますが、barを呼び出すと(したがって、次の3行を追加します)バーコールに固有のコメント)、プログラムは、セグメンテーション違反が発生する最後まで、想定どおりに実行されます。
gdbは、それが__bar_endの最後のポップebpにあると言います...なぜこれが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