【发布时间】:2012-10-26 02:45:14
【问题描述】:
简短说明:
在汇编程序中我的.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
如果我尝试在 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
这里有趣的是,xor 在 Visual Studio 眼中是我程序中的第一个操作。缺少的是move ecx, 6 行。它认为我的源代码开始的正上方是实际将ecx 设置为 6 的行。因此,我的程序的实际启动已根据反汇编进行了破坏。
如果我将程序的第一行设为int 3,则反汇编代码中出现在上面的行是:
00F80FFF add ah,cl
正如其中一个答案所建议的,我关闭了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
在反汇编中可以看到完整的程序,但问题仍然存在。尽管我的程序从预期的地址开始,并且在反汇编中显示了第一个断点,但它仍然被跳过。将int 3 作为第一行仍然会导致以下行:
00400FFF add ah,cl
并且不会停止执行,and 再次在反汇编中重新破坏我的程序的视图。然后我程序的下一行位于位置00401001,我认为这是有道理的,因为int 3 是一个单字节指令,但为什么它会在反汇编中消失?
即使使用“Step Into (F11)”命令启动程序也不允许我在第一行中断。事实上,没有断点,用 F11 启动程序根本不会停止执行。
除了我在这里详细介绍的内容之外,我不确定我还能尝试什么来解决这个问题。这超出了我目前对汇编和调试器的理解。
【问题讨论】:
-
"int 3" 和 "int3" 是两条不同的指令 - 试试后者(它是一个字节)。在 Linux 中,将“nop”作为文件中的第一件事有时会很有帮助。不同的情况,但在这里也可能有帮助(?)。
-
看起来您更改了代码但没有重新构建 :) 您是否尝试重新构建然后设置断点?
-
@FrankKotler 感谢您的建议,但
int3是 MASM 中的语法错误。int 3绝对是英特尔平台的正确指令。 -
@OhadHoresh 构建是最新的。如果不是因为源代码已经过时,我将无法达到任何断点。
-
如果您取消选中(调试选项)中的选项(要求源文件与原始版本完全匹配),您将能够使用过时的源代码打断点。跨度>
标签: visual-studio-2010 assembly masm