You are on page 1of 58

系統程式 – 理論與實務

第 3 章、組合語言

作者:陳鍾誠

旗標出版社
第 3 章、組合語言
3.1 簡介

3.2 基本範例

3.3 進階範例

3.4 函數與副程式

3.5 實務案例

3.5.1 IA32 的組合語言

3.5.2 ARM 的組合語言


3.1 簡介
 程式的主要功能

有系統的移動資料
 在半導體電路當中,只有一種東西在流動著,那就是電子

 程式有系統的搬動電子

組合語言指令

將資料搬來搬去

最多加上一些計算
 計算也是在有系統的搬動資料
指令的執行過程
 組合語言指令
移動指令

算術指令

邏輯運算指令

移位指令

載入儲存指令

跳躍指令

比較指令

條件式跳躍指令
移動指令

暫存器
ALU
( 加法器… )
R1=00000002

R2=00000002

Control Unit
IR=12120000
( 控製單元 ) (MOV R1, R2)

圖 3.1 移動指令 MOV R1, R2 的執行過程


算術指令

暫存器
ALU
( 加法器… )
R1=00000005

R2=00000002

R3=00000003

Control Unit
IR=13123000
( 控製單元 ) (ADD R1, R2, R3)

圖 3.2 加法指令 ADD R1, R2, R3 的執行過程


減法指令

暫存器
ALU
( 加法器… )
R1=00000001

R2=00000002

R3=00000003

Control Unit
IR=14132000
( 控製單元 ) (SUB R1, R3, R2)

圖 3.3 減法指令 SUB R1, R3, R2 的執行過程


邏輯運算指令

暫存器
ALU
( 加法器… ) R1 ( 二進位 ) = * 0100 0001
R1=00000041

R2=000000F4 R2 ( 二進位 ) = * 1111 0100

R3=000000B5 R3 ( 二進位 ) = * 1011 0101

Control Unit
IR=1A123000
( 控製單元 ) (XOR R1, R2, R3)
移位指令

ALU
( 加法器… )
暫存器
R1=00000410

R2=00000041

Control Unit
( 控製單元 ) IR=1E120004

圖 3.5 移位運算 SHL R1, R2, 3 的執行過程


載入指令
記憶體

LD R1, [0x28] 00 10 00 28
ALU 暫存器
( 加法器… ) R1=0F 0A C0 25 0028 0F 0A C0 25

Control Unit IR= 00 10 00 28


( 控製單元 )

圖 3.6 載入指令 LD R1, [0x28] 的執行過程


儲存指令
記憶體

ST R1, [0x32] 01 10 00 32
ALU 暫存器
( 加法器… ) R1=0F 0A C0 25 0032 0F 0A C0 25

Control Unit IR= 01 10 00 32


( 控製單元 )

圖 3.7 儲存指令 ST R1, [0x32] 的執行過程


跳躍指令
記憶體

ALU 暫存器 PC=0028 0E 00 00 30 =JMP


( 加法器… ) [0x30]
+ 00 00 00 58

新的 PC 值
PC=0058
IR = 0E 00 00 30 PC = 00 00 00 28

圖 3.8 跳躍指令 JMP [0x30] 的執行過程


比較指令
條件旗標 保留 中斷 保留 模式

狀態暫存器 N Z C V I T M
Status Word (SW)
31 -28 27 - 8 7 6 5-1 0

ALU 暫存器
( 加法器… ) R1=00 00 00 01
R2=00 00 00 02

IR = 10 12 00 00
Control Unit
( 控製單元 ) SW= 80 00 00 00

圖 3.9 比較指令 CMP R1, R2 的執行過程


條件式跳躍指令
記憶體

ALU 暫存器 PC=0082 0C 00 00 47 =JMP


( 加法器… ) [0x47]
+ 00 00 00 C9

新的 PC 值
PC=00C9
IR = 0C 00 00 47 PC = 00 00 00 82

SW =80 00 00 00

