Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 2010 Visual Studio仅在第二行程序集上中断? 简短描述:_Visual Studio 2010_Assembly_Masm - Fatal编程技术网

Visual studio 2010 Visual Studio仅在第二行程序集上中断? 简短描述:

Visual studio 2010 Visual Studio仅在第二行程序集上中断? 简短描述:,visual-studio-2010,assembly,masm,Visual Studio 2010,Assembly,Masm,在汇编程序中my.code段的第一行设置断点不会停止程序的执行 问题是: 如果VisualStudio的调试器允许它在汇编程序中编写的程序的第一行创建断点时失败,该怎么办?这是调试器的一些奇怪之处,是多字节指令中断的情况,还是我只是在做一些愚蠢的事情 详情如下: 我在Visual Studio中编译并运行了以下汇编程序: ; Tell MASM to use the Intel 80386 instruction set. .386 ; Flat memory model, and Win 32

在汇编程序中my
.code
段的第一行设置断点不会停止程序的执行

问题是: 如果VisualStudio的调试器允许它在汇编程序中编写的程序的第一行创建断点时失败,该怎么办?这是调试器的一些奇怪之处,是多字节指令中断的情况,还是我只是在做一些愚蠢的事情

详情如下: 我在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
这里有趣的是,在VisualStudio看来,
xor
是我程序中的第一个操作。缺少行
移动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  
并且不会停止执行,并在反汇编中再次损坏程序的视图。然后,我的程序的下一行位于位置
00401001
,我认为这是有意义的,因为
int 3
是一条单字节指令,但为什么它会在反汇编中消失呢

即使使用“单步执行(F11)”命令启动程序,也不允许我在第一行中断。事实上,如果没有断点,用F11启动程序根本不会停止执行

除了我在这里详述的以外,我不确定我还能尝试解决什么问题。这超出了我目前对汇编和调试器的理解。

如果按F+11(单步执行)而不是开始调试,调试器将在第一行停止

可能是断点设置有问题。删除项目目录中的所有*.suo文件以重置所有断点

请注意,如果您的项目有一个main函数,那么它将有一个秘密的标题和内容。要在实际入口点设置断点,请使用:调试+新建断点+函数处中断->windows程序的WWINMINCRTSTARTUP或控制台程序的mainCRTStartup或wmainCRTStartup

01370FFF添加字节ptr[ecx+6],bh

至少我能解释一个谜团。请注意地址0x1370fff。代码段从不从这样的地址开始,而是从0x1000的倍数开始。这使得起始地址的最后3个十六进制数字始终为0。调试器被搞糊涂了,开始在错误的地址逐个分解代码。实际起始地址为0x1371000。由于0x1370fff处有一个0,因此反汇编开始时很糟糕。这是一个多字节加法指令。因此,它会显示垃圾一段时间,直到它意外地赶上了真正的机器代码指令

您需要帮助它,并给它一个命令,以便在正确的地址开始反汇编。在地址框中,键入“0x1371000”

另一个值得注意的怪癖是起始地址的奇怪值。进程通常从地址0x400000开始。启用了一个名为ASLR的功能,地址空间布局随机化。它是一种防病毒功能,可使程序在不可预知的起始地址启动。这是一个不错的特性,但它并不能帮助调试程序。不清楚您是如何构建此代码的,但需要使用/DYNAMICBASE:NO linker选项将其关闭

这里您需要记住的调试器的另一个重要怪癖是它们设置断点的方式。它们通过修补代码,用
int3
指令替换指令的起始字节来实现。当断点命中时,它会用原始机器代码指令字节快速替换该字节。所以你从来没见过这个。如果您选择错误的地址来设置断点,那么这就错了,就像在多字节指令的中间。它现在不再中断代码,更改后的字节会弄乱原始指令。当你开始一个糟糕的拆卸时,你很容易陷入这个陷阱


好吧,用正确的方法来做。改用调试器的STEP命令开始调试。

我已经发现了问题的根源,但我不知道为什么会这样

在创建另一个MASM项目后,我注意到新的项目将在程序的第一行中断,并且反汇编似乎没有损坏或更改。因此,我将其属性与原始项目(用于调试配置)进行了比较。我发现的唯一区别是我原来的项目禁用了增量链接。具体来说,它向链接器命令行添加了
/INCREMENTAL:NO


从命令行中删除此选项(从而启用增量链接)会导致程序在调试期间按预期运行;反汇编窗口中显示的代码保持不变,我可以在
main
过程的第一行上点击断点,并且
int 3
指令也可以作为第一行正确执行。

“int 3”和“int 3”是两个不同的指令-尝试后一个指令(它是一个字节)。在Linux中,有时将“nop”作为文件中的第一项是很有帮助的。不同的情况,但在这里可能也有帮助(?。看起来您在不重建的情况下更改了代码:)您是否尝试重建然后设置断点?@FrankKotler感谢您的建议,但是
int3
是MASM中的语法错误
int 3
绝对是英特尔平台的正确指令。@OhadHoresh该版本是最新的。如果不是,我将无法命中任何断点,因为源将过期
.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  
00400FFF  add         ah,cl