第3章 主要なニーモニックの説明 その 0

前へ  戻る     次へ

これから書かれていることはOllyの実践的な使い方ではなく、
アセンブラニーモニックの説明を初めとする基本的な使い方です。


それでは今回では本格的に主要なニーモニックの説明に入ります。

ニーモニックのインデックスからサンプルプログラムがダウンロードできます。


○ADDとSUB

書式:ADD dest,src

SUB dest,src


 簡単に言うとADDは足し算,SUBは引き算です。サンプルプログラムを見るだけでも分かると思いますが、dest±srcです(ハショりすぎw)。演算の結果をdestに転送します

何か、MOVで説明しなかったような気がするので一応遅補足しておくと、destdestination operand, srcsource operandのことです。Operandっていうのは演算の対象となるデータのことですね。

 

00401000 >/$ B8 01000000    MOV EAX,1                         ;  EAX1を転送

00401005  |. 05 FFFF0000    ADD EAX,0FFFF                     ;  EAXFFFFを転送

0040100A  |. 66:83E8 01     SUB AX,1                          ;  AXから1引く

0040100E  |. 04 01          ADD AL,1                          ;  AL1加える

00401010  |. A3 00304000    MOV DWORD PTR DS:[403000],EAX     ;  メモリの403000EAXを転送

00401015  |. 2905 00304000  SUB DWORD PTR DS:[403000],EAX     ;  メモリの403000からEAXを引く

0040101B  |. 6A 00          PUSH 0                            ; /ExitCode = 0

0040101D  \. E8 00000000    CALL <JMP.&kernel32.ExitProcess>  ; \ExitProcess

 

サンプルの説明は特に必要無いでしょう。分からなかったらBBSで質問して下さい。実行時は2の補数を念頭に入れて追ってみるといいかと思います(そういう風に作ったので)。


○INCとDEC
書式:INC dest

DEC dest

destの値を1足す,あるいは1引くという意味です。どっちが、までは説明するまでも無いと思いますが、C言語の++--に相当します。ハイ、必要ない気もしますが一応サンプルプログラムです。

 

00401000 >/$ B8 00000000    MOV EAX,0                         ;  初期化

00401005  |. 40             INC EAX                           ;  EAX1加える

00401006  |. 66:48          DEC AX                            ;  AXから1引く

00401008  |. FEC4           INC AH                            ;  AH1加える

0040100A  |. 48             DEC EAX                           ;  EAXから1引く

0040100B  |. FECC           DEC AH                            ;  AHから1引く

0040100D  |. 6A 00          PUSH 0                            ; /ExitCode = 0

0040100F  \. E8 00000000    CALL <JMP.&kernel32.ExitProcess>  ; \ExitProcess

 

これも特に説明の必要はないですねw


○MULとIMUL
書式:MUL src

IMUL src

   IMUL dest,src

   IMUL dest,src1,src2

 

 掛け算です。アセンブラの乗除は複雑です。何故なら、扱うビットをまず超えてしまうためです。100×10010000で桁が全然違うことを考えれば当たり前ですね。従って演算結果を転送する領域に注意が必要になります。与太話はこれくらいにして実際にそれぞれの説明に入ります。

 MUL srcsrcによって転送する領域が変わります。それぞれ

srcが8ビット

BYTEサイズ)

src ALの乗算結果をAXレジスタに転送

src16ビット

WORDサイズ)

src AXの乗算結果の上位16ビットをDXに、下位16ビットをAXレジスタに転送

(二つのレジスタにより32ビットを表現する)

src32ビット

DWORDサイズ)

src EAXの乗算結果の上位32ビットをEDXに、下位32ビットをEAXレジスタに転送

(二つのレジスタにより64ビットを表現する)

 

IMUL srcMULと同じです。

IMUL dest,srcdestsrcの乗算結果をdestに転送します。destはレジスタでなければなりません。srcはレジスタでもメモリ参照でも数値でもOKです。

IMUL dest,src1,src2はいい加減予想もつきそうですが、src1src2の乗算結果をdestに転送します。destはレジスタ,src1はレジスタまたはメモリ参照,src2は数値が入ります。

 

00401000 >/$ B8 68243412    MOV EAX,12342468

