Transcript Џ*ࡱ*က

第三章
 ARM的介紹
1
ARM(Advanced RISC Machines Limited)
用於低電力與低成本的
embedded system
 Mobile phone
 Communication modem
 Engine management system
 PDA

2
ARM7










Byte-addressable memory(可定址位元組的記憶體)
32 bits register and addressing
Most instructions execute in a single cycle
Every instruction can be conditionally executed
Support both little-endian and big-endian
(determined by control line of CPU)
Word alignment (multiple of 4)
Memory access(8/32 bits) can only via Load,
Store, which is main feature of RISC
All ALU operations are register-register (No
register-memory)
16 32-bit registers R0~R15,where R0~R12 are
GPR and R13 is the stack pointer, R14 is link
register(return address when call sub) R15 is the
program counter
CPSR-Current program Status Register (status
register-N,Z,C,V,NMI,Processor mode)
3
31
28 27
23
0
Condition 1 0 1 K
Of f set
(e) Branch and Branch with Link
I Immediate
S Set
A Accumulate
P Pre/Post-index
U Up/Down
B By te/Word
W Writeback
L Load/Store
K Link
Figure B.1. ARM instruction encoding formats.
ARM instruction format
4
表 3.1 ARM 的索引定址模式
名稱
組譯程式語法
定址函數
前置索引
[Rn,#offset]
EA = [Rn] + offset
包含寫回的前置索引
[Rn,#offset]!
EA = [Rn] + offset;
Rn ← [Rn] + offset
後置索引
[Rn],#offset
EA = [Rn];
Rn ← [Rn] + offset
包含立即偏移量:
在 Rm 中包含偏移量大小:
前置索引
[Rn,±Rm,shift]
EA = [Rn]±[Rm]移位
包含寫回的前置索引
[Rn,±Rm,shift]!
EA = [Rn]±[Rm]移位;
Rn ← [Rn]±[Rm]移位
後置索引
[Rn],±Rm,shift
EA = [Rn];
Rn ← [Rn]±[Rm]移位
相對(包含立即偏移
量的前置索引)
Location
EA = Location
= [PC] + offset
EA = 有效位址
offset = 位於指令中的有號數
shift = 有向整數,其中左移的方向為 LSL,或是右移的方向為 LSR,整數
為用來指定移位量的 5 位元無號數
±Rm = 位於暫存器 Rm 中,可以被加入基底暫存器 Rn ,或是減去 Rn 的偏移量大小
5
ARM 定址模式

前置與後置索引的定址方式是依[ ]的使用方式加以區別



前置索引模式(Pre-indexed mode):EA=base register Rn的內容+offset







EA=base register Rn的內容+offset,且Rn  EA類似自動定址
LDR R0,[R1-R2]! ; R0  [[R1]-[R2]], R1  [R1]-[R2]
STR R0,[R5,#-4]! ; [[R5] -4]  R0, R5  [R5] – 4(見p3-11圖3.4(b))
LDR R0,[R1.-R2,LSL #4]! ; R0  [[R1] -16 * [R2]], R1  [R1]-16*[R2]
STR R3,[R5,R6] ; [[R5]+[R6]]  R3
後置索引模式(Post-indexed mode):EA= base register Rn的內容(cf.間接
定址),且Rn  EA+offset(自動定址)




LDR Rd,[Rn,#offset] ; Rd  [[Rn] + offset] (cf.索引定址p2-29)
LDR Rd,[Rn,Rm]
;Rd  [[Rn] + [Rm]],(cf.索引基底)Rn,Rm的內容表示
Address,裡面的[]是ARM assembly的語法,外面的
[]是定址的語法
包含寫回的前置索引模式(Pre-indexed mode/writeback):


若只有基底暫存器(Rn)被[ ]括起來,則叫後置索引定址,記憶方式因為offset在’]’
之後
若基底暫存器(Rn)與offset被[ ]括起來,則叫前置索引定址,記憶方式因為offset
在’]’之前
注意:只要EA一產生就表示CPU接著會到此位址拿資料
LDR R3,[R2],#4 ; R3  [[R2]], R2  [R2] + 4 (見p3-20)
LDR R1,[R2],R10,LSL#2 ; R1  [[R2]], R2  [R2]+[R10] * 4
相對定址


LDR R1, ITEM ; EA=ITEM的位址=[PC]+offset,where PC為加8後的值,所以
offset = ITEM – 8
注意ARM沒有絕對(直接)定址,所以不要將LDR R1, ITEM 解讀為絕對(直接)定
址
6
ARM 定址模式(cont’d)
記憶體位址
字組
(4個位元組)
Item為Location
1000
LDR R1, ITEM
1004
-
1008
-
*
*
*
*
*
*
ITEM = 1060
更新的 [PC] = 1008
For pipeline
52 =偏移量
運算元
(a) 相對定址模式
STR R3, [R5, R6]
1000
*
*
*
基底暫存器
200
1000
*
*
*
R6
偏移暫存器
*
*
*
1200
R5
200 =偏移量
運算元
(b) 前置索引定址模式
圖 3.3 ARM 的記憶體定址模式範例
7
記憶體位址
1000
100 = 25 x 4
1100
100 = 25 x 4
1200
字組
(4個位元組)
6
1000
*
*
*
基底暫存器
25
-17
*
*
*
321
R2
R10
偏移暫存器
Load 指令:
LDR R1,[R2],R10,LSL #2
(a) 包含寫回的後置索引定址
2012
R5
堆疊指標
2008
27
2012
-
27
執行過 Push 指令之後
R0
Push 指令:
STR R0,[R5,#-4]!
[[R5]-4] R0
R5 [R5]-4
(b) 包含寫回的前置索引定址
圖 3.4 涉及寫回的 ARM 記憶體定址模式
8
Format (a) examples

OP{Cond}{S} Rd,Rn,Operand2





Only operand2 can be shifted
ADD R0,R1,R2
 無條件執行 R0  [R1]+[R2]
ADDEQ R0,R1,R2
 有條件執行
 當Flag Z=1時 R0  [R1]+[R2]
ADDEQS R0,R1,R2
 同上,但會影響Flag (設定CPSR中的Flag)
Why predicated instruction?
 To eliminate conditional branch in small ifthen-elseeasy to write compact code for
embedded system
If(a==b)
CMP R1,R2 /*assume a in R1, b in R2*/
{ a++; } else { a--; }
ADDEQ R1,#1 /*add 1 when equal*/
SUBNE R1,#1 /*sub 1 when not equal*/
CMP R1,R2 /*assume a in R1, b in R2*/
BNE Next
ADD R1,#1 /*add 1 when equal*/
Next SUB R1,#1 /*sub 1 when not equal*/
9
Format (a)
examples(cont)

ADD R0,R1,#17
 R0

ADD R0,R1,R2,LSL #4
 R0

 [R1]+17
 R1 + R2 * 16
ADD R0,R1,R2, LSR R3
 R0
 R1 + R2 / 2[R3]
10
Format (b) examples







MUL{cond}{S} Rd,Rm,Rs
MLA{cond}{S} Rd,Rm,Rs,Rn
{cond} two-character condition mnemonic.
Condition code summary on page B-4.
{S} set condition codes if S present
Rd, Rm, Rs and Rn are expressions evaluating to a register
number other than R15.
MUL R1,R2,R3
 R1:=R2*R3

MLAEQS R1,R2,R3,R4
 Conditionally
R1:=R2*R3+R4,setting
condition codes.
11
Format (c) examples






<LDR|STR>{cond}{B}{T} Rd,<Address>
 {B} if B is present then byte transfer, otherwise word
transfer
 {T} if T is present the W bit will be set in a post-indexed
instruction, forcing non-privileged mode for the transfer
cycle. T is not allowed when a pre-indexed addressing
mode is specified or implied.
LDR Rd,[Rn,#offset]
 Rd  [[Rn]+offset]
LDR R0,[R13,#4] (見p3-27)
 R0  [[R13]+4]
LDR Rd,[Rn,Rm]
 Rd  [[Rn]+[Rm]]
LDR R1,[R2,R3]
 R1  [[R2]+[R3]]
LDR R3,[R2],#4


R3  [[R2]], R2  [R2] + 4
STR R0,[R13,#-4]!

R0  [[R13] – 4], R13  [R13] - 4
12
Format (d) examples

<LDM|STM>{cond}<FD|ED|FA|EA|IA|IB|DA|DB>
Rn{!},<Rlist>{^}
 where:{cond} two character condition mnemonic.
 Rn is an expression evaluating to a valid register number
 <Rlist> is a list of registers and register ranges enclosed
in {} (e.g. {R0,R2-R7,R10}).
 {!} if present requests write-back (W=1), otherwise W=0
 {^} if present set S bit to load the CPSR along with the PC,
or force transfer of user bank when in privileged mode

pre-increment load LDMED
post-increment load LDMFD
pre-decrement load LDMEA
post-decrement load LDMFA
pre-increment store STMFA
post-increment store STMEA
pre-decrement store STMFD
post-decrement store STMED
STMFD R13!,{R3,R14} (見p3-26) FD表堆疊朝低位址成長











R13  [R13]-4, [R13]  R14, R13  [R13]-4, [R13]  R3
Store direction from Right to Left
LDMFD R13!,{R3,R15} (見p3-26) FD表堆疊朝低位址成長


R3  [R13], R13  R13+4, R15  [R13], R13  R13+4
Restore direction from Left to Right
13
Format (e) examples


Items in {} are optional. Items in <> must be present.
B{L}{cond} <expression>






{L} is used to request the Branch with Link form of the instruction.
If absent, R14 will not be affected by the instruction.
{cond} is a two-character mnemonic, If absent then AL(ALways)
will be used. {Cond} 見 pB-4 表B.1
<expression> is the destination. The assembler calculates the
offset.
BL LISTADD (見p3-26)
BGT LOOP (見p3-26)
14
(假定堆疊頂端位於以下第一層)
注意ARM沒有直接定址,所以在此是相對定址
呼叫程式
LDR
STR
LDR
STR
BL
LDR
STR
ADD
..
.
R0,POINTER
R0,[R13,#– 4]!
R0,N
R0,[R13,#– 4]!
LISTADD
R0,[R13,#4]
R0,SUM
R13,R13,#8
把 NUM1 推入堆疊
R13R13 – 4
把 n 推入堆疊
[R13]  R0
注意ARM沒有直接定址,所以在此是相對定址
R14指向下一個指令
把總和移入記憶體位置 SUM
此時R13指向n, Get NUM1
從堆疊上移除參數
R13  [R13]-4, [R13] 
R14; R13  [R13]-4,
[R13]  R3; R13 
[R13]-4, [R13]  R2;
R13  [R13]-4, [R13] 
R1; R13  [R13]-4, [R13]
 R0
副常式
LISTADD
LOOP
STMFD
LDR
LDR
MOV
LDR
ADD
SUBS
BGT
STR
LDMFD
R13!,{ R0 – R3,R14} 儲存暫存器
從堆疊上載入參數
R1,[R13,#20]
R2,[R13,#24]
R0,#0
Get n
R3,[R2],#4
R0,R0,R3
Get NUM1
Get NUM1(注意事後置索引定),R3[[R2]],R2[R2]+4
R1,R1,#1
LOOP
存入NUM1
把總和放上堆疊
R0,[R13,#24]
回復暫存器並且回傳
R13!,{ R0 – R3,R15}
(a) 呼叫程式與副常式
第三層 
[R0]
[R1]
[R2]
[R3]
回傳位址
第二層 
n
NUM1
第一層 
2nd STR R0,[R13,#-4]
1st STR R0,[R13,#-4]
Old TOS
(b) 不同時期的堆疊頂端
圖 3.11 把圖 3.7 的程式改寫成 ARM 副常式的程式;參數透過堆疊來傳遞
15
記憶體位址
指令
呼叫程式
..
.
LDR
STR
LDR
STR
BL
LDR
STR
ADD
2000
2004
2008
2012
2016
2020
2024
2028
2032
註解
把參數放上堆疊
R10,PARAM2
R10,[SP,# – 4]!
R10,PARAM1
R10,[SP,# – 4]!
SUB1
R10,[SP]
R10,RESULT
SP,SP,#8
下一個指令
2020存入R14(LR)
不會自動push RET ADDR
儲存 SUB1 的結果
從堆疊上移除參數
指回舊的TOS
..
.
Push LR Push FP Push R3
Push R2 Push R1 Push R0
第一個副常式
此時SP指在R0
2100 SUB1
2104
2108
2112
STMFD
ADD
LDR
LDR
..
.
LDR
STR
2160
BL
2164
LDR
..
R2[[SP]];SP[SP]+4 .
STR
LDMFD
SP!,{ R0 – R3,FP,LR} 儲存暫存器
載入窗格指標
FP,SP,#16
載入參數
R0,[FP,#8]
R1,[FP,#12]
param1
param2
R2,PARAM3
R2,[SP,# – 4]!
SUB2
R2,[SP],#4
R3,[FP,#8]
SP!,{ R0 – R3,FP,PC}
第二個副常式
3000 SUB2
此時SP指向param1
設定called fun的FP此時FP指
向[FP] from Main(見下圖)
把結果放上堆疊
相當於Push param3
LR(R14)  2164
取出 SUB2 的結果並且放
入 R2
此時SP指向param3 ,注意在此是後置索引定址
把結果放上堆疊
存入param1
回復暫存器並且回傳
此時SP指向[R0]from SUB1
STMFD
ADD
LDR
..
.
SP!,{ R0,R1,FP,LR}
FP,SP,#8
R0,[FP,#8]
STR
LDMFD
R1,[FP,#8]
SP!,{ R0,R1,FP,PC}
儲存暫存器
載入窗格指標
載入參數
建立sub2的FP
Param 3
存入param3
把結果放上堆疊
回復暫存器並且回傳
Pop R0 Pop R1 Pop FP Pop PC
圖 3.12 ARM 組合語言的巢狀副常式
16
低記憶體位址
[R0] from SUB1
[R1] from SUB1
FP
[FP] from SUB1
第二個副常式
的堆疊窗格
2164
param3
[R0] from Main
[R1] from Main
[R2] from Main
[R3] from Main
FP
[FP] from Main
2020
第一個副常式
的堆疊窗格
SUB1中STMFD
param1
param2
舊的 TOS
高記憶體位址
圖 3.13 圖 3.12 的 ARM 堆疊窗格
17
for
(j = n –1; j > 0; j = j – 1)
{ for ( k = j – 1; k > = 0; k = k – 1 )
{ if
(LIST[ k ] > LIST[ j] )
{ TEMP = LIST[ k];
LIST[ k] = LIST[ j ];
LIST[ j ] = TEMP;
}
}
}
(a) 排序的 C 語言程式
OUTER
INNER
ADR
LDR
ADD
ADD
LDRB
MOV
R4,LIST
R10,N
R2,R4,R10
R5,R4,#1
R0,[R2,#–1]!
R3,R2
LDRB
CMP
STRGTB
STRGTB
MOVGT
CMP
BNE
CMP
BNE
R1,[R3,#–1]!
R1,R0
R1,[R2]
R0,[R3]
R0,R1
R3,R4
INNER
R2,R5
OUTER
載入串列指標暫存器 R4,
把外部迴圈的基底暫存器
R2 初始化為 LIST + n
把 LIST + 1 載入 R5
把 LIST(j) 載入 R0
把內部迴圈的基底暫存器
R3 初始化為 LIST + n – 1
把 LIST(k) 載入 R1
比較 LIST(j) 跟 LIST(k)
若LIST(k)>LIST(j)則交換
LIST(k)與LIST(j),並且把
(新的)LIST(j) 移入 R0
若 k > 0 則重複內部迴圈
若 j > 1 則重複外部迴圈
(b) ARM 程式的實作
圖 3.15 ARM 版本的位元組排序程式
18
Jump to IA-32 Pentium
page 3-67

Skip to slide 26
19
長字組
字組
31
16 15
8 7
位元組
0
D0
D1
D2
D3
資料暫存器
D4
D5
D6
D7
A0
A1
A2
A3
位址暫存器
A4
A5
A6
使用者堆疊指標
系統管理者堆疊指標
A7
堆疊指標
程式計數器
PC
15 13 10 8
SR
T-追蹤模式選單
S-系統管理者模式選擇
I-中斷遮罩
4
0
狀態暫存器
CVZNX-
進位
溢位
零
負
擴充
圖 3.18 68000 的暫存器結構
20
15 12 11 9 8 7 6 5
1 1 01 dst 0
0
src
大小
OP 碼
(a) ADD 指令的 OP 碼程式
二進位
1 1 0 1 0 1 1 00 1 1 11 1 0 0
十六進位
D
6
7
C
(b) OP 碼字組的編碼
i
i +2
D67C
OP 碼字組
9
立即運算元
i +4
D3
25
D3
34
PC
i
PC
i+4
提取指令之前
執行指令之後
(c) 執行的結果
圖 3.21 68000 指令 ADD # 9,D3
21
A = 201150
63910
B = 201152
- 21510
OP 碼字組
201200
201202
20
201204
1150
201206
OP 碼字組
201208
20
20120A
1152
20120C
OP 碼字組
20120E
20
201210
2200
MOVE A,D0
ADD B,D0
MOVE D0,C
C = 202200
執行完畢之後 , [202200] = 424
10
圖 3.22 C ← [A] + [B] 的 68000 常式
22
(假定堆疊頂端位於以下第一層)
呼叫程式
MOVE.L
MOVE.L
BSR
MOVE.L
ADDI.L
..
.
#NUM1, – (A7)
N,– (A7)
LISTADD
4(A7),SUM
#8,A7
把參數推上堆疊
MOVEM.L
MOVE.L
SUBQ.L
MOVEA.L
CLR.L
ADD.W
DBRA
MOVE.L
MOVEM.L
RTS
D0 – D1/A2,– (A7)
16(A7),D1
#1,D1
20(A7),A2
D0
(A2)+,D0
D1,LOOP
D0,20(A7)
(A7)+,D0 – D1/A2
儲存暫存器 D0、D1、A2
把計數器初始化為 n
使用 DBRA 調整計數
讓指標指向串列
把總和初始化為 0
加入串列的項目
儲存結果
回復堆疊頂端
副常式
LISTADD
LOOP
把總和放上堆疊
回復暫存器
(a) 呼叫程式與副常式
第三層 
[D0]
[D1]
[A2]
第二層 
回傳位址
n
NUM1
第一層 
(b) 不同時期的堆疊頂端
圖 3.29 把圖 3.26 的程式改寫成 ARM 副常式的程式;參數透過堆疊來傳遞
23
記憶體位址
指令
呼叫程式
..
.
MOVE.L
MOVE.L
BSR
MOVE.L
ADDI.L
2000
2006
2012
2014
2020
2024
註解
PARAM2, – (A7)
PARAM1, – (A7)
SUB1
(A7),RESULT
#8,A7
把參數放上堆疊
LINK
MOVEM.L
MOVEA.L
MOVE.L
..
.
A6,#0
D0 – D2/A0, – (A7)
8(A6),A0
12(A6),D0
設定窗格指標
儲存暫存器
載入參數
MOVE.L
BSR
MOVE.L
..
.
MOVE.L
MOVEM.L
UNLK
RTS
PARAM3, – (A7)
SUB2
(A7)+,D1
把參數放上堆疊
D2,8(A6)
(A7)+,D0 – D2/A0
A6
把結果放上堆疊
回復暫存器
回復窗格指標
回傳
LINK
MOVEM.L
MOVE.L
..
.
A6,#0
D0 – D1,– (A7)
8(A6),D0
設定窗格指標
MOVE.L
MOVEM.L
UNLK
RTS
D1,8(A6)
(A7)+,D0 – D1
A6
把結果放上堆疊
回復暫存器
回復窗格指標
回傳
儲存結果
回復堆疊層級
下一個指令
..
.
第一個副常式
2100 SUB1
2104
2160
2164
取出 SUB2 的結果並且放
入 D1
第二個副常式
3000 SUB2
儲存暫存器
載入參數
圖 3.30 68000 組合語言的巢狀副常式
24
[D0] from SUB1
[D1] from SUB1
A6
[A6] from SUB1
第二個副常式
的堆疊窗格
2164
param3
[D0] from Main
[D1] from Main
[D2] from Main
[A0] from Main
A6
[A6] from Main
第一個副常式
的堆疊窗格
2014
param1
param2
舊的 TOS
圖 3.31 圖 3.30 的 68000 堆疊窗格
25
for
(j = n  1; j > 0; j = j  1)
{ for ( k = j  1; k > = 0; k = k  1 )
{ if (LIST[ k] > LIST[j ] )
{ TEMP = LIST[k];
LIST[ k] = LIST[ j ];
LIST[ j ] = TEMP;
}
}
}
(a) 排序的 C 語言程式
OUTER
INNER
NEXT
MOVEA.L
MOVE
SUBQ
MOVE
SUBQ
MOVE.B
CMP.B
BLE
MOVE.B
MOVE.B
MOVE.B
DBRA
SUBQ
BGT
#LIST,A1
N,D1
#1,D1
D1,D2
#1,D2
(A1,D1),D3
D3,(A1,D2)
NEXT
(A1,D2),(A1,D1)
D3,(A1,D2)
(A1,D1),D3
D2,INNER
#1,D1
OUTER
指向串列開始的指標
初始化位於 D1 的外部迴圈索引 j
初始化位於 D2 的內部迴圈索引 k
D3 存放目前的最大值
若LIST(k)[D3]
交換LIST(k)與LIST(j),並且把新
的最大值載入 D3
遞減計數器 k 與 j,若是尚未完成
工作則跳回
(b) 68000 程式的實作
圖 3.34 68000 的位元組排序程式
26
IA-32 Pentium








IA-32 : Intel Architecture 32 bits
80386 (1985)– 1st generation
80486 (1989)
Pentium (1993)
Pentium Pro (1995)
Pentium II (1997)
Pentium III (1999)
Pentium IV (2000)
27
IA-32









Byte-addressable memory(可定址位元組
的記憶體)
8/32 bits register and addressing
little-endian
byte alignment (不須對齊記憶體)
8 32-bit registers R0~R7, 8 64-bit floating
point registers which can extend to 80
bits
CS:code segment DS:data segment
SS:stack segment ES:extra segment
FS,GS:Data Segment
Eflags Register(CF,ZF,SF,OF,IOPL,IF,TF)
OPcode dst,src
28
IA-32定址模式
表 3.3 IA-32 的定址模式
名稱
組譯程式語法
定址函數
立即
Value
運算元 = Value
直接
Location
EA = Location
暫存器
Reg
EA = Reg,
也就是運算元 = [Reg]
暫存器間接
[Reg]
EA = [Reg]
包含位移量的基底
[Reg + Disp]
EA = [Reg] + Disp
包含位移量的索引
[Reg * S + Disp]
EA = [Reg] × S + Disp
包含索引的基底
[Reg1 + Reg2 * S]
EA = [Reg1] + [Reg2] × S
包含索引與位移量的索引
[Reg1 + Reg2 * S + Disp]
EA = [Reg1] + [Reg2] × S +
Disp
Value
Location
Reg,Reg1,Reg2
Disp
S
= 8 位元或 32 位元的有號數
= 32 位元位址
= 通用暫存器 EAX、EBX、ECX、EDX、ESP、EBP、ESI、
EDI 之一,其中 ESP 無法被用於索引暫存器
= 8 位元或 32 位元的有號數,其中在包含位移量的索引模式
中只能使用 32 位元。
=縮放因子 1、2、4、或 8
29
立即定址模式

Mov EAX,25
 EAX

 25 (decimal)
Mov EAX, 3FA00h
 EAX
 3FA00 (Hex)
30
直接(絕對)定址模式

Mov EAX,LOCATION
 (LOCATION)
 LOCATION表示記憶體位址,i.e.
EA=LOCATION
 如果LOCATION=1000,則表示
1000~1003這四個記憶體的內容
被COPY到EAX
 EAX
31
立即定址vs直接定址



Number EQU 25 (組譯指引命令)
Mov EAX, Number (立即定址)
Mov EAX,[Number] (直接定址)



但若Number本身已經是”位址標記”時,則不需要括號
 Mov EAX,Number (直接定址)
假設LOCATION為”位址標記=1000”,則Mov
EBX,OFFSET LOCATION (立即定址)把1000
copy 到 EBX,通常接下來的指令為 Mov EAX,[EBX]
(暫存器定址,EA=EBX的內容)
The OFFSET operator returns the offset of a
memory location

Mov EBX, offset LOCATION can be rewritten as
LEA EBX, LOCATION

Where LEA means Load Effective Address
32
包含位移的基底定址模式

Mov EAX,[EBP+60] ;
 運算元位址(EA)
= [EBP] + 60
33
包含索引與位移的基底定址模式

Mov EAX,[EBP+ESI*4+200];
 EA=
=[EBP] + [ESI] x 4+200
34
0
31
R0
R1
8個通用
暫存器
R7
0
63
FP0
FP1
8個浮點數
暫存器
FP7
0
16
程式區段
CS
堆疊區段
SS
DS
資料區段
6個區段
暫存器
ES
FS
GS
0
31
指令指標
31
13 12 11
9 8 7 6
0
狀態暫存器
輸入/輸出
特權等級
OF – 溢位
IF – 中斷啟用
CF – 進位
ZF – 零
SF – 正負號
TF – 陷阱
圖 3.37 IA-32 的暫存器結構
35
通用命名方式
31
R0
EAX
16 15
8 7
AH
0
AL
AX
R1
ECX
CH
CL
資料暫存器
CX
R2
EDX
DH
DL
DX
R3
EBX
BH
BL
BX
R4
ESP
SP
R5
EBP
BP
R6
ESI
SI
R7
EDI
DI
EIP
IP
指令暫存器
FLAGS
狀態暫存器
指標暫存器
索引暫存器
EFLAGS
Compatibility of the
register structure
圖 3.38 Figure
IA-323.38.
暫存器結構跟之前
IntelIA-32
處理器暫存器結構的相容性
36
主記憶體
位址
雙字組
1000
基底暫存器
1000
*
*
*
1060
*
*
*
60 = 位移量
運算元
運算元位址(EA) = [EBP] + 60
(a) 包含位移量的基底模式,表示為 [EBP + 60]
1000
基底暫存器
1000
40
*
*
*
*
*
*
索引暫存器
200 = 位移量
1200
縮放因子 = 4
(雙字組)
4 位元組資料
項目的列表
*
*
*
1360
**
**
**
*
*
*
160 =[索引暫存器]x 4
運算元
運算元位址(EA) =[EBP] + [ESI] x 4+200
(b) 包含索引與位移量的基底模式,表示為 [EBP + ESI*4 + 200]
圖 3.39 IA-32 架構的定址模式範例
37
IA-32指令與IA-32組合語言



Most instructions One or two operands
For two operands, either two of them are
registers or one of them is register. Two
memory locations are not allowed
組合語言

見P3-87圖3.42
38
STARTADD:
LEA
MOV
MOV
MOV
ADD
INC
DEC
JG
MOV
EBX,NUM1
ECX,N
EAX,0
EDI,0
EAX,[EBX + EDI * 4]
EDI
ECX
STARTADD
SUM,EAX
初始化基底(EBX)與計數
(ECX)暫存器
清除累積(EAX)與索引(EDI)
暫存器
把下一個數加入 EAX
遞增索引暫存器
遞減計數暫存器
若 [ECX] > 0 則跳回
把總和存在記憶體
.
(a) 直接方式
STARTADD:
LEA
SUB
MOV
MOV
ADD
LOOP
EBX,NUM1
EBX,4
ECX,N
EAX,0
EAX,[EBX + ECX * 4]
STARTADD
初始化基底暫存器 EBX 並且讓
它存放 NUM - 4
MOV
SUM,EAX
把總和存在記憶體
初始化累積/索引(ECX)
清除累積器(EAX)
把下一個數加入 EAX
遞減 ECX,若 [ECX] > 0 則跳回
(b) 較簡潔的程式
圖 3.40 用來累加數值的 IA-32 程式
39
呼叫程式
..
.
LEA
MOV
CALL
MOV
..
.
EBX,NUM1
ECX,N
LISTADD
SUM,EAX
把參數載入 EBX、ECX
LISTADD:
PUSH
MOV
MOV
EDI
EDI,0
EAX,0
儲存
ve EDI
使用 EDI 做為索引暫存器
使用 EAX 做為累積暫存器
STARTADD:
ADD
INC
DEC
JG
POP
RET
EAX, [EBX+ EDI * 4]
EDI
ECX
STARTADD
EDI
加上下一個數
遞增索引
遞減計數器
若 [ECX] > 0 則跳回
回復 EDI
跳回呼叫程式
跳到副常式
把總和存入記憶體
副常式
(a) 呼叫程式與副常式
ESP 
[EDI]
Return Address
Old TOS
(b) 在副常式中儲存 EDI 後的堆疊內容
圖 3.45 把圖 3.40a 寫成 IA-32 副常式的程式;此程式透過暫存器來傳遞參數
40
1
(假定堆疊頂端位於以下第一層)
呼叫程式
PUSH
PUSH
CALL
ADD
POP
..
.
OFFSET NUM1
N
LISTADD
ESP,4
SUM
把參數推上堆疊
PUSH
MOV
PUSH
MOV
PUSH
MOV
PUSH
MOV
ADD
INC
DEC
JG
MOV
POP
POP
POP
POP
RET
EDI
EDI,0
EAX
EAX,0
EBX
EBX,[ESP+20]
ECX
ECX,[ESP+20]
EAX,[EBX+EDI * 4]
EDI
ECX
STARTADD
[ESP+24],EAX
ECX
EBX
EAX
EDI
儲存
e EDI 並且用來做為索引暫
存器
儲存 EAX 並且用來做為累積暫
存器
儲存 EBX 並且載入位址 NUM1
跳到副常式
從堆疊中移除 n
取出總和並放入 SUM
副常式
LISTADD:
STARTADD:
儲存 ECX 並且載入計數 n
加上下一個數
遞增索引
遞減計數器
若尚未完成則跳回
以總和覆蓋堆疊的 NUM1
回復暫存器
回傳
(a) 呼叫程式與副常式
第三層

[ECX]
[EBX]
[EAX]
[EDI]
第二層

回傳位址
n
NUM1
第一層

(b) 不同時期的堆疊內容
圖 3.46 把圖 3.40a 的程式寫成 IA-32 子常式的程式;
參數透過堆疊來傳遞
41
記憶體位址
呼叫程式
2000
2006
2012
2017
第一個子常式
2100 SUB1:
2060
2165
指令
...
PUSH
PUSH
CALL
POP
ADD
...
PUSH
MOV
PUSH
PUSH
PUSH
PUSH
MOV
MOV
...
PUSH
CALL
POP
...
MOV
POP
POP
POP
POP
POP
RET
第二個副常式
3000 SUB2:
PUSH
MOV
PUSH
PUSH
MOV
...
MOV
POP
POP
POP
RET
註解
PARAM2
PARAM1
SUB1
RESULT
ESP,4
把參數放上堆疊
EBP
EBP,ESP
EAX
EBX
ECX
EDX
EAX,[EBP+8]
EBX,[EBP+12]
儲存窗格指標暫存器
載入窗格指標
儲存暫存器
儲存結果
回復堆疊層次
建立sub1的EBP 此時EBP指向[EBP] from Main
取得第一個參數
取得第二個參數
PARAM3
SUB2
ECX
把參數放上堆疊
[EBP+8],EDX
EDX
ECX
EBX
EAX
EBP
把答案放上堆疊
回復暫存器
EBP
EBP,ESP
EAX
EBX
EAX,[EBP+8]
儲存窗格指標暫存器
載入窗格指標
儲存暫存器
[EBP+8],EBX
EBX
EAX
EBP
把 SUB2 結果放上堆疊
回復暫存器
取出 SUB2 的結果並放入 ECX
回復窗格指標暫存器
回到主程式
取得參數
回復窗格指標暫存器
回到第一個子常式
圖 3.47 IA-32 組合語言的巢狀副常式
42
[EBX] from SUB1
[EAX] from SUB1
[EBP] from SUB1
EBP
第二個副常式
的堆疊窗格
2165
param3
[EDX] from Main
[ECX] from Main
[EBX] from Main
[EAX] from Main
EBP
[EBP] from Main
第一個副常式
的堆疊窗格
2017
param1
param2
舊的 TOS
圖 3.48 圖 3.47 的 IA-32 堆疊窗格
43
for
(j = n – 1; j > 0; j = j – 1)
{ for ( k = j – 1; k > = 0; k = k – 1 )
{ if (LIST[ k] > LIST[j ])
{ TEMP = LIST[k];
LIST[ k] = LIST[ j ];
LIST[ j ] = TEMP;
}
}
}
(a) 排序的 C 語言程式
OUTER:
INNER:
NEXT:
LEA
MOV
DEC
EAX,LIST
EDI,N
EDI
載入串列指標的基底暫存器 (EAX),
把外部迴圈的索引暫存器(EDI)初始
化為 j = n - 1
MOV
DEC
MOV
CMP
JLE
ECX,EDI
ECX
DL,[EAX + EDI]
[EAX + ECX],DL
NEXT
XCHG
[EAX + ECX],DL
把內部迴圈的索引暫存器 (ECX)初始
化為 k = j - 1
把 LIST(j) 載入暫存器 DL
比較 LIST(k) 跟 LIST(j)
若LIST(k)≤ LIST(j)則跳到下一個較
小的 k 索引項目;
否則,交換LIST(k)與LIST(j),並且
把新的 LIST(j) 留在 DL
MOV
DEC
JGE
DEC
JG
[EAX + EDI],DL
ECX
INNER
EDI
OUTER
遞減內部迴圈索引 k
重複或結束內部迴圈
遞減外部迴圈索引 j
重複或結束外部迴圈
(b) IA-32 程式的實作
圖 3.50 使用直接選擇排序之 IA-32 版本的位元組排序程式
44
表 3.1 ARM 的索引定址模式
名稱
組譯程式語法
定址函數
前置索引
[Rn,#offset]
EA = [Rn] + offset
包含寫回的前置索引
[Rn,#offset]!
EA = [Rn] + offset;
Rn ← [Rn] + offset
後置索引
[Rn],#offset
EA = [Rn];
Rn ← [Rn] + offset
包含立即偏移量:
在 Rm 中包含偏移量大小:
前置索引
[Rn,±Rm,shift]
EA = [Rn]±[Rm]移位
包含寫回的前置索引
[Rn,±Rm,shift]!
EA = [Rn]±[Rm]移位;
Rn ← [Rn]±[Rm]移位
後置索引
[Rn],±Rm,shift
EA = [Rn];
Rn ← [Rn]±[Rm]移位
相對(包含立即偏移
量的前置索引)
Location
EA = Location
= [PC] + offset
EA = 有效位址
offset = 位於指令中的有號數
shift = 有向整數,其中左移的方向為 LSL,或是右移的方向為 LSR,整數
為用來指定移位量的 5 位元無號數
±Rm = 位於暫存器 Rm 中,可以被加入基底暫存器 Rn ,或是減去 Rn 的偏移量大小
45
表 3.2 68000 定址模式
名稱
組譯程式語法
定址函數
立即
#Value
運算元 = Value
絕對短
Value
EA = 以正負號延伸的 WValue
絕對長
Value
EA = Value
暫存器
Rn
暫存器間接
(An)
EA = Rn,
也就是運算元 = [Rn]
EA = [An]
自動遞增
(An)+
自動遞減
-(An)
索引基本
WValue(An)
EA = [An];
遞增 An
遞減 An;
EA = [An]
EA = WValue + [An]
索引完整
BValue(An,Rk.S)
EA = BValue + [An] + [Rk]
相對基本
WValue(PC)
或 Label
BValue(An,Rk.S)
或 Label(Rk)
EA = WValue + [PC]
相對完整
EA
Value
BValue
WValue
An
Rn
S
EA = BValue + [PC] + [Rk]
= 有效位址
= 明確給定的數,或是以標記表示的數
= 8 位元的 Value
= 16 位元的 Value
= 位址暫存器
= 位址或資料暫存器
= 大小指示子:W 表示以正負號延伸的 16 位元字組,
L 表示 32 位元的長字組
46
表 3.3 IA-32 的定址模式
名稱
組譯程式語法
定址函數
立即
Value
運算元 = Value
直接
Location
EA = Location
暫存器
Reg
EA = Reg,
也就是運算元 = [Reg]
暫存器間接
[Reg]
EA = [Reg]
包含位移量的基底
[Reg + Disp]
EA = [Reg] + Disp
包含位移量的索引
[Reg * S + Disp]
EA = [Reg] × S + Disp
包含索引的基底
[Reg1 + Reg2 * S]
EA = [Reg1] + [Reg2] × S
包含索引與位移量的索引
[Reg1 + Reg2 * S + Disp]
EA = [Reg1] + [Reg2] × S +
Disp
Value
Location
Reg,Reg1,Reg2
Disp
S
= 8 位元或 32 位元的有號數
= 32 位元位址
= 通用暫存器 EAX、EBX、ECX、EDX、ESP、EBP、ESI、
EDI 之一,其中 ESP 無法被用於索引暫存器
= 8 位元或 32 位元的有號數,其中在包含位移量的索引模式
中只能使用 32 位元。
=縮放因子 1、2、4、或 8
47
結論

RISC




ARM(Advanced RISC Machines
Limited,Acorn Computers
Company)
Support both big-endian and littleendian
Opcode dst,src
CISC

68000 (Motorola Processor)

Big-endian



例如12345678h在記憶體擺放為
Opcode src,dst
IA-32 (Intel Architecture-32 bits)

Little-endian


例如12345678h在記憶體擺放為
Opcode dst,src
48