來源:http://ibf.tw/xqzCv
備註:如果作者不希望被轉帖到此處,請告知,小弟會馬上刪帖。
-------------------------------------------------------------------------------------
資料轉移指令 ( Data Transfer Instructions ) * mov 指令
mov 目的 , 來源
◆ 兩個運算元要一樣的大小
◆ 兩個運算元不能是記憶體單元
◆ CS , EIP 及 IP 不能是目的運算元
◆ 一個立即值不能移至區段暫存器
◆ 區段暫存器只能在 real-mode下執行
* movzx 指令 (複製較小值到較大值,整數的補零)
movzx r32 , r/m8 movzx r32 , r/m16
movzx r16 , r/m8 ; 8bit來源運算元補零擴展到16bit目的運算元
◆ 只能用在無號整數 * movsx 指令 (複製較小值到較大值,符號擴展)
movzx r32 , r/m8
movzx r32 , r/m16
movzx r16 , r/m8 ; 低八位元複製後,取出來源最高位元,複製到目的運算元高八位元
◆ 只能用在有號整數
* Example : 移動
; movzx
mov bx , 0A69Bh
movzx eax , bx ; eax = 0000A69Bh
movzx edx , bl ; edx = 0000009Bh
movzx cx , bl ; cx = 009Bh
; movsx
mov bx , 0A69Bh
movsx eax , bx ; eax = FFFFA69Bh
movsx edx , bl ; edx = FFFFFF9Bh
movsx cx , bl ; cx = FF9Bh
; Memory-to-memory exchange
mov ax , val1 ; ax = 1000h
xchg ax , val2 ; ax = 2000h , val2 = 1000h
mov val1, ax ; val1 = 2000h
; Direct-Offset Addressing (byte array)
mov al , arrayB ; al = 10h , arrayB Byte 10h,20h,30h,40h,50h
mov al , [arrayB+1] ; al = 20h
mov al , [arrayB+2] ; al = 30h
; Direct-Offset Addressing (word array)
mov ax , arrayW ; ax = 100h , arrayW WORD 100h,200h,300h
mov ax , [arrayW+2] ; ax = 200h
; Direct-Offset Addressing (doubleword array)
mov eax , arrayD ; eax = 10000h , arrayD DWORD 10000h,20000h
mov eax , [arrayD+4] ; eax = 20000h
● 加法與減法
*零值旗標 : 當算術指令將目的運算元設為零時就會設定 zero flag
mov cx , 1
sub cx , 1 ; cx = 0 , ZF = 1
mov ax , 0FFFFh
inc ax ; ax = 0 , ZF = 1
inc ax ; ax = 1 , ZF = 0
*符號旗標 : 算術結果為負數時,就會設定sign flag
mov cx , 0
sub cx , 1 ; cx = -1 , SF = 1
add cx , 2 ; cx = 1 , SF = 0
*進位旗標 : 執行無號數運算時才會很重要,對目的運算元而言
無號數的加法結果太大(或太小),carry flag會被設定
◆ inc 與 dec指令不會影響進位旗標 mov al , 0FFh
add al , 1 ; CF = 1 , al = 00
mov ax, 00FFh
add ax, 1 ; CF = 0 , ax = 0100h
mov ax, 0FFFFh
add ax, 1 ; CF = 1 , ax = 0000h
mov al , 1
sub al , 2 ; CF = 1
*溢位旗標 : 只有在有號數算術時才會啟用 over flag
mov al , +127
add al , 1 ; OF = 1
mov al, - 128
sub al , 1 ; OF = 1
* Example :
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40
;---------------------------------------------------------------------
; inc and dec
mov ax , 1000h
inc ax ; 1001h
dec ax ; 1000h
; Expression : Rval = -Xval + ( Yval - Zval ) mov eax , Xval
neg eax ; -26
mov ebx , Yval
sub ebx , Zval ; -10
add eax , ebx
mov Rval , eax ; -36
; Zero flag
mov cx , 1
sub cx , 1 ; ZF = 1
mov ax , 0FFFFh
inc ax , 1 ; ZF = 1
; Sign flag
mov cx , 0
sub cx , 1 ; SF = 1
mov ax , 7FFFh
add ax , 2 ; SF = 1
; Carry flag
mov al , 0FFh
add al , 1 ; CF = 1 , al = 00
; Overflow flag
mov al , +127
add al , 1 ; OF = 1
mov al , -128
sub al , 1 ; OF = 1
;---------------------------------------------------------------------
● Data-Related Operators and Directives
*OFFSET : 傳回變數從所在區段開始的偏移距離
.data
bVal BYTE ?
wVal WORD ?
dVal DWORD ?
dVal2 DWORD ?
.code ; assume bVal's offset : 00404000
mov esi , OFFSET bVal ; ESI = 00404000
mov esi , OFFSET wVal ; ESI = 00404001
mov esi , OFFSET dVal ; ESI = 00404003
mov esi , OFFSET dVal2 ; ESI = 00404007
*ALIGN : 將變數置於位元組、字組、雙字組或是段落的邊界 ALIGN 邊界
邊界 = 1 : 下一變數位址會置於一個位元組的邊界(預設)
= 2 : 雙數的位址
= 4 : 四的倍數
bval BYTE ? ; 00404000
ALIGN 2
wVal DWORD ? ; 00404002
bVal2 BYTE ? ; 00404004
ALIGN 4
dVal DWORD ? ; 原本是00404005,現為00404008
dVal2 DWORD ? ; 0040400C
*PTR : 存取的變數大小與當初宣告的變數不同 .data
myDouble DWORD 12345678h
.code
mov ax , myDouble ; error
mov ax , WORD PTR myDouble ; ax = 5678h
mov ax , WORD PTR [myDouble + 2] ; ax = 1234h
mov bl , BYTE PTR myDouble ; bl = 78h
*TYPE : 傳回變數單一元件以 byte為單位的大小值 .data
var1 BYTE ?
var2 WORD ?
var3 DWORD ?
var4 QWORD ?
TYPE var1 ; 1
TYPE var2 ; 2
TYPE var3 : 4
TYPE var4 ; 8
*LENGTHOF : 計算陣列中的元件數 .data
byte1 BYTE 10,20,30
array1 WORD 30 DUP(?) , 0,0
array2 WORD 5 DUP( 3 DUP(?) )
array3 DWORD 1 ,2 ,3, 4
digitStr BYTE "12345678" , 0
LENGTHOF byte1 ; 3
LENGTHOF array1 ; 30+2
LENGTHOF array2 ; 5*3
LENGTHOF array3 ; 4
LENGTHOF digitStr ; 9
myArray BYTE 10,20,30,40,50
BYTE 60,70,80,90,100
LENGTHOF myArray ;只計算第一列定義的部分陣列,傳回 5
*SIZEOF : 傳回的值等於LENGTHOF乘上TYPE的值
intArray WORD 32 DUP(0) ; SIZEOF = 32 * 2
● 間接定址 : 暫存器當作指標 *間接運算元 : 可是任一個 32 bit通用暫存器(eax ebx ecx edx esi edi ebp esp)
◆在real-mode,若暫存器作間接運算元,僅可能是 si di bx 及bp,避免用bp
它通常用來定址堆疊區段
◆在間接運算元中使用PTR
inc [esi] ; 錯誤,運算元必須標示大小
inc BYTE PTR [esi]
*陣列 .data
arrayD DWORD 10000h , 20000h , 30000h
.code
mov esi , OFFSET arrayD
mov eax , [esi] ; first number
add esi , 4
add eax , [esi] ; second number
add esi , 4
add eax , [esi] ; third number
*索引運算元 : 加一個常數到暫存器上,產生一個有效位址
◆在real-mode,若暫存器作間接運算元,僅可能是 si di bx 及bp,避免用bp
它通常用來定址堆疊區段
常數[暫存器] [ 常數 + 暫存器 ] .data
arrayB BYTE 10h,20h,30h
.code
mov esi , 0
mov al , [ arrayB + esi ] ; al = 10h
*指標 : 變數中有另一個變數的位址時,稱為指標變數或指標
在 16 及 32 位元模式下的指標
16位元模式 | 32位元模式 | |
NEAR 指標 | 從資料區段開始的 16位元位移值 | 從資料區段開始的 32位元位移值 |
FAR 指標 | 32位元區段位移位址 | 48位元區段位移位址 |
保護模式使用NEAR指標,所以儲存在雙字組變¸
arrayB BYTE 10h , 20h , 30h , 40h
arrayW WORD 1000h , 2000h , 3000h
ptr DWORD arrayB
ptrW DWORD arrayW
ptrB DWORD OFFSET arrayB
ptrW DWORD OFFSET arrayW
*TYPEDEF : 定義變數時,建立使用者定義型態
PBYTE TYPEDEF PTR BYTE
.data
arrayB BYTE 10h , 20h , 30h , 40h
ptr1 PBYTE ? ;未初始化
ptr2 PBYTE arrayB ; 指向一個陣列
● JMP及LOOP指令 * JMP指令
JMP 目的標籤 top :
...
jmp top ;重覆無止盡迴圈
* LOOP指令 : 指定次數(ecx),重覆執行特定區段的指令
迴圈的目的必須在現在位置-128到+127之間 mov ax , 0
mov ecx , 5
L1:
inc ax
loop L1 ;迴圈中止後,ax=5 , ecx = 0
* Example : SumArray
intarray WORD 100h , 200h , 300h , 400h
mov edi , OFFSET intarray ; intarray位址
mov ecx , LENGTHOF intarray ; 迴圈次數
mov ax , 0 ; 歸零
L1:
add ax , [edi] ; 加上一整數
add edi , TYPE intarray ; 指向下一個整數
loop L1 ; 重複直到 ecx = 0
* Example : 字串複製
source BYTE "This is the source string" , 0
target BYTE SIZEOF source DUP(0) , 0
mov esi , 0 ; 索引暫存器
mov ecx , SIZEOF source ; 迴圈次數
L1:
mov al , source[esi] ; 從來源取得字元
mov target[esi] , al ; 儲存在目標
inc esi ; 移到下一個字元
loop L1 ; 重複整個字串
沒有留言:
張貼留言