00401005  |. BA 78563412    MOV EDX,12345678

0040100A  |. F6E2           MUL DL                            ;  78×68AX

0040100C  |. 66:F7E2        MUL DX                            ;  5678×30C0AX:DX

0040100F  |. BA 78563412    MOV EDX,12345678

00401014  |. F7EA           IMUL EDX                          ;  12345678×12345A00EDX:EAX

00401016  |. B8 00500000    MOV EAX,5000

0040101B  |. BA 33330000    MOV EDX,3333

00401020  |. 0FAFC2         IMUL EAX,EDX                      ;  3333×5000EAX

00401023  |. 69C2 66660000  IMUL EAX,EDX,6666                 ;  3333×6666EAX

00401029  |. 6A 00          PUSH 0                            ; /ExitCode = 0

0040102B  \. E8 00000000    CALL <JMP.&kernel32.ExitProcess>  ; \ExitProcess

 

まぁあまり見ないのでそれほど気にしなくてもいい気もしますw


○DIVとIDIV

書式:DIV src

   IDIV  src

 

ハイ、もちろん割り算です。またもやsrcのサイズに応じて計算結果を転送します。

ちなみにDIVIDIVで挙動は同じです。srcにはレジスタかメモリ参照が入ります。

srcが8ビット

BYTEサイズ)

AHを上位8ビット,ALを下位8ビットとする全部で16ビット(つまりAXのこと)をsrc で除し(AH:AL/srcAX/src)、商をAL,余りをAHレジスタに転送

src16ビット

WORDサイズ)

DXを上位16ビット,AXを下位16ビットとする全部で32ビット(つまりDX:AX)をsrc で除し(DX:AX /src)、商をAX,余りをDXレジスタに転送

src32ビット

DWORDサイズ)

EDXを上位32ビット,EAXを下位32ビットとする全部で64ビット(つまりEDX:EAX)をsrc で除し(EDX:EAX /src)、商をEAX,余りをEDXレジスタに転送

 

略して書くとこんな感じです。

srcのサイズ

演算処理

余り

BYTE

AH:AL/src

AL

AH

WORD

DX:AX/src

AX

DX

DWORD

EDX:EAX/src

EAX

EDX

 

 ちなみにsrc0を与えるとエラーになります。また、商や余りがその持つ領域を超えるような場合もエラーになります。例えば1010÷101010ですね。これはsrcBYTEサイズなので商・余りもBYTEサイズでないといけませんが、101WORDサイズの領域が必要になります。従ってエラーです。まぁ「余り小さい数で割らないようにしようsrcを余り小さくしない」ということです。

 

00401000 >/$ B4 12          MOV AH,12

00401002  |. B0 34          MOV AL,34

00401004  |. B2 20          MOV DL,20

00401006  |. F6F2           DIV DL                              ;  1234/209114

00401008  |. B8 78560000    MOV EAX,5678

0040100D  |. BA 34120000    MOV EDX,1234

00401012  |. C705 00304000 >MOV DWORD PTR DS:[403000],4321      ;  12345678/4321456C1F8C

0040101C  |. 66:F735 003040>DIV WORD PTR DS:[403000]

00401023  |. B8 F0DEBC9A    MOV EAX,9ABCDEF0

00401028  |. BA 78563412    MOV EDX,12345678

0040102D  |. C705 00304000 >MOV DWORD PTR DS:[403000],98765432

00401037  |. F735 00304000  DIV DWORD PTR DS:[403000]           ;  123456789ABCDEF0/987654321E9131AB91430F8A

0040103D  |. 6A 00          PUSH 0                              ; /ExitCode = 0

0040103F  \. E8 00000000    CALL <JMP.&kernel32.ExitProcess>    ; \ExitProcess

 


 

 と言うことで、第二回はアセンブラの四則演算でした。本当は主要なニーモニック全部説明しようかとも思ったのですが冗長的になりそうだったので。第三回では他のニーモニックの説明を完結させたいと思いますが、わたしのモチベーションによっては第四回まで伸びるかも・・・^^;

 なお、ニーモニックが終わったらいよいよAPIの登場です。

 


サンプルプログラムの著作権とかは面倒なので放棄してます。好きに使ってもらって構いません。


 

前へ  戻る     次へ