0

不久前,我发布了这个关于我在尝试单步执行 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 反汇编窗口的一个功能)。启用增量链接后,反汇编完全符合我在程序中编写的内容,这就是我一直期望它的行为方式。

那么,为什么禁用增量链接会导致我的程序的反汇编被更改?幕后可能发生的事情会真正改变程序的执行方式?

4

1 回答 1

1

“add”指令是一个双字节指令,第二个是 int3 的 1 字节操作码。两字节相加指令的第一个字节可能是入口点之前的一些垃圾。add 指令的地址可能是 int3 指令所在位置的 1 个字节。

我用 GNU as en objdump 快速组装然后反汇编了这两条指令,结果是:

  8:    00 cc                   add    %cl,%ah
  a:    cc                      int3   

这里可以清楚的看到add指令包含第二个字节0xcc,而int3是0xcc

IOW 确保您在入口点开始反汇编以避免此问题。

于 2012-12-05T16:07:13.077 回答