不久前,我发布了this question关于我在尝试逐步完成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:命令行上没有选项)。重新启用它将导致类似以下内容:
.CODE
main PROC
int 3
00401010 int 3
mov eax, 6
00401011 mov eax,6
xor eax, eax
00401016 xor eax,eax
我应该注意,交错行是对原始代码的引用(我猜Visual Studio的反汇编窗口的一个特性)。启用增量链接后,反汇编完全符合我在程序中编写的内容,这就是我一直期望它的表现。
那么,为什么禁用增量链接会导致我的程序的反汇编被改变?幕后可能会发生什么,实际上会改变程序的执行方式?
答案 0 :(得分:1)
“add”指令是一个双字节指令,第二个指令是int3的1字节操作码。两个字节添加指令的第一个字节可能是在入口点之前的一些垃圾。 add指令的地址可能是int3指令之前的1个字节。
我快速组装,然后用GNU作为en objdump反汇编这两条指令,结果是:
8: 00 cc add %cl,%ah
a: cc int3
在这里你可以清楚地看到add指令包含第二个字节0xcc,而int3是0xcc
IOW确保您开始在入口点上进行反汇编以避免此问题。