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

「追加」命令は2バイトの命令であり、2番目の命令はint3の1バイトのオペコードです。2バイトのadd命令の最初のバイトは、おそらくエントリポイントの直前のゴミです。add命令のアドレスは、int3命令がある場所の1バイト前にある可能性があります。

GNUをenobjdumpとして使用して、これら2つの命令をすばやくアセンブルしてから逆アセンブルしたところ、結果は次のようになりました。

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

ここでは、add命令に2番目のバイト0xccが含まれているのに対し、int3は0xccであることがはっきりとわかります。

IOWは、この問題を回避するために、エントリポイントで逆アセンブルを開始することを確認してください。

于 2012-12-05T16:07:13.077 に答える