ARM組合語言

Report
第四章
ARM組合語言
DMATEK CO.,LTD
深圳市長高科技有限公司
本章節將介紹ARM指令集、Thumb指令集以及各類指令所對應的定址方式,透過對
本文章的閱讀,希望讀者能瞭解ARM微處理器所支援的指令集及相關具體的使用方法。
本章的主要內容有:
-ARM指令集、Thumb指令集概述。
-ARM指令集的分類與具體應用。
-Thumb指令集簡介及應用場合。
 4-1 ARM微處理器的指令集概述:
 4-1.1 ARM微處理器的指令的分類與格式
 ARM微處理器的指令集是載入/存回做為基礎,也就是指令集僅能處理暫存器中的相
關資料,且處理結果都需存回暫存器中,而對系統記憶體的存取則必需透通過透過
專門的載入/存回指令來達成。
 ARM微處理器的指令集可以分為跳躍指令、資料處理指令、程式狀態暫存器(PSR
)處理指令、載入/存回指令、輔助運算器指令和異常產生指令六大類,具體的指令
及功能如表4-1所示(表中指令為基本ARM指令,不包括衍生的ARM指令)。

表表44-1 -1 ARMARM指令及功能描述一覽表指令及功能描述一覽表
助記符
指令功能與描述
ADC
Add with carry,表示具進位旗標位元的算術加法指令
ADD
Add,表示算術加法指令
AND
Logical AND,表示邏輯AND運算指令
B
Branch,表示跳躍指令
BIC
Bit Clear,表示位元清除運算指令
BL
Branch with Link,這包含返回的跳躍指令,也就是呼叫指令
BLX
Branch and Exchange Instruction Set,這包含返回和狀態切換的跳躍指
令
BX
Branch with Link Exchange Instruction Set這包含狀態切換的跳躍指令
CDP
Coprocessor data processing,表示協同處理器資料操作指令
CMN
Compare negative,表示測試算術加法運算的結果指令
CMP
Compare,比較指令,表示測試算術減法運算的結果指令
EOR
Logic Exclusive OR,表示邏輯XOR運算指令
LDC
Load coprocessor from memony,表示記憶體到協同運算器的資料傳輸指令
LDM
Load multiple registers,表示連續載入多個暫存器資料指令
LDR
Load register from memory,表示記憶體到暫存器的資料傳輸指令
MCR
Move CPU register to coprocessor register,表示從ARM暫存器到協同處理器
暫存器的資料傳輸指令
MLA
Multiply accumulate,表示乘加運算指令
MOV
Move,表示資料傳送指令
MRC
Move from coprocessor register to CPU register,表示從協同處理運算器暫
存器到ARM暫存器的資料傳輸指令
MRS
Move PSR status/flags to register,表示傳送CPSR或SPSR的內容到通用
暫存器指令
MSR
Move register to PSR status/flags,表示傳送通用暫存器到CPSR或SPSR
的指令
MUL
Multiply,表示32位元乘法指令
MLA
Move negative register,表示32位元乘加指令
MVN
Move Not,表示資料取反相後傳送指令
ORR
OR,表示邏輯OR指令
RSB
Reverse Subtract,表示被減數與減數角色互換的算數減法運算指令
RSC
Reverse subtract with carry,這包含借位的逆向減法指令
SBC
Subtract with Carry,這包含進位的算術減法指令
STC
Store coprocessor register tomemory,表示協同處理器暫存器的寫入記憶
體指令
STM
Store multiple,表示連續存回多筆暫存器資料指令
STR
Store register to memory,表示協同處理器暫存器的寫入記憶體指令
SUB
Subtract,表示減法指令
SWI
Software Interrupt,表示軟體中斷指令
SWP
Swap register with memory,表示交換指令
TEQ
Test bit-wise equality,表示相等測試指令
TST
Test Bit,位元測試指令
 4-1.2 指令的條件區域
 當處理器工作在ARM狀態時,幾乎所有的指令均根據CPSR中條件碼欄位裡的各
