簡単な説明:
アセンブリ プログラムのセグメントの最初の行にブレークポイントを設定して.CODE
も、プログラムの実行が停止しません。
質問:
アセンブリで記述されたプログラムの最初の行で、Visual Studio のデバッガーがブレークポイントの作成に失敗することを許可するのはどうですか? これはデバッガーの奇妙な点ですか、マルチバイト命令で中断する場合ですか、それとも私が何かばかげたことをしているだけですか?
詳細:
次のアセンブリ プログラムを Visual Studio でコンパイルして実行しています。
; 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 ; <-- If uncommented, this will not break.
mov ecx, 6 ; <-- Breakpoint here will not hit.
xor eax, eax ; <-- Breakpoint here will.
_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
メイン関数の最初の行にブレークポイントを設定しようとするとmov ecx, 6
、それは無視され、プログラムは停止せずに実行されます。xor eax, eax
その後の行、または後続の行にブレークポイントを設定した場合にのみ、ブレークポイントがヒットします。
int 3
関数の最初の行としてソフトウェア ブレークポイントを挿入しようとしましたが、これも無視されます。
最初に奇妙な点に気付きました。ブレークポイントの 1 つにヒットした後に逆アセンブリを表示すると、次のようになります。
01370FFF add byte ptr [ecx+6],bh
--- [Path]\main.asm
xor eax, eax
00841005 xor eax,eax --- <-- Breakpoint is hit here
_label: add eax, ecx
00841007 add eax,ecx
dec ecx
00841009 dec ecx
jnz _label
0084100A jne _label (841007h)
cmp eax, 21
0084100C cmp eax,15h
ここで興味深いのxor
は、Visual Studio から見れば、これが私のプログラムの最初の操作であるということです。行がありませんmove ecx, 6
。私のソースが開始すると思われる場所のすぐ上に、実際にはecx
6 に設定されている行があります。したがって、私のプログラムの実際の開始は、逆アセンブルに従って壊れています。
プログラムの最初の行を作成するとint 3
、コードが逆アセンブリにある場所の上に表示される行は次のようになります。
00F80FFF add ah,cl
回答の1つで提案されているように、ASLRをオフにしましたが、逆アセンブリはもう少し安定しているようです:
.CODE
main PROC
;mov ecx, 6
xor eax, eax
00401000 xor eax,eax --- <-- Breakpoint is present here, but not hit.
_label: add eax, ecx
00401002 add eax,ecx --- <-- Breakpoint here is hit.
dec ecx
00401004 dec ecx
完全なプログラムは逆アセンブルで表示されますが、問題は解決しません。私のプログラムは予想されるアドレスで開始し、逆アセンブリに最初のブレークポイントが表示されますが、それでもスキップされます。最初の行としてan を配置しint 3
ても、次の行になります。
00400FFF add ah,cl
実行を停止せず、逆アセンブリでプログラムのビューを再びマングルします。私のプログラムの次の行は location00401001
にあり、これは 1 バイトの命令なので理にかなっていると思いますint 3
が、なぜ逆アセンブリで消えてしまったのでしょうか?
「ステップ イン (F11)」コマンドを使用してプログラムを開始しても、最初の行で中断できません。実際、ブレークポイントがない場合、F11 でプログラムを開始しても、実行はまったく停止しません。
ここで詳しく説明した以外に、問題を解決するために他に何ができるか本当にわかりません。これは、アセンブリとデバッガーに関する私の現在の理解を超えています。