kev*_*sco 5 assembly masm visual-studio-2010
.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
Run Code Online (Sandbox Code Playgroud)
如果我尝试在main函数的第一行设置断点mov ecx, 6
,则忽略它,并且程序在不停止的情况下执行.只有在我将其设置在该行xor eax, eax
或任何后续行之后的行上时才会触发断点.
我甚至尝试插入一个软件断点,int 3
作为函数的第一行,它也被忽略了.
我注意到的第一件事很奇怪:在点击我的一个断点后查看反汇编给出了以下内容:
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
Run Code Online (Sandbox Code Playgroud)
这里有趣的xor
是,在Visual Studio的眼中,是我程序中的第一个操作.缺席就是这条线move ecx, 6
.直接在它认为我的源开始的地方上面是实际设置ecx
为6 的行.所以我的程序的实际开始根据反汇编被破坏了.
如果我创建程序的第一行int 3
,那么我的代码在反汇编中的上面显示的行是:
00F80FFF add ah,cl
Run Code Online (Sandbox Code Playgroud)
正如其中一个答案中所建议的,我关闭了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
Run Code Online (Sandbox Code Playgroud)
完整的程序在反汇编中可见,但问题仍然存在.尽管我的程序从预期地址开始,并且第一个断点显示在反汇编中,但它仍然被跳过.将int 3
第一行作为第一行仍然会产生以下行:
00400FFF add ah,cl
Run Code Online (Sandbox Code Playgroud)
并且不会停止执行,并再次重新破坏我的程序在反汇编中的视图.我的程序的下一行是在位置00401001
,我认为这是有道理的,因为它int 3
是一个单字节指令,但为什么它会在反汇编中消失?
即使使用'Step Into(F11)'命令启动程序也不允许我在第一行中断.事实上,没有断点,用F11启动程序根本不会停止执行.
除了我在这里详细介绍的内容之外,我不确定我还能尝试解决这个问题.这超出了我目前对汇编和调试器的理解.
我已经发现了问题的根源是什么,但我不知道为什么会这样。
创建另一个 MASM 项目后,我注意到新的项目会在程序的第一行中断,并且反汇编似乎没有被破坏或更改。因此,我将其属性与我的原始项目(用于调试配置)进行了比较。我发现的唯一区别是我原来的项目禁用了增量链接。具体来说,它添加/INCREMENTAL:NO
到链接器命令行中。
从命令行中删除此选项(从而启用增量链接)会导致程序在调试期间按预期运行;反汇编窗口中显示的代码保持不变,我可以在过程的第一行上命中断点main
,并且int 3
指令也将作为第一行正确执行。