位元狀態與指令的條件的條件區域做有條件的執行(Conditional Execution)。
當指令所執行的條件滿足時,指令將會被執行,否則指令就將被忽略。
 因此,我們需要先加以整理指令的幾個相關重點:
 -所有ARM指令都包括一個可選擇的條件碼,以{cond}來表示。
 -只要滿足CPSR的條件欄位所指定的條件時,符合這條件程式碼才可以被執行
。
 如下圖4-1列出一些部分指令程式碼所顯示的條件碼欄位示意圖。
圖4-1 列出部分的指令程式碼所顯示的條件碼欄位示意圖
 在這當中,顯示每一條ARM指令包含4位元的條件碼,且位於指令的最高4位元
[31:28]。條件碼共有16種,每個條件碼可用兩個字元表示,這兩個字元可以添加在
指令附加字尾後面與指令同時使用。例如,跳躍指令B可以加上附加字尾EQ變為
BEQ,表示了“相等則跳躍”,即當CPSR中的Z旗標位元被設定時,則發生跳躍
。
 而在這16種條件標誌碼中,只有15種可以使用,如表4-2所示,第16種(1111)為
系統保留,所以暫時不能使用。
 表4-2 指令的條件碼
條件碼{cond
}
組合語言附加
字尾
旗標位元
意
義
0000
EQ
Z設定
相等
0001
NE
Z清除
不相等
0010
CS
C設定
無符號數大於或等於
0011
CC
C清除
無符號數小於
0100
MI
N設定
負數
0101
PL
N清除
正數或零
0110
VS
V設定
溢位
0111
VC
V清除
無溢位
1000
HI
C設定且Z清除
無號數大於
1001
LS
C清除且Z設定
無號數小於或等於
1010
GE
N等於V
有號數大於或等於
1011
LT
N不等於V
有號數小於
1100
GT
Z清除且N等於V
有號數大於
1101
LE
Z設定或N不等於V
有號數小於或等於
1110
AL
忽略
無條件執行
1111
無意義,不存在
 4-2 ARM指令的定址方式:
 所謂定址方式就是處理器根據指令中所給予的位址資訊來尋找出實體位址的方式
。目前ARM指令系統支援如下幾種常見的定址方式。透過這些定址方式,可以讓
讀者瞭解所要介紹的各種指令的類型,並加以相互比照對應。
 4-2.1 立即定址
 立即定址,這是一種特殊的定址方式,運算元本身是在指令中直接加以設定,只
要取出指令也就取到了運算元。這個運算元被稱為立即數值,所以其對應的定址
方式也就叫做立即定址。以下為指令的範例:
ADD
ADD
R0,R0,#1
R0,R0,#0x3f
;R0←R0+1
;R0←R0+0x3f
 4-2.2 暫存器定址
 暫存器定址就是利用暫存器中的數值作為運算元,這種定址方式是各類微處理
器經常採用的一種方式,也是一種執行效率較高的定址方式,以下為指令的範
例:
ADD
R0,R1,R2
;R0←R1+R2
 該指令的執行效果是將暫存器R1和R2的內容相加,並將結果存放於暫存器R0
中。
 4-2.3 暫存器間接定址
 暫存器間接定址就是以暫存器中的值作為運算元的位址,而運算元本身是存放在記
憶體位址中。以下為指令的範例:
ADD
LDR
STR
R0,R1,[R2]
R0,[R1]
R0,[R1]
;R0←R1+[R2]
;R0←[R1]
;[R1]←R0
 在第一行條的指令中,以暫存器R2的值作為運算元的位址,在記憶體中取得一個運
算元後與R1相加,結果存入R0的暫存器中。第二行指令是載入的指令,將R1的值
作為位址的記憶體中的資料,然後傳送到R0暫存器中。而第三行的指令是存回指令
,是將R0的數值傳送到以R1的數值為位址的記憶體中。
 4-2.4 基底定址
 基底定址就是將暫存器(該暫存器一般稱之為基底暫存器)的內容與指令中給予的位
址偏移量然後加以相加,進而得到一個運算元的有效位址。基底定址方式常用於存取
某基底位址附近的記憶體區域,此包含了基底加上偏移量,以及基底加上索引值等來
定址的方式。
 這跟之後所要介紹的暫存器定址相當類似,只不過後者是偏移量為0而已。而基底加
