私はアセンブリ(ネットワイドアセンブラ)にatoiを実装しようとしています。デバッガーでレジスター値を検査することにより、私のアプローチが有効であることを確認しました。問題は、アプリケーションが終了しようとしているときにクラッシュすることです。私のプログラムが何らかの形でスタックを破損しているのではないかと心配しています。printf 関数の使用を許可するために、GCC stdlib に対してリンクしています。レジスタが変更され、予期しない動作 (認識できない値に対する広範な反復) が発生したことに気付きましたが、EAX の値を EBX 内に格納し (printf によって変更されていません)、関数呼び出しの後に値を復元することでこれを解決しました。これが、アルゴリズムをシングルステップ実行することでプログラムが想定どおりに動作することを確認し、プログラムが終了しようとしてクラッシュすることを確認できた理由です。コードは次のとおりです。
global _main
extern _printf
section .data
_str: db "%d", 0
section .text
_main:
mov eax, 1234
mov ebx, 10
call _itoa
_terminate:
ret
_itoa:
test eax, eax
jz _terminate
xor edx, edx
div ebx
add edx, 30h
push eax
push edx
push _str
call _printf
add esp, 8
pop eax
jmp _itoa
そして、ここにスタックダンプがあります:
例外:eip = 00402005のstatus_access_violation = 00402005 EAX = 00000000 EBX = 00000000 ECX = 20000038 EDX = 61185C40 ESI = 612A3A7C EDI = 0022CD84 EBP = 0022ACF8 ESP = 002AC20 PROMINT PROGRAM \ 5. ESGIN , thread main cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023 Stack trace: Frame Function Args 0022ACF8 00402005 (00000000, 0022CD84, 61007120, 00000000) スタックトレース終了
編集: プログラムがクラッシュしなくなったため、スタックダンプは実際にはあまり関係がないことに注意してください。誤った値が表示されるだけです。