圖 3.10 條件式跳躍指令 JLE [0x47] 的執行過



3.2 基本範例
資料流動

數學運算

if 判斷

模擬迴圈

完整範例:從 1 加到 10
範例 3.1 C 語言當中的指定敘述 - 資料流動指

void main() {
int x = 3, y;
y = x;
}
範例 3.2 組合語言當中的資料移動指令 - MOV

組合語言 C 語言
MOV R1, R2 R1 = R2
範例 3.3 以組合語言模擬 C 語言當
中的指定敘述 A=B

組合語言 C 語言 ( 對照 C 語言 ( 簡化
LD R1, B 版 )= B
R1 版=
A ) B
ST R1, A A = R1
範例 3.4 以組合語言模擬 C 語言當
中的數學運算式 A = B + C - D

組合語言 C 語言 ( 對照 C 語言 ( 簡化
LD R2, B 版 )= B
R2 版=
A ) B+C–
LD R3, C R3 = C D
LD R4, D R4 = D
ADD R1, R2, R1 = R2 +
R3 R3
SUB R1, R1, R1 = R1 – R4
R4 A = R1
ST R1, A
範例 3.5 以組合語言模擬 C 語言當
中的 if 判斷式

組合語言 C 語言 ( 對照版 ) C 語言
LD R1, A R1 = A;
LD R2, B R2 = B; If
CMP R1, R2 If (R1 > R2) (A>B)
JGT goto LABEL1; C=
LABEL1 C = R2; A;
ST R2, C goto LABEL2 else
JMP LABEL1: C=
LABEL2 C = R1 B;
LABEL1: LABEL2:
ST R1, C
LABEL2:
範例 3.6 以組合語言實作無窮迴

組合語言 C 語言 ( 對照版 )
LOOP: while (1) {
ADD R1, R2, R1 R1 = R1 + R2;
JMP LOOP }
範例 3.7 組合語言的完整程式範例,
加總迴圈,從 1 加到 10 。
組合語言 C 語言 ( 對照版 ) C 語言 ( 簡化版 )
1 START void main() { void main() {
2 LD R1, sum R1 = sum; int sum=0;
3 LD R2, I R2 = i; int i;
4 LD R3, ten R3 = ten; for (i=0;
5 LD R4, one R4 = one; i<=10; i++)
6 FOR: CMP R2, R3 if (R2 > R3)//(i > sum += i;
7 JGT EXIT 10) }
8 ADD R1, R2, R1 goto EXIT;
9 ADD R2, R4, R2 R1 = R2 + R1;
10 JMP FOR R2 = R2 + R4;
11 EXIT: RET goto FOR;
12 i RESW 1 EXIT: return;
13 Sum WORD 0 int i;
14 Ten WORD 10 int sum = 0;
15 One WORD 1 int ten = 10;
16 END int one = 1;
}
3.3 進階範例
字串複製 ( 指標版 )

字串複製 ( 索引版 )

整數陣列的複製