上偏移量所定址之用的基底暫存器包含了並非是正確的位址。這基底暫存器需加上或
是減掉最大達4KB的偏移量來計算出所要存取的位址。以下為指令的範例:
LDR R0,[R1,#4]
;R0←[R1+4]
 這是前索引定址的方式。我們將透過一個基底暫存器來存取同一個記憶體區域的某個
記憶體單元的內容。在這指令中,我們可以將暫存器R1的內容加上4後形成一個有效
位址,然後從此位址的記憶體中取得數值後,再存入暫存器R0中。
 除此之外,除了上述所使用的方法外,我們還可以透過基底定址的方式,除了找
到基底定址所指向的記憶體區域外,還可去改變這基底的暫存器。以下為指令的
範例:
LDR R0,[R1,#4]!
;R0←[R1+4]、R1←R1+4
 即可改變基底暫存器來指向下一個要傳送的位址,這對多筆的資料傳送是很有用
途。這是一種包含自動索引的前索引定址方式。其中,“!”符號是表示指令在
完成資料傳送後,還需更新基底的暫存器。然而ARM微處理器對於這種自動索引
的方式,是不會消耗額外的週期時間。
 而還有另一種基底加偏移定址的方式,則稱之為後索引定址。即是一種基底不包
含偏移量來作為傳送的位址,當傳送後,自動加上索引的方式。以下為指令的範
例:
LDR R0,[R1] ,#4
;R0←[R1]、R1←R1+4
 在這裡沒有使用“!”符號,只運用了立即數值的偏移來作為基底暫存器的變
化量。
 除此之外,基底加上索引定址的方式是在指令中設定一個暫存器,然後再去指
定另外一個暫存器(作為索引之用),而這後面的數值可作為位移到基底位址上
而形成一個記憶體位址。以下為指令的範例:
LDR R0,[R1,R2]
;R0←[R1+R2]
 這個指令是將R1與R2的內容相加而得到的運算元位址,再將此位址所指定的
記憶體的內容傳送至R0。而上述的這4個指令都是屬於存回的指令。
 在以上兩條指令中,第二個來源運算元即為立即常數,要求以“#”為首碼,
而對於以十六進位表示的立即常數,還要求在“#”後加上“0x”或“&”。
 4-2.5 相對定址
 與基底定址方式相類似,相對定址是以程式計數器PC的目前數值作為基底位址
,指令中的位址標號作為偏移量,而將兩者相加之後得到有效位址。以下所列
的程式段完成了副程式的跳躍與返回,其中,跳躍指令,BL採用了相對定址方
式:
BL
;跳躍到副程式NEXT處執行
NEXT
……
NEXT
……
MOV
PC,LR
;從副程式返回
 4-2.6 多暫存器定址
 採用多暫存器定址方式,一條指令可以完成多個暫存器值的傳送。這種定址方
式可以用一條指令完成傳送最多16個通用暫存器的值。
 如下,舉出一個指令的範例:
LDMIA R0,{R1,R2,R3,R4}
;R1←[R0]
;R2←[R0+4]
;R3←[R0+8]
;R4←[R0+12]
 該指令的尾碼IA表示在每次執行完載入/存回操作後,R0按字元組長度增加,因
此,這個指令可將連續記憶體單元的數值傳送到R1~R4。稍後,我們會再進一
步地說明這個指令的用法。
 4-2.7 堆疊定址
 堆疊是一種資料結構,按先進後出(First In Last Out,FILO)的方式工作,使
用一個稱作堆疊指標的專用暫存器來指示當前的操作位置,堆疊指標總是指向
堆疊的頂端。
 當堆疊指標指向最後所填入堆疊的資料時,稱為滿堆疊(Full Stack),而當堆
疊指標指向下一個將要放入資料的空位置時,稱為空堆疊(Empty Stack)。
 同時,根據堆疊的生成方式,又可以分為遞增堆疊(Ascending Stack)和遞減
堆疊(Decending Stack)。當堆疊由低位址向高位址生長時,稱為遞增堆疊,
反之,當堆疊由高位址向低位址生長時,稱為遞減堆疊。這樣就有四種類型的
堆疊工作方式,所以ARM微處理器支援這四種類型的堆疊工作方式,即:
 -
滿遞增堆疊:堆疊指標指向最後填入的資料,且由低位址向高位址生長。
 -
滿遞減堆疊:堆疊指標指向最後填入的資料,且由高位址向低位址生長。
 -
空遞增堆疊:堆疊指標指向下一個將要放入資料的空位置,且由低位址向
高地址生長。
 -
空遞減堆疊:堆疊指標指向下一個將要放入資料的空位置,且由高位址向
低地址生長。
 4-3 組合程言程式設計:
 上述的組合語言介紹以了解組合語言基本語法,在下面的章節我們以兩個例子來
說明講解。
 1.HELLO程式
 2.簡易LED控制
 4-3.1 Hello程式
 以下範例程式是列印出HELLO WORLD的字串。
AREA ASM1,CODE,READONLY ;定義一個程式區段,區段名稱為
;
名稱為ASM1,屬性唯讀
ENTRY
;程式的入口點 虛擬指令
START
mov r0,#0x3
將0x3這個值傳送到r0
ldr r1,=str1
;將str1的位址存放到暫存器r0中
printstr
swi 0x123456
;在0x123456位址設置軟體中斷點
add r1,r1,#1
ldrb r2,[r1]
cmp r2,#0
bne printstr
;r1=r1+1
;將r2的值與0相比較
;比較結果r2不為0,繼續這個迴圈
stop
mov r0,#0x18
;將0x18的位址
ldr r1,=0x20026
;將0x2006的位址存放到暫存器r1中
swi 0x123456
;在0x123456設置中斷點
area strdata,data,readonly
;定義一個程式區段,區段名稱為
;
名稱為strdata,屬性唯讀
str1 dcb "Hello World", 0
;宣告連續記憶區塊將字串” Hello
World”;
傳給str1位址
end
 程式執行結果如下圖4-2所示,為Hello World程式的輸出結果:
圖4-2 Hello World程式的輸出結果
 4-3.2 簡易LED控制
 使用是以2440XP平台,以下範例程式是簡單控制LED燈的亮滅,使用BL指令呼
叫程式的組合語言基本結構。
rGPFCON EQU 0x56000050
rGPFDAT EQU 0x56000054
rGPFUP EQU 0x56000058
;定義S3C2440 GPIO的位址
AREA Init,CODE,READONLY;該虛擬指令定義了一個程式區段,區段名稱為
;Init,屬性唯讀
ENTRY
;程式的入口點 虛擬指令
;= = = =設置I/O埠GPF5為輸出屬性= = = = =
ldr r0,=rGPFCON
;將暫存器rPCONF的位置存放到暫存器r0中
ldr r1,=0x400
str r1,[r0]
;將r1中的資料存放到暫存器Rpconf中

;下面3個指令,主要是取消GPF埠的提升電阻
ldr r0;=rGPFUP
ldr r1,=0xffff
str r1,[ r0]
dr r2,=rGPFDAT
loop
ldr r1,=0xff
str r1,[r2]
bl delay
ldr r1,=0x0
str r1,[r2]
bl delay
b loop
;將資料埠F的資料暫存器的位址附給暫存器r2
;使GPE5輸出高電壓,LED1燈滅
;呼叫延遲副程式
;使GPE5輸出低電壓,LED1燈亮
;呼叫延遲
;不斷的迴圈,LED1將不停的閃爍
;delay 延遲副程式
delay
ldr r3,=0xaffff
delay1
sub r3,r3,#1
cmp r3,#0x0 ;
bne delay1
;執行下一個指令
mov pc,lr
END
;設置延遲的時間
;r3=r3-1
;將r3的值與0相比較
;比較結果不為0(r3不為0),繼續呼叫delay1,否則
;從副程式返回
;程式結束
 4-4 問題與討論:
 一、何謂有條件的執行?
 二、ARM 支援那些定址模式。
 三、試著改寫Hello的程式,使其能支援輸出兩個字串。【提示:增列宣告str2】
 四、改寫簡易LED控制程式使其奇偶數燈號交互閃爍。

similar documents