大學必修-筆記
暫存器名稱 | 中文名稱 | 用途 |
---|---|---|
AX | 累加器暫存器 | 用在算術運算 |
BX | 基址暫存器 | 作為一個指向資料的指標 |
CX | 計數器暫存器 | 用於移位/迴圈指令和迴圈 |
DX | 資料暫存器 | 用在算術運算和I/O操作 |
SP | 堆疊指標暫存器 | 用於指向堆疊的頂部 |
BP | 棧基址指標暫存器 | 用於指向堆疊的底部 |
SI | 源變址暫存器 | 在流操作中用作源的一個指標 |
DI | 標的索引暫存器 | 用作在流操作中指向標的的指標 |
暫存器 | 累加器 | 基址 | 計數器 | 資料 | ||||
---|---|---|---|---|---|---|---|---|
32-bit | EAX | EBX | ECX | EDX | ||||
16-bit | AX | BX | CX | DX | ||||
8-bit | AH | AL | BH | BL | CH | CL | DH | DL |
| 暫存器 | 堆疊指標 | 棧基址指標 | 源變址 | 標的索引 |
|––––|:––:|:––-:|:––:|:––-:|:––:|:––:|
| 32-bit |ESP | EBP | ESI | EDI |
| 16-bit | SP | BP | SI | DI |
暫存器名稱 | 中文名稱 |
---|---|
CS | 程式區段暫存器 |
DS | 資料區段暫存器 |
SS | 堆疊區段暫存器 |
ES | 額外區段暫存器 |
FS | 額外區段暫存器 |
GS | 額外區段暫存器 |
FLAG名稱 | 中文名稱 |
---|---|
CF (Carry) | 進位旗標 |
OF (Overflow) | 溢位旗標 |
ZF (Zero) | 零值旗標 |
AF (Auxiliary) | 輔助進位旗標 |
PF (Parity) | 奇偶旗標 |
DF (Direction) | 方向旗標 |
IF (Interrupt) | 中斷旗標 |
TF (Trap) | 單步旗標 |
數字結尾
指令格式
指令範本
TITLE Program Template (Template.asm)
; Program Description:
; Author:
; Creation Date:
; Revisions:
; Date: Modified by:
INCLUDE Irvine32.inc
.data
; (這裡插入變數)
.code
main PROC
; (這裡插入可執行的 instructions)
exit
main ENDP
; (這裡插入額外的程序)
END main
Unsigned Data Types | 功用 | Signed Data Types | 功用 |
---|---|---|---|
BYTE | 8-bit unsigned integer | SBYTE | 8-bit signed integer |
WORD | 16-bit unsigned integer | SWORD | 16-bit signed integer |
DWORD | 32-bit unsigned integer | SDWORD | 32-bit signed integer |
QWORD | 64-bit integer | ||
TBYTE | 80-bit integer |
Data Types | 功用 |
---|---|
REAL4 | 32-bit (4 byte) IEEE短實數 |
REAL8 | 64-bit (8 byte) IEEE長實數 |
REAL10 | 80-bit (10 byte) IEEE延伸實數 |
名稱 型態 值
value BYTE 10 -> 定義一個BYTE 名字value 值為10
value BYTE ? -> 定義一個BYTE 名字value 值末定
list BYTE 10, 20, 30, 40 -> 定義一個BYTE 大小有四格的矩陣
list BYTE ?, 32, 41h, 00100010b
利用 DUP()
list BYTE 20 DUP(0) -> 定義一個大小為 20 byte(格),內容皆為 0 的矩陣
string BYTE "Hallo World!", 0 -> 記得要加上 0,表示結束
string BYTE "Hallo World!", 0dh, 0ah, 0 -> 表示換行
Directive 則是人自己手動加入的,而不屬於 CPU 的指令,作用有兩種:
而這個部分,並不會被 assembler 轉為 machine code,一般常見的 directive 用法大概有幾種:
list BYTE 10, 20, 30, 40
ListSize = ($ - list) ; 得到 list 矩陣的 index 個數
list WORD 1000h, 2000h, 3000h, 4000h
ListSize = ($ - list) / 2 ; 得到 list 矩陣的 index 個數
list DWORD 1, 2, 3, 4
ListSize = ($ - list) / 4 ; 得到 list 矩陣的 index 個數
PI EQU <3.1416>
move EAX, PI
continueMsg TEXTEQU <"Do you wish to continue (Y/N)?"> // 定義為文字
count TEXTEQU %(rowSize * 2) // 定義為計算式
setupAL TEXTEQU <mov al, count> // 定義為指令
COUNT = 500
mov al,COUNT
;定義兩個陣列,每個元素的大小分別為 byte 與 word
byteArray db 5, 4, 3, 2, 1
wordArray dw 5, 4, 3, 2, 1
;存取 byte 陣列
mov al, [byteArray] ;AL = byteArray[0]
mov al, [byteArray + 1] ;AL = byteArray[1]
mov [byteArray + 3], al ;byteArray[3] = AL
;存取 word 陣列
mov ax, [wordArray] ;AX = wordArray[0]
mov ax, [wordArray + 2] ;AX = wordArray[1] 注意! 這邊 + 2 bytes 即是 + 1 word
mov [wordArray + 6], ax ;wordArray[3] = AX
mov ax, [wordArray + 1] ;這是錯誤的用法,因為元素大小為 word(2 bytes)
;存取 dword 陣列
mov ax, [dwordArray] ;AX = dwordArray[0]
mov ax, [dwordArray + 4] ;AX = dwordArray[1] 注意! 這邊 + 4 bytes 即是 + 1 dword
register
memory
immediate
implied
MOV 目地, 來源
XCHG 要互換的資料, 要互換的資料
INC 變數名稱
DEC 變數名稱
inc myWord ; 1001h
dec myWord ; 1000h
inc myDword ; 10000001h
mov ax, 00FFh
inc ax ; AX = 0100h
mov ax, 00FFh
inc al ; AX = 0000h
myByte BYTE 0FFh, 0
mov al, myByte ; AL = FFh
mov ah, [myByte+1] ; AH = 00h
dec ah ; AH = FFh
inc al ; AL = 00h
dec ax ; AX = FEFF
ADD 目標變數, [數字, 變數]
SUB 目標變數, [數字, 變數]
.data
var1 DWORD 10000h
var2 DWORD 20000h
.code
mov eax, var1 ; 00010000h
add eax, var2 ; 00030000h
add ax, 0FFFFh ; 0003FFFFh
add eax, 1 ; 00040000h
sub ax, 1 ; 0004FFFFh
NEG [變數名稱, 暫存器]
.data
valB BYTE -1
valW WORD +32767
.code
mov al,valB ; AL = -1
neg al ; AL = +1
neg valW ; valW = -32767
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
mov al, 0
sub al, 1 ; AL = 11111111b, SF = 1
add al, 2 ; AL = 00000001b, SF = 0
mov al, 0FFh
add al, 1 ; CF = 1, AL = 00
mov al, 0
sub al, 1 ; CF = 1, AL = FF
mov al, -128
neg al ; CF = 1 OF = 1
mov ax, 8000h
add ax, 2 ; CF = 0 OF = 0
mov ax, 0
sub ax, 2 ; CF = 1 OF = 0
mov al, -5
sub al, +125 ; OF = 1
mov esi, 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 因為 BYTE 1 個 byte
mov esi, OFFSET dVal ; ESI = 00404003 因為 WORD 2 個 byte
mov esi, OFFSET dVal2 ; ESI = 00404007 因為 DWORD 4 個 byte
型態 PTR 變數名
.data
myDouble DWORD 12345678h
mov al, BYTE PTR myDouble ; AL = 78h
mov al, BYTE PTR [myDouble+1] ; AL = 56h
mov al, BYTE PTR [myDouble+2] ; AL = 34h
mov ax, WORD PTR myDouble ; AX = 5678h
mov ax, WORD PTR [myDouble+2] ; AX = 1234h
.data
myBytes BYTE 12h, 34h, 56h, 78h
.code
mov ax, WORD PTR [myBytes] ; AX = 3412h
mov ax, WORD PTR [myBytes+2] ; AX = 7856h
mov eax, DWORD PTR myBytes ; EAX = 78563412h
.data
var1 BYTE ?
var2 WORD ?
var3 DWORD ?
var4 QWORD ?
.code
mov eax,TYPE var1 ; 1
mov eax,TYPE var2 ; 2
mov eax,TYPE var3 ; 4
mov eax,TYPE var4 ; 8
byte1 BYTE 10, 20, 30 ; 3
array1 WORD 30 DUP(?), 0, 0 ; 32
array2 WORD 5 DUP(3 DUP(?)) ; 15
digitStr DWORD "12345678", 0 ; 9
mov ecx, LENGTHOF array1 ; 32
byte1 BYTE 10,20,30 ; 3 = 3 * 1
array1 WORD 30 DUP(?),0,0 ; 64 = 32 * 2
array2 WORD 5 DUP(3 DUP(?)) ; 30 = 15 * 2
digitStr DWORD "12345678",0 ; 36 = 9 * 4
.data
array WORD 10, 20
WORD 30, 40
WORD 50, 60
.code
mov eax, LENGTHOF array ; 2 -> 只會看 WORD 10,20
mov ebx, SIZEOF array ; 4 -> 只會看 WORD 10,20
.data
dwList LABEL DWORD
wordList LABEL WORD
intList BYTE 00h, 10h, 00h, 20h
.code
mov eax,dwList ; 20001000h
mov cx,wordList ; 1000h
mov dl,intList ; 00h
.data
val1 BYTE 10h, 20h, 30h
.code
mov esi,OFFSET val1
mov al,[esi] ; dereference ESI (AL = 10h)
inc esi
mov al,[esi] ; AL = 20h
inc esi
mov al,[esi] ; AL = 30h
.data
myCount WORD 0
.code
mov esi,OFFSET myCount
inc esi ; 錯誤
inc WORD PTR [esi] ; 要給一個確定的大小才是對的
常數[暫存器]
[ 常數 + 暫存器 ]
.data
arrayW WORD 1000h, 2000h, 3000h
.code
mov esi, 0
mov ax, [arrayW + esi] ; AX = 1000h
mov ax, arrayW[esi] ; 另一種寫法
add esi, 2
add ax, [arrayW + esi]
.data
arrayW WORD 1000h, 2000h, 3000h
ptrW DWORD arrayW ; 定義一個指標變數
ptrW DWORD OFFSET arrayW ; 另一種寫法
.code
mov esi, ptrW ; 把指標變數丟給 esi 暫存器
mov ax, [esi] ; AX = 1000h
JMP 目的標籤
top:
...
jmp top ; 跳到 top 標籤
mov ax, 0
mov ecx, 5
L1:
inc ax
loop L1 ; 迴圈中止後 ax = 5, ecx = 0
mov ecx,0
X2:
inc ax
loop X2 ; 迴圈中止後 ax = 4,294,967,296, ecx = 0
.data
count DWORD ?
.code
mov ecx,100 ; 設定 L1 外迴圈的次數
L1:
mov count,ecx ; 把 L1 的次數存起來
mov ecx,20 ; 設定 L2 外迴圈的次數
L2:
...
loop L2 ; 重複 L2 迴圈
mov ecx, count ; 把 L1 的迴圈次數存回來
loop L1 ; 重複 L1 迴圈
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
source BYTE "This is the source string", 0
target BYTE SIZEOF source DUP(0)
mov esi, 0 ; 索引暫存器
mov ecx, SIZEOF source ; 迴圈次數
L1:
mov al, source[esi] ; 從來源取得字元
mov target[esi], al ; 儲存在目標
inc esi ; 移到下一個字元
loop L1 ; 重複整個字串
INCLUDE Irvine32.inc
.code
mov eax,1234h
call WriteHex ; print 出 hex
call Crlf ; 結束一行
mov ecx, 100 ; 設定外部迴圈次數
L1: ; 外部迴圈開始
push ecx ; 把目前外部迴圈的次數存起來
mov ecx, 20 ; 設定內部迴圈次數
L2: ; 內部迴圈開始
...
loop L2 ; 回 L2
pop ecx ; 把外部迴圈的次數重新存回 ecx
loop L1 ; 回 L1
程序名稱 PROC
......
ret
程序名稱 ENDP
main PROC // 以下為各指令的 OFFSET (位置)
call MySub // 00000020
mov eax, ebx // 00000025 -> mov 的 offset
main ENDP
MySub PROC
mov eax, edx // 00000040 -> MySub 程序第一行的 offset
ret
MySub ENDP
call 呼叫程序
ret (return) 回傳
call 會 push 00000025 到 stack 上
然後把 00000040 存進 EIP(下一個執行指標) 裡
ret 會從 stack pop 出 00000025 到 EIP 裡面
theSum DWORD ?
mov eax, 10000h ; 參數 1
mov ebx, 20000h ; 參數 2
mov ecx, 30000h ; 參數 3
call SumOf ; eax = ( eax + ebx + ecx)
mov theSum, eax ; 存到 theSum 裡
程序名稱 PROC USES [暫存器名稱, 暫存器名稱, ...]
ArraySum PROC USES esi ecx
mov eax, 0
L1:
add eax, [esi]
add esi, 4
loop L1
ret
ArraySum ENDP
ArraySum PROC
push esi // 由組譯器產生
push ecx // 由組譯器產生
mov eax, 0
L1:
add eax, [esi]
add esi, 4
loop L1
pop ecx // 由組譯器產生
pop esi // 由組譯器產生
ret
ArraySum ENDP
AND 目的地, 來源
00111011
00001111 (and
-------------
00001011
01100001 = 61h ('a')
11011111 = DFh (and ; 將字元與 11011111 作 and 運算轉成大寫
-----------------------------------
01000001 = 41h ('A')
OR 目的地, 來源
00111011
00001111 (or
-------------
00111111
00000101 = 05h
00110000 = 30h (or ; 將字元與 00110000 作 or 運算轉成ascii
-----------------------------------
00110101 = 35h ('5')
XOR 目的地, 來源
00111011
00001111 (xor
-------------
00110100
NOT 目的地, 來源
00111011 (not
-------------
11000100
TEST 變數名稱, 變數名稱
mov al, 00001101b ; 輸入值
test al, 00000001b ; 測試位元 0,結果為 00000001b,ZF = 0
------------------------------
mov al, 00001101b ; 輸入值
test al, 00000010b ; 測試位元 1,結果為 00000000b,ZF = 1
CMP 目的地, 來源
與 flag 的互動
無號數
有號數
and al, 0 ; zero flag = 1,任何運算元和 0 作 and 運算
or al, 1 ; zero flag = 0,任何運算元和 1 作 or 運算
or al, 80h ; sign flag = 1,任何運算元和 100000000 作 or 運算
and al, 7Fh ; sign flag = 0,任何運算元和 01111111 作 and 運算
stc ; carry flag = 1
clc ; carry flag = 0
mov al, 7Fh ; al = +127
inc al ; al = 80h(-128) , overflow flag = 1
or eax, 0 ; overflow flag = 0
條件跳越指令的類型
一些幫助記憶的代碼
特別的 jump
助憶符 | 說明 | 旗標 |
---|---|---|
JZ | 若為零則跳 | ZF = 1 |
JNZ | 若不為零則跳 | ZF = 0 |
JC | 若進位則跳 | CF = 1 |
JNC | 若不進位則跳 | CF = 0 |
JO | 若溢位則跳 | OF = 1 |
JNO | 若不溢位則跳 | OF = 0 |
JS | 若負號則跳 | SF = 1 |
JNS | 若非負號則跳 | SF = 0 |
JP | 同位(偶)則跳 | PF = 1 |
JNP | 非同位(偶)則跳 | PF = 0 |
助憶符 | 說明 |
---|---|
JE | 相等則跳 |
JNE | 不相等則跳 |
JCXZ | 若 CX = 0 則跳 |
JECXZ | 若 ECX = 0 則跳 |
助憶符 | 說明 |
---|---|
JA | 較大則跳 |
JNBE | 不是較小或相等則跳 (=JA) |
JAE | 較大或相等則跳 |
JNB | 不是較小則跳 (=JAE) |
JB | 較小則跳 |
JNAE | 不是較大或相等則跳 (=JB) |
JBE | 較小或相等則跳 |
JNA | 不是較大則跳 (=JBE) |
助憶符 | 說明 |
---|---|
JG | 較大則跳 |
JNLE | 不是較小或相等則跳 (=JG) |
JGE | 較大或相等則跳 |
JNL | 不是較小則跳 (=JGE) |
JL | 較小則跳 |
JNGE | 不是較大或相等則跳 (=JL) |
JLE | 較小或相等則跳 |
JNG | 不是較大則跳 (=JLE) |
cmp eax, ebx
ja Larger
cmp eax, ebx
jg Greater
cmp EAX, Val1
jbe L1
cmp EAX, Val1
jle L1
mov Large, bx
cmp ax, bx
jna Next
mov Large, ax
Next:
cmp WORD PTR [esi], 0
je L1
test DWORD PTR [edi], 1 // 與 1 作 and
jz L2
and al,00001011b ; 清空不須要的 bit
cmp al,00001011b ; 檢查剩下的 bit
je L1
bt bitBase, n
目標暫存器, 第n個位元
bt ax, 9 ; CF = bit 9
jc L1 ; jump if Carry
.data
array SWORD -3, -6, -1, -10, 10, 30, 40, 4
sentinel SWORD 0
.code
mov esi, OFFSET array
mov ecx, LENGTHOF array
next:
test WORD PTR [esi], 8000h ; test sign bit
pushfd ; 將flag放入堆疊
add esi, TYPE array
popfd ; 將flag從堆疊中拿出
loopnz next ; 迴圈繼續
jnz quit ; none found
sub esi, TYPE array ; ESI 指向該值
quit:
if( op1 == op2 )
X = 1;
else
X = 2;
--------------------------------
mov eax, op1
cmp eax, op2
jne L1
mov X, 1
jmp L2
L1:
mov X, 2
L2:
if( ebx <= ecx )
{
eax = 5;
edx = 6;
}
--------------------------------
cmp ebx, ecx
ja next
mov eax, 5
mov edx, 6
next:
if (al > bl) && (bl > cl)
X = 1;
--------------------------------
// 用正面的邏輯去實作
// code 比較長
cmp al, bl ; 第一次比較
ja L1
jmp next
L1:
cmp bl, cl ; 第二次比較
ja L2
jmp next
L2: ; 都是對的時
mov X, 1 ; 把 X 設成 1
next:
--------------------------------
// 用反面的邏輯去實作
// code 比較短
cmp al, bl ; 第一次比較
jbe next ; 離開 if false
cmp bl, cl ; 第二次比較
jbe next ; 離開 if false
mov X, 1 ; 都是對的時
next:
if (al > bl) || (bl > cl)
X = 1;
--------------------------------
cmp al, bl ; 看條件一是不是對的
ja L1 ; 對的,跳到 L1
cmp bl, cl ; 錯的,看條件二是不是對的
jbe next ; 錯的,跳過 L1 的標籤
L1:
mov X, 1 ; set X to 1
next:
while( eax < ebx)
eax = eax + 1;
--------------------------------
top:
cmp eax, ebx ; 看看條件是不是對的
jae next ; 如果錯的話,離開迴圈
inc eax
jmp top ; 重複迴圈
next:
shl reg, imm8
shl mem, imm8
shl reg, CL
shl mem, CL
EX: 5 * 2 ^ 2 = 20
mov dl, 5
shl dl, 2 ; dl = 20
EX: 20 / 2 ^ 2
mov dl, 5
shr dl, 2 ; dl = 5
mov dl, -80
sar dl, 1 ; DL = -40
sar dl, 2 ; DL = -10
mov al, 11110000b
rol al, 1 ; AL = 11100001b
mov dl, 3Fh
rol dl, 4 ; DL = F3h
mov al, 11110000b
ror al, 1 ; AL = 01111000b
mov dl, 3Fh
ror dl, 4 ; DL = F3h
clc ; CF = 0
mov bl, 88h ; CF,BL = 0 10001000b
rcl bl, 1 ; CF,BL = 1 00010000b
rcl bl, 1 ; CF,BL = 0 00100001b
stc ; CF = 1
mov ah, 10h ; CF,AH = 00010000 1
rcr ah, 1 ; CF,AH = 10001000 0
SHLD destination, source, count
.data
wval WORD 9BA6h
.code
mov ax, 0AC36h
shld wval, ax, 4
SHRD destination, source, count
mov ax, 234Bh
mov dx, 7654h
shrd ax, dx, 4
mov ax, 2 ; test value
mov dx, ax
shl dx, 4 ; AX * 16
push dx ; save for later
mov dx, ax
shl dx, 3 ; AX * 8
shl ax, 1 ; AX * 2
add ax, dx ; AX * 10
pop dx ; recall AX * 16
add ax, dx ; AX * 26
mov ax, dx ; make a copy of DX
shr ax, 5 ; shift right 5 bits
and al, 00001111b ; clear bits 4-7
mov month, al ; save in month variable
使用 stack 來存取
什麼是 EBP
為什麼要 EBP
stack 注意事項
如何實作一個 stack
push ebp ; 將 EBP 的內容先存到 stack 中
mov ebp, esp ; EBP = ESP
; 函式的實作內容置於此處
pop ebp ; 還原 EBP 的值
ret
.data
sum DWORD ?
.code
push 6 ; 第二個參數
push 5 ; 第一個參數
call AddTwo ; EAX = sum
mov sum, eax ; save the sum
AddTwo PROC
push ebp ; stack 起手式
mov ebp, esp
mov eax, [ebp + 12] ; 存取第二個參數 (6) 使用位址來存取參數
add eax, [ebp + 8] ; 存取第一個參數 (5) 使用位址來存取參數
pop ebp
ret 8 ; stack 起手式結束
AddTwo ENDP ; EAX contains the sum
push ebp
mov ebp, esp
sub esp, LOCAL_BYTES ; 在此處根據需求保留給 local 變數的空間
; subprogram 的實作內容置於此處
mov esp, ebp
pop ebp
ret
MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD
; (C 語言程式碼)
; void calc_sum(int n, int *sump) {
; int i, sum = 0;
;
; for(i = 1 ; i <= n ; i++)
; sum += i;
;
; *sump = sum;
; }
calc_sum:
push ebp
mov ebp, esp
sub esp, 4 ;保留儲存 local 變數的 memory address 的空間
mov dword [ebp - 4], 0 ; sum = 0;
mov ebx, 1 ; 假設 EBX = i
for_loop:
cmp ebx, [ebp + 8] ; i <= n
jnle end_for ; jump if not(less & equal)
add [ebp - 4], ebx ; sum += i
inc ebx
jmp for_loop
end_for:
mov ebx, [ebp + 12] ; ebx = sump
mov eax, [ebp - 4] ; eax = sum
mov [ebx], eax ; *sump = sum
mov esp, ebp
pop ebp
ret
處理 array 的指令
使用 ESI、EDI 做為索引之用
Direction flag (DF) 來判斷索引為遞增或遞減
Repeat Prefix 可以用來重複陣列操作指令,方向由 DF 控制
.data
array BYTE 1, 2, 3, 4, 5, 6, 7, 8, 9
.code
mov esi, OFFSET array
mov ecx, LENGTHOF array
cld
L1: lodsb ; 從 AL 中讀取值
or al, 30h ; convert to ASCII
call WriteChar ; display it
loop L1
.data
Count = 100
string1 BYTE Count DUP(?)
.code
mov al, 0FFh ; value to be stored
mov edi, OFFSET string1 ; 用 EDI 指向存入目標
mov ecx, Count ; character count
cld ; 把 DL 設成往上加
rep stosb ; fill with contents of AL
.data
source DWORD 0FFFFFFFFh
target DWORD ?
.code
mov esi, OFFSET source
mov edi, OFFSET target
movsd
.data
source DWORD 1234h
target DWORD 5678h
.code
mov esi, OFFSET source
mov edi, OFFSET target
cmpsd ; 比較 ESI EDI
ja L1 ; jump if source > target
jmp L2 ; jump if source <= target
.data
alpha BYTE "ABCDEFGH", 0
.code
mov edi, OFFSET alpha
mov al, 'F' ; 把 'F' 放入 AL 中代表我們要找它
mov ecx, LENGTHOF alpha
cld
repne scasb ; 重複直到不一樣
jnz quit
dec edi ; EDI points to 'F'
table BYTE 10h, 20h, 30h, 40h, 50h
BYTE 60h, 70h, 80h, 90h, 0A0h
BYTE 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
NumCols = 5
table BYTE 10h, 20h, 30h, 40h, 50h, 60h, 70h, 80h, 90h, 0A0h, 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
NumCols = 5
只不過要用下面的方法來取值
EX:在上面 5x3 的陣列中取 table[1][2]
RowNumber = 1
ColumnNumber = 2
mov ebx, NumCols * RowNumber ; NumCols = 5
mov esi, ColumnNumber
mov al, table[ebx + esi]
給予邏輯相關變數的模板或模式。
巢狀結構
SIZE 與 LENGTH 皆為其所有變數的總和
定義方式
name STRUCT
STRUCT 裡面放的各式變數
name ENDS
.data
name StructName < 變數1, 變數2.....>
.code
MOV 對應暫存器, name.變數1
; 定義 STRUCT
Employee STRUCT
IdNum BYTE "000000000"
LastName BYTE 30 DUP(0)
Years WORD 0
SalaryHistory DWORD 0,0,0,0
Employee ENDS
----------------------------------
; 取 STRUCT 中的值
mov dx, worker.Years
mov esi, OFFSET worker
mov ax, (Employee PTR [esi]).Years
mov ax, [esi].Years ; 無效,指令不明確
name UNION
UNION 裡面放的各式變數
name ENDS
name MACRO [ 參數1, 參數2...] //參數可選
MACRO 裡面放的指令集
name ENDM
IFB <參數> //若參數為空 = true
EXITM // 退出巨集
ENDIF
IF boolean-expression
statements
[ELSE //可選
statements]
ENDIF
IFIDNI <參數1>, <參數二> //此處參數可為任何內容、主要是比名稱
statements
ENDIF
ShowRegister MACRO regName //宣告MACRO,將regName改成參數
.data
tempStr BYTE " ®Name=",0 //本宣告內容會變成 " EDX="
.code
ShowRegister EDX //呼叫巨集,使此參數改名為EDX
Expansion (%) 用於將參數從常數改成文本提供MACRO輸入
Literal-Text (<>) 用於將多個文本參數組合成單一文本
Literal-Character (!) 用於將上述特殊運算子改成正常文本
WHILE constExpression //類似於boolean-expression
statements
ENDM //迴圈直到constExpression = false
REPEAT constExpression //參數為重複的次數
statements
ENDM //迴圈重複的次數
FOR 參數,< 引數1, 引數2, 引數3,...>
statements
ENDM
FOR 參數,<字串>
statements
ENDM
小信豬的原始部落
組語維基教科書
Xuite 筆記