最低限のアセンブラ命令だけざっくり把握する

参考書籍 : たのしいバイナリの歩き方


よく使われるアセンブラ命令
MOV, ADD, SUB, INC, DEC
LEA : LEA EAX, [ECX+4] ; ECX+4のアドレスの値をEAXへ格納
CMP : CMP EAX, ECX ; EAXとECXが同じならZF=1, 異なればZF=0
TEST : TEST EAX, EAX ; EAXを0と比較して同じならZF=1, 異なればZF=0
JE(JZ) : JE 040010000 ; ZFが1なら040010000にジャンプ
JNE(JNZ) : JNE 040010000 ; ZFが0なら040010000にジャンプ
JMP
CALL
PUSH
POP


アセンブラではどのように条件分岐が実現されているのか

.text:00401000                 push    ebp
.text:00401001                 mov     ebp, esp
.text:00401003                 push    offset String2  ; "2012"
.text:00401008                 push    [ebp+lpCmdLine] ; lpString1
.text:0040100B                 call    ds:__imp__lstrcmpW@8 ; lstrcmpW(x,x)
.text:00401011                 push    0               ; uType
.text:00401013                 push    offset Caption  ; "MESSAGE"
.text:00401018                 test    eax, eax ; 比較の処理
.text:0040101A                 jnz     short loc_401034 ; 条件分岐の処理
.text:0040101C                 push    offset Text     ; "Hello! 2012"を表示
.text:00401021                 call    ds:__imp__GetActiveWindow@0 ; GetActiveWindow()
.text:00401027                 push    eax             ; hWnd
.text:00401028                 call    ds:__imp__MessageBoxW@16 ; MessageBoxW(x,x,x,x)
.text:0040102E                 xor     eax, eax
.text:00401030                 pop     ebp
.text:00401031                 retn    10h|
.text:00401034 ; ---------------------------------------------------------------------------
.text:00401034
.text:00401034 loc_401034:                             ; "Hello! Windows"を表示
.text:00401034                 push    offset aHelloWindows ; "Hello! Windows"
.text:00401039                 call    ds:__imp__GetActiveWindow@0 ; GetActiveWindow()
.text:0040103F                 push    eax             ; hWnd
.text:00401040                 call    ds:__imp__MessageBoxW@16 ; MessageBoxW(x,x,x,x)
.text:00401046                 xor     eax, eax
.text:00401048                 pop     ebp
.text:00401049                 retn    10h
.text:00401049 _wWinMain@16    endp

lstrcmpWの戻り値がeaxに渡され、testによって戻り値が0以外ならジャンプするようになっている。


・引数はスタックに積まれる

.text:00401003                 push    offset String2  ; "2012"
.text:00401008                 push    [ebp+lpCmdLine] ; lpString1
.text:0040100B                 call    ds:__imp__lstrcmpW@8 ; lstrcmpW(x,x)

引数は後ろからスタックへ積むため、C言語では次のようになる

eax = lstrcmpW(lpString1, "2012")