少し前に、MASMプログラムをステップ実行しようとしたときに経験した奇妙な動作に関するこの質問を投稿しました。
基本的に、次のコードが与えられます。
; Tell MASM to use the Intel 80386 instruction set.
.386
; Flat memory model, and Win 32 calling convention
.MODEL FLAT, STDCALL
; Treat labels as case-sensitive (required for windows.inc)
OPTION CaseMap:None
include windows.inc
include masm32.inc
include user32.inc
include kernel32.inc
include macros.asm
includelib masm32.lib
includelib user32.lib
includelib kernel32.lib
.DATA
BadText db "Error...", 0
GoodText db "Excellent!", 0
.CODE
main PROC
int 3
mov eax, 6
xor eax, eax
_label: add eax, ecx
dec ecx
jnz _label
cmp eax, 21
jz _good
_bad: invoke StdOut, addr BadText
jmp _quit
_good: invoke StdOut, addr GoodText
_quit: invoke ExitProcess, 0
main ENDP
END main
int 3
トリガーする命令を取得できませんでした。分解を調べて、なぜそうしなかったのかは明らかでした:
00400FFD add byte ptr [eax],al
00400FFF add ah,cl
--- [User path]\main.asm
mov eax, 6
00401001 mov eax,6
xor eax, eax
00401006 xor eax,eax
_label: add eax, ecx
int 3
命令はに置き換えられましたが、add al,cl
理由はわかりませんでした。インクリメンタルリンクが有効になっているかどうかまで問題を追跡することができました。上記の分解は、インクリメンタルリンクを無効にして生成されました(コマンドラインの/ INCREMENTAL:NOオプション)。再度有効にすると、次のようになります。
.CODE
main PROC
int 3
00401010 int 3
mov eax, 6
00401011 mov eax,6
xor eax, eax
00401016 xor eax,eax
インターリーブ行は元のコードへの参照であることに注意してください(Visual Studioの逆アセンブリウィンドウの機能だと思います)。インクリメンタルリンクを有効にすると、逆アセンブルはプログラムで記述した内容に正確に対応します。これは、プログラムがずっと動作することを期待していた方法です。
では、なぜインクリメンタルリンクを無効にすると、プログラムの逆アセンブリが変更されるのでしょうか。プログラムの実行方法を実際に変更する舞台裏で何が起こっている可能性がありますか?