複雜結構的存取
範例 3.9 字串複製 ( 索引版 )
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
START void main() { void main() {
LD R1, I R1=i; char a[10];
LD R2, aptr R2=*aptr; char b[] = "Hello !";
LD R3, bptr R3=*bptr; char *aptr=a, *bptr=b;
LD R7, one R7=one; while (1) {
while: while: *aptr = *bptr;
LDB R4, [R3] R4 = [R3]; // R4 = *bptr aptr++;
STB R4, [R2] [R2] = R4; //*aptr = R4 bptr++;
ADD R2, R2, R2= R2+1; if (*bptr == '\0')
R7; R3=R3+1; break;
ADD R3, R3, if (R4!= R0) // b[i] != '\0' }
R7; goto endw; return;
CMP R4, R0 goto while; }
JEQ endw endw: return;
JMP while char a[10];
endw: RET char b[] = "Hello !"
A RESB 10 int i=0;
B BYTE "Hello ! int one = 1;
",0 int *aptr = a;
i WORD 0 int *bptr = b;
one WORD 1 }
aptr WORD &a
字串複製 ( 索引版 )
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
START void main() { void main() {
LD R1, I R1=i; char a[10];
LD R2, aptr R2=*aptr; char b[] = "Hello !";
LD R3, bptr R3=*bptr; int i = 0;
LD R7, one R7=one; while (1) {
while: while: a[i] = b[i];
ADD R5, R3, R1 R5 = R3+R1;// R5=&b[i] if (b[i] == '\0')
LDB R4, [R5] R4 = [R5]; // R4 = b[i] break;
ADD R6, R2, R1 R6 = R2+R1;// R6=&a[i] i++;
STB R4, [R6] [R6] = R4; // a[i] = R4 }
CMP R4, R0 if (R4!= R0) // b[i] != '\0' return;
JEQ endw goto endw; }
ADD R1, R1, R7 R1 = R1 + R7; // i++;
JMP while goto while;
endw: RET endw: return;
A RESB 10 char a[10];
B BYTE "Hello !",0 char b[] = "Hello !"
aptr WORD &a int *aptr=a;
bptr WORD &b int *bptr=b;
i WORD 0 int i=0;
one WORD 1 int one = 1;
END }
範例 3.10 陣列複製 ( 索引版 )
組合語言 組合語言 C 語言
START void main() { int a[100], b[100];
LD R2, aptr R2 = *aptr; int i;
LD R3, bptr R3 = *bptr; for (i=0; i<=100; i++) {
LDI R8, 1 R8 = 1; a[i] = b[i];
LDI R9, 100 R9 = 100; }
ST R0, i i = 0;
LD R1, i R1 = i;
FOR: FOR:
SHL R5, R1, 2 R5 = R1 << 2; //
ADD R6, R5, R2 R5=i*4;
ADD R7, R5, R3 R6 = R5 + R2; //
LD R5, [R6] R6=&a[i]
ST R5, [R7] R7 = R5 + R3; //
ADD R1, R1, R8 R7=&b[i]
CMP R1, R9 R5 = [R6]; // R5 = a[i]
JLE FOR [R7] = R5; // b[i] = R5;
RET R1 = R1+1; // i++;
a RESW 100 If (R1 < R9) // i<=100
b RESW 100 goto FOR;
aptr WORD &a return
bptr WORD &b int a[100];
i RESW 1 int b[100];
END int *aptr=a;
範例 3.11 複雜結構的存取
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
START void main() { typedef struct {
… … char name[20];
LDI R5, 20 R5 = 20; int age;
LD R1, pptr R1 = *pptr; } person;
ADD R2, R1, R5 R2 = R1 + R5;// p + 20; void main() {
LDI R6, 18 R6 = 18; person p;
ST R6, [R2] [R2] = R6; // [p+20] = …
… 18; p.age = 18;
p RESB 24 … …
pptr WORD &p char p[24]; }
END int *pptr = &p;
}
3.4 函數與副程式
副程式呼叫

呼叫:跳躍指令 JSUB

返回:返回指令 RET

參數的傳遞方法

透過暫存器傳遞參數給副程式

透過堆疊進行多層次的副程式呼叫
範例 3.12 單層副程式的呼叫
- 以暫存器傳遞參數

void main() { START


int x = 1, y; LD R1, x
y = f(x); JSUB f
} ST R2, y
int f(int a) { RET
return a+a; x WORD 1
} y RESW 1
f:
ADD R2, R1, R1
RET
END
範例 3.13 多層副程式的呼叫的 C
語言程式
1 int main() {
2 int x = 1;
3 int y;
4 y = f1(x);
5 return 1;
6 }
7 int f1(int t) {
8 int b = f2(&t);
9 return b+b;
10 }
11 int f2(int *p) {
12 int r= *p+5;
13 return r;
14 }
範例 3.14 多層副程式的呼叫
(1)
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
MAIN START void main() int main() {
LD R1, x R1 = x; int x = 1;
PUSH push R1; //push int y;
R1 parameter x y = f1(x);
JSUB f1 f1(); return 1;
POP R1 POP R1; // R1 = }
ST R1, y f1()
RET y = R1; // y =
x WORD 1 f1()
y RESW 1 return;
int x = 1;
int y;
範例 3.14 多層副程式的呼叫
(2)
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
f1: f1() { int f1(int t) {
POP R1 POP R1; // R1=x; int b = f2(&t);
PUSH LR PUSH LR // 保留連結暫 return b+b;
ST R1, t 存器 }
LD R2, pt t = R1;
PUSH R2 R2 = pt;
JSUB f2 PUSH R2; // push &t
POP R1 f2();
ST R1, b POP R1; // R1= f2()
ADD R2, b = R1; // b = f2()
R1, R1 R2 = R1 + R1;
POP LR POP LR // // 回復連結暫
PUSH R2 存器
RET push R2; // push b+b
t RESW 1 return; // return b+b;
b RESW 1 int t;
pt WORD &t int b;
int *pt = &t;
範例 3.14 多層副程式的呼叫
(3)
組合語言 C 語言 ( 對照版 ) C 語言 ( 真實版 )
f2: f2() { int f2(int *p) {
POP R1 POP R1; // R1=p int r=
LD R2, [R1] R2=[R1]; // R2 = *p *p+5;
LDI R3, 5 R3 = 5; return r;
ADD R4, R2, R4 = R2 + R3; // }
R3 R4=*p+5
ST R4, r r = R4 // r = R4 =
PUSH R4 *p+5
RET PUSH R4; // push
r RESW 1 return value
END MAIN return;
int r;
}
3.5 實務案例
3.5.1 IA32 的組合語言

3.5.2 ARM 的組合語言


3.5.1 IA32 的組合語言
組譯器
微軟的 MASM 組譯器
GNU 的 as 組譯器
NASM 組譯器

語法
MASM 與 NASM 以 Intel 語法為基礎
 但各自進行了擴充。

GNU as 採用的是 AT&T 的語法


範例 3.15 兩種 IA32 的組合語言語
法 (Intel 與 AT&T 語法 )
MASM 組合語言 (Intel 語 GNU 組合語言 (AT&T 語法 )
法 ) eax,1
mov movl $1,%eax
mov ebx,0ffh movl $0xff,%ebx
int 80h int $0x80
mov ebx, eax movl %eax, %ebx
mov eax,[ecx] movl (%ecx),%eax
mov eax,[ebx+3] movl 3(%ebx),%eax
mov eax,[ebx+20h] movl 0x20(%ebx),%eax
add eax,[ebx+ecx*2h] addl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx] leal (%ebx,%ecx),%eax
sub eax,[ebx+ecx*4h-20h] subl 0x20(%ebx,%ecx,0x4),%eax
IBM PC 上的組合語言
IBM PC :使用的是 IA32 的處理器

具有 BIOS 晶片 ( 基本輸出入系統 )


BIOS 當中燒錄有中斷向量與中斷程式,因此、許多
的輸出入動作都可以透過呼叫 BIOS 完成,不需要程
式設計人員再撰寫輸出入程式。
但是對學習 IA32 組合語言的人而言,往往會將
BIOS 視為一組神奇的函數,反而無法理解輸出入的
原理。
PC 的 BIOS
中斷向量 (0x000-0x400)
指向中斷處理函數

中斷資料區 (0x400-0x470)

中斷處理函數
int $0x10 :可呼叫第 10 號中斷,在螢幕上輸出字

表格 3.1 個人電腦的 BIOS 資料

位移 說明 位移 說明
0000-0007 COM1-COM4 埠位 004A- 螢幕的欄數
0008-000F LPT1-LPT4
址 埠位址 004B
004C- 視訊緩衝區的長度
0010-0011 已安裝的硬體清單 004D
004E- 視訊緩衝區的起點
0012 初始化旗標 0050-
004F 游標位址 (8 個視訊頁 )
0013-0014 記憶體的大小 (KB) 005F
0060 游標結束列
0015-0016 I/O 通道的記憶體 0061 游標起始列
0017-0018 鍵盤的狀態旗標 0062 目前顯示的視訊頁編號
0019 替代鍵的儲存區 0063- 作用中的視訊基底位址
001A- 鍵盤緩衝區指標 ( 頭 0064
0065 CRT 模式暫存器
001C-
001B )
鍵盤緩衝區指標 (尾 0066 彩色圖形介面卡的暫存器
001D
001E- )
鍵盤緩衝區 0067- 卡帶磁帶資料區
003D
003E-0048 磁碟資料區 006B
006C- 計時器資料區
0049 目前的視訊模式 0070
表格 3.2 個人電腦 PC 的中斷表
(1)
編號 說明 編號 說明
0 除法錯誤 19 啟動程式載入器
1 單步追蹤 1A 本日時間 ( 單位為 18.2 次 / 秒 )
2 不可遮罩中斷 1B 鍵盤中斷
3 中斷點 1C 使用者計時器中斷
4 溢位 1D 視訊參數
5 列印螢幕 1E 磁碟參數
6 無效的運算碼 1F 繪圖表格
7 無法使用處理器擴充 20 終止程式
8 IRQ0 計時器中斷 (18.2 次 21 MS-DOS 服務
9 / 秒 ) 鍵盤中斷
IRQ1 22 MS-DOS 終止服務
A IRQ2 可程式化中斷控制器 23 MS-DOS 中斷位址
B IRQ3 序列通訊 (COM2) 24 MS-DOS 嚴重錯誤位址
表格 3.2 個人電腦 PC 的中斷表
(2)
C IRQ4 序列通訊 (COM1) 25 絕對磁碟的讀取 ( 已棄用 )
D IRQ5 固定磁碟 26 絕對磁碟的寫入 ( 已棄用 )
E IRQ6 磁碟中斷 27 終止並且常駐 ( 已棄用 )
F IRQ7 平行印表機 28-FF 保留
10 視訊服務 ( 螢幕 ) 33 滑鼠控制
11 設備檢查 34-3E 浮點樹模擬
12 記憶體大小 3F 覆蓋 (Overlay) 管理程式
13 軟碟服務 40-41 固定磁碟的服務
14 非同步序列埠服務 42-5F 保留:特殊用途
15 卡帶控制器 60- 可供應用程式使用
16 鍵盤服務 6C-7F
6B 保留:特殊用途
17 印表機服務 80-F0 保留:由 ROM-BASIC 使用
18 執行 ROM 中的 BASIC F1-FF 可供應用程式使用
表格 3.3 BIOS 第 10 號中斷 – 銀幕
控制的詳細功能 (1)
AH 功能 參數
0 設置顯示方式 AL= 顯示模式( 0 ~ 13H )
1 設置游標類型 CH= 游標開始行
CL= 游標結束行
2 設置游標位置 BH= 頁號; DH/DL = 行號 / 列號
3 讀游標位置 BH= 頁號
5 設置當前顯示頁 AL= 頁號
6 螢幕初始化或上卷 AL= 上卷行數; AL=0 全螢幕為空白
BH= 捲入行屬性
CH/CL= 左上角行號 / 列號
DH/DL= 右上角行號 / 列號
7 螢幕初始化或下卷 AL= 下卷行數; AL=0 全螢幕為空白
BH= 捲入行屬性
CH/CL= 左上角行號 / 列號
DH/DL= 右上角行號 / 列號
表格 3.3 BIOS 第 10 號中斷 – 銀幕
控制的詳細功能 (2)

8 讀游標位置的屬性和字元 BH= 顯示頁號; AH= 屬性;


AL = 字元
9 在游標位置顯示字元和屬性 BH= 顯示頁號; AL = 字元
BL= 屬性; CX= 字元重複次數
A 在游標位置僅顯示字元 BH= 顯示頁號; AL = 字元
CX= 字元重複次數
E 顯示字元(游標前移) AL = 字元; BL= 前景色
13 顯示字串 ES : BP= 串地址; CX= 串長
DH/DL= 起始行 / 列號; BH= 頁號
AL = 模式; BL= 屬性
範例 3.16 利用 PC BIOS 的 10 號中
斷,輸出 Hello! 的範例 (AT&T 語法
)


mov $msg, %ax
mov %ax,%bp #ES:BP = 串地址
mov $6,%cx #CX = 串長度
mov $0x1301,%ax #AH = 13, AL = 01h
mov $0x00C,%bx # 頁號為 0(BH = 0) 黑底紅
字 (BL = 0Ch)
mov $0,%dl
int $0x10 #10h 號中斷
ret
msg:.ascii "Hello!"

MS. DOS 系統中的組合語言
MS. DOS 的組合語言
較為簡單很多組合語言課程
學習者可以任意操控系統
不會受到保護模式的限制。

DOS 的系統呼叫 – INT21H


第 21 號中斷是保留給 MS. DOS 使用的
組合語言可以透過 21 號中斷呼叫 DOS 。
表格 3.4DOS 的中斷
AH 說明 編號 說明
0 讀取字元,回傳 AL= 2A 取得系統日期
字元
1 輸出字元,參數 DL= 2B 設定系統日期
字元
2 從序列埠讀取字元 …
3 寫出字元道序列埠 4B 載入或執行程式
4 將字元寫到印表機 4C 終止行程
… …
9 將字串寫入標準輸出 7305 絕對磁碟的讀取與寫入
DS:DX = 字串的位 h

範例 3.17 利用 DOS 系統呼叫進行輸出

組合語言 (Intel 語法 ) 說明
code segment 段開始位址
assume cs:code,ds:code 設定程式段及資料段起始位址
org 100h 程式進入點
start: jmp begin 要印出的訊息
msg db 'Hello!$‘ 設定參數 ds:dx = 字串起點
begin: mov dx,offset msg 設定 9 號服務
mov ah,9 進行 DOS 系統呼叫
int 21h 設定 4C 號服務
mov ax,4c00h 進行 DOS 系統呼叫
int 21h .code 段結束
code ends 程式結束點
end start
MS. Windows 系統下的組合語言
 撰寫視窗程式
可以使用組合語言
也可以用高階的 C/C++/C#, VB 等語言

 MASM32
下載 MASM32 組譯器並安裝
C:\MASM32 資料夾中附有許多進階的組合語言範例
 包含許多組合語言版的 MS. Windows 視窗程式
 MASM32 雖然全名為 Microsoft Assembler ,但卻不是現在
Microsft Visual Studio 中所使用的組譯器
 因為現在 Visual Studio 中所使用的是 ML 這個組譯連結器
 您可以在 http://www.masm32.com/ 這個網站中下載 MASM32
這個組譯器。
範例 3.18 以 MASM32 撰寫組合語
言以顯示對話視窗的範例 ( 頁 1)
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\dialogs.inc
include simple.inc
dlgproc PROTO :DWORD,:DWORD,:DWORD,:DWORD
.code
start:
mov hInstance, FUNC(GetModuleHandle,NULL)
call main
invoke ExitProcess,eax
main proc
Dialog "Simple Dialog","MS Sans Serif",10, \ ; caption,font,pointsize
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \ ; style
2, \ ; control count
50,50,150,80, \ ; x y co-ordinates
1024 ; memory buffer size
DlgButton "&OK",WS_TABSTOP,48,40,50,15,IDCANCEL
DlgStatic "Simple Dialog Written In MASM32",SS_CENTER,2,20,140,9,100
CallModalDialog hInstance,0,dlgproc,NULL
ret
main endp
範例 3.18 以 MASM32 撰寫組合語
言以顯示對話視窗的範例 ( 頁 2)
dlgproc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg == WM_INITDIALOG
invoke
SendMessage,hWin,WM_SETICON,1,FUNC(LoadIcon,NULL,IDI_ASTERISK)
.elseif uMsg == WM_COMMAND
.if wParam == IDCANCEL
jmp quit_dialog
.endif
.elseif uMsg == WM_CLOSE
quit_dialog:
invoke EndDialog,hWin,0
.endif
xor eax, eax
ret
dlgproc endp
end start
範例 3.18 的執行結果
3.5.2 ARM 的組合語言
ARM 的定址模式
圖 3.12 ARM 處理器的定址的範

範例 語意 說明
LDR Rd, [Rn, ± Rd[Rn± 前置索引
Rd, [Rn, ±
offset]
LDR offset]
Rd[Rn± 寫回運算 (!)
offset]! offset]
LDR [Rn], ±offset RnRn±offset
Rd[Rn] 後置索引
RnRn±offset
LDR Rd, [Rn, ±Rm] Rd[Rn±Rm] 前置索引 ( 使用 Rm)
LDR Rd, [Rn, ±Rm]! Rd[Rn±Rm] 前置索引 + 寫回運算
RnRn±Rm
LDR Rd, [Rn], ±Rm Rd[Rn] 後置索引 ( 使用 Rm)
RnRn±Rm
LDR Rd, [Rn, ±Rm Rd[Rn± 移位後載入
Rd, [Rn, ±Rm
LSL Cx]
LDR Rm<<Cx]
Rd[Rn± 移位後載入 ( 移位量由暫
LSL Rx] Rm<<Rx] 存器 Rx 指定 )
LDR Rd, [±offset] Rd[PC± 相對於程式計數器的定址
offset]
常數的表示:旋轉立即數
旋轉立即數
<rotated_immed>=<immed8> ROR (2*<immed4>)

哪些數字『屬於』旋轉立即數?
0xFF 、 0x104 、 0xBC00000

哪些數字『不屬於』旋轉立即數?
0x0101 和 0x102
常數的設定
對於旋轉立即數 (ex: 972)
可以直接設定
Ex : mov R3, #972

對於非旋轉立即數 (ex: 973)


先設定一個最接近的旋轉立即數
 mov R3, #972
然後再使用加法
 add R3, R3, #1
範例 3.19 ARM 的組合語言範例
組合語言 C 語言 ( 對照 )
AREA CODE void main()
ENTRY {
LDR R1, n R1=n;
LDR R2, ptr R2=ptr;
MOV R0, #0 R0=0;
loop LDR R3, [R2], #4 R3 = [R2]; R2 = R2+4;
ADD R0, R0, R3 R0 = R0 + R3
SUBS R1, R1, #1 R1 = R1 – 1; if (R1 > 0)
BGT loop goto Loop;
STR R0, sum sum = R0
AREA DATA int sum=0;
sum DCD 0 int n=6;
n DCD 6 int *ptr = array;
ptr DCD Array int array[] = {6, -3, 2, 9, -33, 100};
array DCD 6, -3, 2, 9, -33, }
100
END
本章摘要 (1)
 3.1 簡介

組合語言指令通常用來有系統的移動資料

MOV, ADD, XOR, JMP, CMP, JGT 等指令的功能

 3.2 基本範例

資料移動、數學算式、 if, while,

範例:從 1 加到 10

 3.3 進階範例

字串複製、陣列複製、複雜結構存取
本章摘要 (2)
 3.4 函數與副程式
透過 JSUB 呼叫與 RET 返回

透過暫存器傳遞參數、或透過堆疊傳遞參數

 3.5 實務案例
3.5.1 IA32 的組合語言
 MASM (Intel 語法 ) 與 GNU as (AT&T 語法 )

 BIOS, DOS, Windows 組合語言的寫法

3.5.2 ARM 的組合語言


 定址法、立即數、範例

You might also like