arm彙編指令是學習彙編必須要掌握的,很多人覺得arm彙編指令記得很頭疼,而且還很亂,在這裡一個美女學霸總結出了最全面的arm彙編指令,看看學霸是怎麼總結的,還在等什麼,快收藏起來。
剛開始就是ARM彙編語言基本結構,這是必須先要了解的:
AREA Init, CODE, READONLY
ENTRY
Start
LDR R0, =0x3FF5000
LDR R1, 0xFF
STR R1, [R0]
LDR R0, =0x3FF5008
LDR R1, 0x01
STR R1, [R0]
... ... ... ... ... ...
END
指令格式
ARM指令的基本格式:
[][S] , {,operand2}
opcode:指令助記碼,如:MOV
con:執行條件,如NE,EQ
S:是否影響CPSR寄存器的值,設定時影響CPSR
Rd:目标寄存器
Rn:第一個操作數的寄存器
operand2:第二個操作數
ARM處理器尋址方式
尋址方式是根據指令中給出的位址碼字段來實作尋找真實操作數位址的方式。ARM處理器有九種尋址方式,寄存器尋址、立即數尋址、寄存器偏移尋址為資料處理指令操作數尋址方式,寄存器間接尋址、基址尋址、多寄存器尋址、堆棧尋址、相對尋址為存儲器通路指令操作數尋址方式。
a、寄存器尋址
操作數的值存在寄存器中,指令中的位址碼字段指出的是寄存器編号,指令執行時直接取出寄存器值操作。例如:
MOV R0,R1
SUB R0,R1,R2
b、立即尋址
立即尋址指令中的操作碼字段部分後面的位址碼部分就是操作數本身,即資料包含在指令當中。例如:
MOV R0,#0xff
立即數要以“#”為字首,十六進制以“0x”表示
c、寄存器偏移尋址
寄存器偏移尋址是ARM指令集特有的尋址方式,當第2操作數是寄存器,在執行操作之前,可以做一次移位操作。
MOV R0,R2,LSL #3
ANDS R1,R1,R2,LSL R3
d、寄存器間接尋址
寄存器間接尋址指令中的位址碼給出的是一個通用寄存器的編号,所需的操作數儲存在寄存器指定位址的存儲單元中,即寄存器為操作數的位址指針。
LDR R1,[R2] ;将R2指向的單元中的資料儲存再R1中
SWP R1,R1,[R2] ;将寄存器R1的值和R2指向的單元中進行内容交換
e、基址尋址
基址尋址就是将基址寄存器的内容與指令中給出的偏移量進行相加,形成操作數的有效位址。基址尋址用于通路基址附近的存儲單元,常用于查表、數組操作以及功能不見寄存器通路等。
LDR R2,[R3,#0x0c] ;讀取R3 0x0c位址指向的存儲單元的内容,放入R2
STR R1,[R0,#-4]! ;先R0=R0-4,然後把R1的值寄存到R0所指向的單元中
LDR R1,[R0,R3,LSL #1] ;将R0 R3*2位址上的單元的内容讀出,并存入R1中
f、多寄存器尋址
多寄存器尋址即一次可傳送幾個寄存器的值,允許一條指令傳送16個寄存器的任何子集或所有的存儲器。
LDMIA R1!,{R2-R7,R12};将R1指向的單元中的資料讀出到R2---R7、R12中(R1自自動 )
STMIA R0!,{R2-R7,R12};将R2---R7、R12中的資料一次讀入到R0指向的單元中(R0自動 )
g、堆棧尋址
堆棧是一種按特定順序進行存取的存儲區,操作順序分為“先進後出”和“後進先出”,堆棧尋址是隐含的,它使用一個專門的寄存器(堆棧指針)指向的存儲區域(堆棧),指針所指向的存儲單元即是堆棧的棧頂。
STMFD SP!,{R1-R7,LR} ;将R1---R7、LR入棧。滿遞減堆棧
LDMFD SP!,{R1-R7,LR} ;資料出棧,放入R1---R7、LR寄存器,滿遞減堆棧
h、塊拷貝尋址
多寄存器傳送指令用于将一塊資料從存儲器的某一位置拷貝到另一位置。
STMIA R0!,{R1-R7} ;将R1~R7的資料儲存到存儲器中。
;存儲指針在儲存第一個值之後增加,
;增長方向為向上增長。
STMIB R0!,{R1-R7} ;将R1~R7的資料儲存到存儲器中。
;存儲指針在儲存第一個值之前增加,
;增長方向為向上增長。
i、相對尋址
相對尋址是基址尋址的一種變通。由程式計數器PC提供基址位址,指令中的位址碼字段為偏移量。兩者相加後得到的位址即為操作數的有效位址。
點選擷取1V1嵌入式學習規劃,現在還送100G精選學習資料。文中文擷取吖
ARM存儲器通路指令
ARM處理器是加載/存儲體系結構的典型RISC處理器,對存儲器的通路隻能用加載和存儲指令實作。ARM的加載/存儲指令可以實作字、半字、位元組操作。
1、LDR和STR
加載/存儲字和無符号位元組指令。使用單一資料傳送指令來裝載和存儲單一位元組或字的資料。LDR指令用于從記憶體中讀取資料放入記憶體中,STR指令用于将寄存器中的資料儲存到記憶體中。
指令格式如下:
LDR[cond][T] Rd,<位址>;
加載指定位址上的資料(字),放入Rd中
STR[cond][T] Rd,<位址>;
存儲資料(字)到指定位址的存儲單元,要存儲的資料在Rd中
LDR[cond]B[T] Rd,<位址>;加載位元組資料,放入Rd中,Rd低位元組有效
STR[cond]B[T] Rd,<位址>;存儲位元組資料,要存儲的資料在Rd中
指令T表示在處理器特權模式下,存儲系統也将通路看做是在使用者模式下。
STR R0,[R1],#8;将R0中内容寫入R1為位址的記憶體中,并将新位址R1+8寫入R1。
STR R0,[R1,#8];将R0中的字資料寫入以R1+8為位址的存儲器中。
LDR/STR指令尋址非常靈活,由兩部分組成,一部分為基址寄存器,可以是任一通用寄存器,另一部分為位址偏移量,由以下三種格式:
a、立即數
立即數可以是一個無符号數值,這個數值可以加到基址寄存器或由基址寄存器減去,例如:
LDR R0,[R1,#0x12];将R1+0x12位址處的資料讀出儲存到R0寄存器中
LDR R0,[R1,#-0x12];将R1-0x12位址處的資料讀出儲存到R0寄存器中
LDR R0,[R1];将R1位址處的資料讀出儲存到R0寄存器中
b、寄存器
寄存器中的數值可以加到基址寄存器,也可以從基址寄存器中減去這個值,例如:
LDR R0,[R1,R2];将R1+R2位址處的資料讀出,儲存到R0寄存器中
LDR R0,[R1,-R2];将R1-R2位址處的資料讀出,儲存到R0寄存器中
c、寄存器及移位常數
基址寄存器加上或減去寄存器移位後的值
LDR R0,[R1,R2,LSL#2];将R1+R2*4位址處的資料讀出,儲存到寄存器R0
LDR R0,[R1,-R2,LSL#2];将R1-R2*4位址處的資料讀出,儲存到寄存器R0
LDRB指令用于從存儲器中将一個8位的位元組資料傳送到目的寄存器中,同時将寄存器的高24位清零。 該指令通常用于從存儲器中讀取8位的位元組資料到通用寄存器,然後對資料進行處理。當程式計數器PC作為目的寄存器時,指令從存儲器中讀取的字資料被當作目 的位址,進而可以實作程式流程的跳轉。
LDRH指令的格式為:
LDR{條件}H 目的寄存器,<存儲器位址>
LDRH指令用于從存儲器中将一個16位的半字資料傳送到目的寄存器中,同時将寄存器的高16位清零。 該指令通常用于從存儲器中讀取16位的半字資料到通用寄存器,然後對資料進行處理。當程式計數器PC作為目的寄存器時,指令從存儲器中讀取的字資料被當作 目的位址,進而可以實作程式流程的跳轉。
STRB指令的格式為:
STR{條件}B 源寄存器,<存儲器位址>
STRB指令用于從源寄存器中将一個8位的位元組資料傳送到存儲器中。該位元組資料為源寄存器中的低8位。
STRH指令的格式為:
STR{條件}H 源寄存器,<存儲器位址>
STRH指令用于從源寄存器中将一個16位的半字資料傳送到存儲器中。該半字資料為源寄存器中的低16位。
應用示例:
GPIO設定:
GPIO_BASE EQU 0xE0028000;定義GPIO寄存器的基位址
LDR R0,=GPIO_BASE
LDR R1,=0x00FFFFFF00
STR R1,[R0,#0x0C];将0xE002800C位址的值設為0x00FFFFFF00
MOV R1,0x00F00000
STR R1,[R0,#0x04];将0xE0028004位址的值設為0x00F00000
2、LDM和STM
批量加載/存儲指令可以實作在一組寄存器和一塊連續的記憶體單元之間傳輸資料,指令格式如下:
LDM[cond]<模式> Rn[!],reglist{^}
STM[cond]<模式> Rn[!],reglist{^}
模式有八種:
IA 每次傳送後位址加4;
IB 每次傳送前位址加4;
DA 每次傳送後位址減4;
DB 每次傳送前位址減4;
FD 滿遞減堆棧;
ED 空遞減堆棧;
FA 滿遞增堆棧;
EA 空遞增堆棧;
3、SWP
寄存器和存儲器交換指令,指令格式:
SWP[cond][B] Rd,Rm,[Rn]
将Rn的值為位址的記憶體單元的值讀取到Rd寄存器中,同時将寄存器Rm的值寫入該記憶體單元。
如果有B,則交換位元組,否則交換32位字;
ARM資料處理指令
資料處理指令分為資料傳送指令、算數邏輯運算指令、比較指令
資料處理指令隻能對寄存器的内容進行操作
1、資料傳送指令
A、MOV
指令格式:
MOV[con][S] Rd,operand2
MOV R0,#0x04
MOV R0,R1
MOVS R3,R2,LSL#2
MOV PC,LR;PC=LR,子程式傳回
B、MVN
指令格式:
MOV[con][S] Rd,operand2
MVN R0,R1
MVN R2,#0xFF;R2位0xFFFFFF00
2、算數邏輯運算指令
A、ADD加法運算指令
指令格式:
ADD[con][S] Rd,Rn,operand2
将operand2資料與Rn的值相加,結果儲存到Rd寄存器
ADD指令用于把兩個操作數相加,并将結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。
ADD R0,R1,R2
ADD R0,R1,#0x12
ADDS R0,R1,R2,LSL#2
B、SUB減法運算指令
SUB[con][S] Rd,Rn,operand2
用寄存器Rn的值減去operand2,結果儲存在Rd中,指令格式:
SUBS R0,R0,#1
SUBS R0,R1,R2
RBS逆向減法指令
用寄存器operand2減去Rn,結果儲存到Rd中,指令格式:
RBS[con][S] Rd,Rn,operand2
RSB R0,R1,#0x100;R0=0x100-R1
C、ADC帶進位加法指令
将operand2的資料與Rn的值相加,再加上CPSR中的C條件标志位,結果儲存到Rd寄存器,指令格式:
ADC[con][S] Rd,Rn,operand2
D、AND邏輯與操作指令
将寄存器operand2的值與寄存器Rn的值按位作邏輯與操作,結果儲存到Rd中,指令格式:
AND[con][S] Rd,Rn,operand2
ANDS R0,R1,#0x01
AND R0,R1,R2
E、ORR邏輯或操作指令
将寄存器operand2的值與寄存器Rn的值按位作邏輯或操作,結果儲存到Rd中,指令格式:
ORR[con][S] Rd,Rn,operand2
ORR R0,R0,#0x0F;将R0的低4位置1
F、EOR邏輯異或操作指令
将寄存器operand2的值與寄存器Rn的值按位作邏輯異或操作,結果儲存到Rd中,指令格式:
ERR[con][S] Rd,Rn,operand2
H、BIC位清零操作指令
将寄存器Rn的值與寄存器operand2的值反碼按位作邏輯與操作,結果儲存到Rd中,指令格式:
BIC[con][S] Rd,Rn,operand2
BIC R1,R1,#0x0F
3、比較指令
A、CMP比較指令
用寄存器Rn的值減去寄存器operand2的值,根據操作的結果更新CPSR中相應的條件标志位,以便後面的指令根據相應的條件标志位判斷是否執行,指令格式:
CMP[con] Rn,operand2
B、CMN負數比較指令
CMN[con] Rn,operand2
CMN指令用于把一個寄存器的内容和另一個寄存器的内容或立即數取反後進行比較,同時更新CPSR中條件标志位的值。該指令實際完成操作數1和操作數2相 加,并根據結果更改條件标志位。
指令示例:
CMN R1,R0 ;将寄存器R1的值與寄存器R0的值相加,并根據 結果設定CPSR的标志位
4、乘法指令
A、MUL 32位乘法指令
将Rm與Rs中的值相乘,結果的低32位儲存到Rd中,指令格式:
MUL[con][S] Rd,Rm,Rs
MUL R0,R1,R2
B、MLA 32位乘法疊加指令
将Rm與Rs中的值相乘,結果再與Rn相加,低32位儲存到Rd中,指令格式:
MLA[con][S] Rd,Rm,Rs,Rn
MLA R0,R1,R2,R3
C、UMULL 64位無符号乘法指令
将Rm與Rs的值作無符号數相乘,結果的低32位儲存到RdLo中,高32位儲存到RdHi中,指令格式:
UMULL[con][S] RdLo,RdHi,Rm,Rs
UMULL R0,R1,R4,R5;(R1,R0)=R4*R5
D、SMULL 64位有符号乘法指令
将Rm與Rs的值作有符号數相乘,結果的低32位儲存到RdLo中,高32位儲存到RdHi中,指令格式:
SMULL[con][S] RdLo,RdHi,Rm,Rs
SMULL R0,R1,R4,R5;(R1,R0)=R4*R5
ARM跳轉指令
1、B跳轉指令
跳轉到指定的位址執行程式,指令格式:
B[con] label
B hello
B #0x30008000
2、BL帶連結的跳轉指令
将下一條指令的位址拷貝到R14(LR)連結寄存器中,然後跳轉到指定位址運作程式,指令格式:
BL[con] label
BL hello
BL用于子函數的調用
3、BX帶狀态切換的跳轉指令
BX指令的格式為:
BX{條件}目标位址
BX指令跳轉到指令中所指定的目标位址,目标位址處的指令既可以是ARM指令,也可以是Thumb指令。
資料交換指令
1、SWP指令
SWP指令的格式為:
SWP{條件} 目的寄存器,源寄存器1,[源寄存器2]
SWP指令用于将源寄存器2所指向的存儲器中的字資料傳送到目的寄存器中,同時将源寄存器1中的字資料傳送到源寄存器2所指向的存儲器中。顯然,當源寄存 器1和目的寄存器為同一個寄存器時,指令交換該寄存器和存儲器的内容。
指令示例:
SWP R0,R1,[R2] ;将R2所指向的存儲器中的字資料傳送到R0,同時将R1 中的字資料傳送到R2所指向的存儲單元。
SWP R0,R0,[R1] ;該指令完成将R1所指向的存儲器中的字數 據與R0中的資料交換。
2、SWPB指令
SWPB指令的格式為:
SWP{條件}B 目的寄存器,源寄存器1,[源寄存器2]
SWPB指令用于将源寄存器2所指向的存儲器中的位元組資料傳送到目的寄存器中,目的寄存器的高24清零,同時将源寄存 器1中的位元組資料傳送到源寄存器2所指向的存儲器中。顯然,當源寄存器1和目的寄存器為同一個寄存器時,指令交換該寄存器和存儲器的内容。
指令示例:
SWPB R0,R1,[R2] ;将R2所指向的存儲器中的位元組資料傳送到 R0,R0的高24位清零,同時将R1中的低8位資料傳送到R2所指向的存儲單元。
SWPB R0,R0,[R1] ;該指令完成将R1所指向的存儲器中的 位元組資料與R0中的低8位資料交換。
程式狀态寄存器通路指令
1、MRS指令
MRS指令的格式為:
MRS{條件} 通用寄存器 程式狀态寄存器(CPSR或SPSR)
MRS指令用于将程式狀态寄存器的内容傳送到通用寄存器中。該指令一般用在以下兩種情況:
Ⅰ.當需要改變程式狀态寄存器的内容時,可用MRS将程式狀态寄存器的内容讀入通用寄存器,修改後再寫回程式狀态寄存器。
Ⅱ.當在異常處理或程序切換時,需要儲存程式狀态寄存器的值,可先用該指令讀出程式狀态寄存器的值,然後儲存。
指令示例:
MRS R0,CPSR ;傳送CPSR的内容到R0
MRS R0,SPSR ;傳送 SPSR的内容到R0
2、MSR指令
MSR指令的格式為:
MSR{條件} 程式狀态寄存器(CPSR或SPSR)_<域>,操作數
MSR指令用于将操作數的内容傳送到程式狀态寄存器的特定域中。其中,操作數可以為通用寄存器或立即數。<域>用于設定程式狀态寄存器中需要 操作的位,32位的程式狀态寄存器可分為4個域:
位[31:24]為條件位域,用f表示;
位[23:16]為狀态位域,用s表示;
位[15:8]為擴充位域,用x表示;
位[7:0] 為控制位域,用c表示;
該指令通常用于恢複或改變程式狀态寄存器的内容,在使用時,一般要在MSR指令中指明将要操作的域。隻有在特權模式下才可以修改狀态寄存器。
指令示例:
MSR CPSR,R0 ;傳送R0的内容到CPSR
MSR SPSR,R0 ;傳送R0的内容到SPSR
MSR CPSR_c,R0 ;傳送R0的内容到SPSR,但僅僅修改CPSR中的控制位域
ARM協處理器指令
1、CDP指令
CDP指令的格式為:
CDP{條件} 協處理器編碼,協處理器操作碼1,目的寄存器,源寄存器1,源寄存器2,協處理器操作碼2。
CDP指令用于ARM處理器通知ARM協處理器執行特定的操作,若協處理器不能成功完成特定的操作,則産生未定義指令異常。其中協處理器操作碼1和協處理 器操作碼2為協處理器将要執行的操作,目的寄存器和源寄存器均為協處理器的寄存器,指令不涉及ARM處理器的寄存器和存儲器。
指令示例:
CDP P3,2,C12,C10,C3,4 ;該指令完成協處理器P3的初始化
2、LDC指令
LDC指令的格式為:
LDC{條件}{L} 協處理器編碼,目的寄存器,[源寄存器]
LDC指令用于将源寄存器所指向的存儲器中的字資料傳送到目的寄存器中,若協處理器不能成功完成傳送操作,則産生未定義指令異常。其中,{L}選項表示指 令為長讀取操作,如用于雙精度資料的傳輸。
指令示例:
LDC P3,C4,[R0] ;将ARM處理器的寄存器R0所指向的存儲器中的字數 據傳送到協處理器P3的寄存器C4中。
3、STC指令
STC指令的格式為:
STC{條件}{L} 協處理器編碼,源寄存器,[目的寄存器]
STC指令用于将源寄存器中的字資料傳送到目的寄存器所指向的存儲器中,若協處理器不能成功完成傳送操作,則産生未定義指令異常。其中,{L}選項表示指 令為長讀取操作,如用于雙精度資料的傳輸。
指令示例:
STC P3,C4,[R0] ;将協處理器P3的寄存器C4中的字資料傳送到ARM處理 器的寄存器R0所指向的存儲器中。
4、MCR指令
MCR指令的格式為:
MCR{條件} 協處理器編碼,協處理器操作碼1,源寄存器,目的寄存器1,目的寄存器2,協處理器操作碼2。
MCR指令用于将ARM處理器寄存器中的資料傳送到協處理器寄存器中,若協處理器不能成功完成操作,則産生未定義指令異常。其中協處理器操作碼1和協處理 器操作碼2為協處理器将要執行的操作,源寄存器為ARM處理器的寄存器,目的寄存器1和目的寄存器2均為協處理器的寄 存器。
指令示例:
MCR P3,3,R0,C4,C5,6 ;将ARM處理器寄存器R0中的資料傳送到協處 理器P3的寄存器C4和C5中。
5、MRC指令
MRC指令的格式為:
MRC{條件} 協處理器編碼,協處理器操作碼1,目的寄存器,源寄存器1,源寄存器2,協處理器操作碼2。
MRC指令用于将協處理器寄存器中的資料傳送到ARM處理器寄存器中,若協處理器不能成功完成操作,則産生未定義指令異常。其中協處理器操作碼1和協處理 器操作碼2為協處理器将要執行的操作,目的寄存器為ARM處理器的寄存器,源寄存器1和源寄存器2均為協處理器的寄存器。
指令示例:
MRC P3,3,R0,C4,C5,6 ;該指令将協處理器P3的寄存器中的資料傳送到 ARM處理器寄存器中。
ARM僞指令
ARM僞指令不是ARM指令集中的指令,隻是為了程式設計友善編譯器定義了僞指令,使用時可以像其他ARM指令一樣使用,但在編譯時這些僞指令将被等效的ARM指令代替。
1、符号定義僞指令
A、全局變量定義
GBLA(GBLL/GBLS) 全局變量名
GBLA 、GBLL 和GBLS 僞指令用于定義一個ARM 程式中的全局變量,并将其初始化。其中:
GBLA 僞指令用于定義一個全局的數字變量,并初始化為0 ;
GBLL 僞指令用于定義一個全局的邏輯變量,并初始化為F(假);
GBLS 僞指令用于定義一個全局的字元串變量,并初始化為空;
由于以上三條僞指令用于定義全局變量,是以在整個程式範圍内變量名必須唯一。
B、局部變量定義
LCLA (LCLL 或 LCLS )局部變量名
LCLA 、LCLL 和LCLS 僞指令用于定義一個ARM 程式中的局部變量,并将其初始化。其中:
LCLA僞指令用于定義一個局部的數字變量,并初始化為0 ;
LCLL僞指令用于定義一個局部的邏輯變量,并初始化為F(假);
LCLS僞指令用于定義一個局部的字元串變量,并初始化為空;
以上三條僞指令用于聲明局部變量,在其作用範圍内變量名必須唯一。
C、變量的指派
變量名 SETA (SETL 或 SETS )表達式
僞指令 SETA 、SETL 、SETS 用于給一個已經定義的全局變量或局部變量指派。
SETA僞指令用于給一個數學變量指派;
SETL僞指令用于給一個邏輯變量指派;
SETS僞指令用于給一個字元串變量指派;
其中,變量名為已經定義過的全局變量或局部變量,表達式為将要賦給變量的值。
D、RLIST
名稱 RLIST { 寄存器清單 }
RLIST僞指令可用于對一個通用寄存器清單定義名稱,使用該僞指令定義的名稱可在ARM 指令 LDM/STM中使用。在LDM/STM指令中,清單中的寄存器通路次序為根據寄存器的編号由低到高,而與清單中的寄存器排列次序無關。
RegList RLIST {R0-R5,R8,R10} 将寄存器清單名稱定義為 RegList ,可在ARM指令LDM/STM中通過該名稱通路寄存器清單。
2、資料定義僞指令
資料定義僞指令一般用于為特定的資料配置設定存儲單元,同時可完成已配置設定存儲單元的初始化。
常見的資料定義僞指令有如下幾種:
DCB 用于配置設定一片連續的位元組存儲單元并用指定的資料初始化。
DCW(DCWU)用于配置設定一片連續的半字存儲單元并用指定的資料初始化。
DCD (DCDU)用于配置設定一片連續的字存儲單元并用指定的資料初始化。
DCFD(DCFDU)用于為雙精度的浮點數配置設定一片連續的字存儲單元并用指定的資料初始化。
DCFS(DCFSU)用于為單精度的浮點數配置設定一片連續的字存儲單元并用指定的資料初始化。
DCQ(DCQU)用于配置設定一片以8位元組為機關的連續的存儲單元并用指定的資料初始化。
SPACE 用于配置設定一片連續的存儲單元。
MAP 用于定義一個結構化的記憶體表首位址。
FIELD 用于定義一個結構化的記憶體表的資料域。
A、DCB
文法格式:
标号 DCB 表達式
DCB僞指令用于配置設定一片連續的位元組存儲單元并用僞指令中指定的表達式初始化。其中,表達式可以為0~255的數字或字元串。DCB 也可用“=”代替。
使用示例:
Str DCB “This is a test” ;配置設定一片連續的位元組存儲單元并初始化。
B、DCW(或DCWU)
文法格式:
标号 DCW (或DCWU) 表達式
DCW(或DCWU)僞指令用于配置設定一片連續的半字存儲單元并用僞指令中指定的表達式初始化。
其中,表達式可以為程式标号或數字表達式。
用DCW配置設定的字存儲單元是半字對齊的,而用DCWU配置設定的字存儲單元并不嚴格半字對齊。
使用示例:
DataTest DCW 1 ,2 ,3 ;配置設定一片連續的半字存儲單元并初始化。
C、DCD(或DCDU)
文法格式:
标号 DCD(或DCDU) 表達式
DCD(或DCDU)僞指令用于配置設定一片連續的字存儲單元并用僞指令中指定的表達式初始化。其中,表達式可以為程式标号或數字表達式。DCD也可 用"&” 代替。
用DCD配置設定的字存儲單元是字對齊的,而用DCDU配置設定的字存儲單元并不嚴格字對齊。
使用示例:
DataTest DCD 4 ,5 ,6 ;配置設定一片連續的字存儲單元并初始化。
D、DCFD(或DCFDU)
文法格式:
标号 DCFD(或DCFDU) 表達式
DCFD(或DCFDU)僞指令用于為雙精度的浮點數配置設定一片連續的字存儲單元并用僞指令中指定的表達式初始化。每個雙精度的浮點數占據兩個字單元。用 DCFD配置設定的字存儲單元是字對齊的,而用DCFDU配置設定的字存儲單元并不嚴格字對齊。
使用示例: FDataTest DCFD 2E115 ,-5E7 ;配置設定一片連續的字存儲單元并初始化 為指定的雙精度數。
E、DCFS(或DCFSU)
文法格式:
标号 DCFS(或DCFSU) 表達式
DCFS(或DCFSU)僞指令用于為單精度的浮點數配置設定一片連續的字存儲單元并用僞指令中指定的表達式初始化。每個單精度的浮點數占據一個字單元。用 DCFS配置設定的字存儲單元是字對齊的,而用DCFSU配置設定的字存儲單元并不嚴格字對齊。
使用示例:
FDataTest DCFS 2E5 ,-5E -7 ;配置設定一片連續的字存儲單元并初始化為 指定的單精度數。
F、DCQ(或DCQU)
文法格式:
标号 DCQ(或DCQU) 表達式
DCQ(或DCQU)僞指令用于配置設定一片以8個位元組(雙字)為機關的連續存儲區域并用僞指令中指定的表達式 初始化。 用DCQ配置設定的存儲單元是字對齊的,而用DCQU 配置設定的存儲單元并不嚴格字對齊。
使用示例:
DataTest DCQ 100 ;配置設定一片連續的存儲單元并初始化為指定的值。
G、SPACE
文法格式:
标号 SPACE 表達式
SPACE僞指令用于配置設定一片連續的存儲區域并初始化為0 。其中,表達式為要配置設定的位元組數。
SPACE也可用“ % ”代替。
使用示例:
DataSpace SPACE 100 ;配置設定連續100位元組的存儲單元并初始化為0 。
H、MAP
文法格式:
MAP 表達式 { ,基址寄存器 }
MAP僞指令用于定義一個結構化的記憶體表的首位址。MAP也可用“^” 代替。
表達式可以為程式中的标号或數學表達式,基址寄存器為可選項,當基址寄存器選項不存在時,表達式的值即為記憶體表的首位址,當該選項存在時,記憶體表的首位址 為表達式的值與基址寄存器的和。
MAP僞指令通常與FIELD僞指令配合使用來定義結構化的記憶體表。
使用示例:
MAP 0x100 ,R0 ;定義結構化記憶體表首位址的值為0x100+R0 。
I、FILED
文法格式:
标号 FIELD 表達式
FIELD僞指令用于定義一個結構化記憶體表中的資料域。FILED 也可用“#” 代替。
表達式的值為目前資料域在記憶體表中所占的位元組數。
FIELD僞指令常與MAP僞指令配合使用來定義結構化的記憶體表。MAP僞指令定義記憶體表的首位址,FIELD僞指令定義記憶體表中的各個資料域,并可以為 每個資料域指定一個标号供其他的指令引用。
注意MAP和FIELD僞指令僅用于定義資料結構,并不實際配置設定存儲單元。
使用示例:
MAP 0x100 ; 定義結構化記憶體表首位址的值為0x100。
A FIELD 16 ; 定義A的長度為16位元組,位置為0x100。
B FIELD 32 ; 定義B的長度為32位元組,位置為0x110。
S FIELD 256 ;定義S的長度為256位元組,位置為0x130。
3、彙編控制僞指令
彙編控制僞指令用于控制彙程式設計式的執行流程,常用的彙編控制僞指令包括以下幾條:
IF 、ELSE 、ENDIF
WHILE 、WEND
MACRO 、MEND、MEXIT
A、IF、ELSE、ENDIF
文法格式:
IF 邏輯表達式
指令序列 1
ELSE
指令序列 2
ENDIF
IF 、ELSE 、ENDIF僞指令能根據條件的成立與否決定是否執行某個指令序列。當IF後面的邏輯表達式為真,則執行指令序列1 ,否則執行指令序 列2 。其中,ELSE及指令序列2可以沒有,此時,當IF後面的邏輯表達式為真,則執行指令序列1 ,否則繼續執行後面的指令。
IF 、ELSE 、ENDIF僞指令可以嵌套使用。
使用示例:
GBLL Test ;聲明一個全局的邏輯變量,變量名為Test
IF Test = TRUE
指令序列 1
ELSE
指令序列 2
ENDIF
B、WHILE、WEND
文法格式:
WHILE 邏輯表達式
指令序列
WEND
WHILE 、WEND僞指令能根據條件的成立與否決定是否循環執行某個指令序列。當WHILE後面的邏輯表達式為真,則執行指令序列,該指令序列執行完畢後,再判斷 邏輯表達式的值,若為真則繼續執行,一直到邏輯表達式的值為假。
WHILE 、WEND僞指令可以嵌套使用。
使用示例:
GBLA Counter ; 聲明一個全局的數學變量,變量名為Counter
Counter SETA 3 ;由變量Counter 控制循環次數
……
WHILE Counter < 10
指令序列
WEND
C、MACRO、MEND、MEXIT
文法格式:
MACRO
[$ 标号]宏名[$ 參數 1 ,$ 參數 2 ,……]
語句段
MEXIT
D、MEXIT
文法格式:
MEXIT
MEXIT用于從宏定義中跳轉出去。
4、其他僞指令
A、AREA
文法格式:
AREA 段名 屬性1 ,屬性2 ,……
AREA僞指令用于定義一個代碼段或資料段。其中,段名若以數字開頭,則該段名需用“|”括起來,如:|1_test| 。
屬性字段表示該代碼段(或資料段)的相關屬性,多個屬性用逗号分隔。常用的屬性如下:
— CODE 屬性:用于定義代碼段,預設為READONLY 。
— DATA 屬性:用于定義資料段,預設為READWRITE 。
— READONLY 屬性:指定本段為隻讀,代碼段預設為READONLY 。
— READWRITE 屬性:指定本段為可讀可寫,資料段的預設屬性為READWRITE 。
— ALIGN 屬性:使用方式為ALIGN表達式。在預設時,ELF(可執行連接配接檔案)的代碼段和資料段是按字對齊的,表達式的取值範圍為0~31,相應的對齊方式為2 表達式次方。
— COMMON 屬性:該屬性定義一個通用的段,不包含任何的使用者代碼和資料。各源檔案中同名的COMMON段共享同一段存儲單元。
一個彙編語言程式至少要包含一個段,當程式太長時,也可以将程式分為多個代碼段和資料段。
使用示例:
AREA Init ,CODE ,READONLY ; 該僞指令定義了一個代碼段,段 名為Init ,屬性為隻讀。
B、ALIGN
文法格式:
ALIGN { 表達式 { ,偏移量 }}
ALIGN僞指令可通過添加填充位元組的方式,使目前位置滿足一定的對齊方式。其中,表達式的值用于指定對齊方式,可能的取值為2的幂,如1 、2 、4 、8 、16 等。若未指定表達式,則将目前位置對齊到下一個字的位置。偏移量也為一個數字表達式,若使用該字段,則目前位置的對齊方式為:2的表達 式次幂+偏移 量。
使用示例:
AREA Init ,CODE ,READONLY ,ALIEN=3 ;指定後面的指令為8 位元組對齊。
指令序列
END
C、CODE16、CODE32
文法格式:
CODE16(或CODE32)
CODE16僞指令通知編譯器,其後的指令序列為16位的Thumb指令。
CODE32僞指令通知編譯器,其後的指令序列為32位的ARM指令。
若 在彙編源程式中同時包含ARM指令和Thumb指令時,可用CODE16僞指令通知編譯器其後的指令序列為16位的Thumb指令,CODE32僞指 令 通知編譯器其後的指令序列為32位的ARM指令。是以,在使用ARM指令和Thumb指令混合程式設計的代碼裡,可用這兩條僞指令進行切換,但注意他們隻 通知 編譯器其後指令的類型,并不能對處理器進行狀态的切換。
使用示例:
AREA Init ,CODE ,READONLY ……
CODE32 ; 通知編譯器其後的指令為32位的 ARM指令
LDR R0 ,=NEXT+1 ;将跳轉位址放入寄存器R0
BX R0 ; 程式跳轉到新的位置執行, 并将處理器切換到Thumb工作狀态
……
CODE16 ; 通知編譯器其後的指令為16位的 Thumb指令
NEXT LDR R3,=0x3FF
……
END ;
D、ENTRY
文法格式:
ENTRY
ENTRY僞指令用于指定彙程式設計式的入口點。在一個完整的彙程式設計式中至少要有一個ENTRY(也可以有多個,當有多個ENTRY時,程式的真正入口點由鍊 接器指定),但在一個源檔案裡最多隻能有一個ENTRY(可以沒有)。
使用示例:
AREA Init ,CODE ,READONLY
ENTRY ; 指定應用程式的入口點
……
E、END
文法格式:
END
END僞指令用于通知編譯器已經到了源程式的結尾。
使用示例:
AREA Init ,CODE ,READONLY
……
END ;指定應用程式的結尾
F、EQU
文法格式:
名稱 EQU 表達式 { ,類型 }
EQU僞指令用于為程式中的常量、标号等定義一個等效的字元名稱,類似于C語言中的#define 。其中EQU可用“*”代替。名稱為EQU僞指令定義的字元名稱,當表達式為32位的常量時,可以指定 表達式的資料類型,可以有以下三種類型:
CODE16 、CODE32 和DATA
使用示例:
Test EQU 50 ; 定義标号Test 的值為50。
Addr EQU 0x55 ,CODE32 ; 定義Addr的值為0x55 ,且該處為32位的ARM指令。
G、EXPORT(或GLOBAL)
文法格式:
EXPORT 标号 {[WEAK]}
EXPORT僞指令用于在程式中聲明一個全局的标号,該标号可在其他的檔案中引用。EXPORT 可用GLOBAL代替。标号在程式中區分大小寫,[WEAK] 選項聲明其他的同名标号優先于該标号被引用。
使用示例:
AREA Init ,CODE ,READONLY
EXPORT Stest ;聲明一個可全局引用的标号Stest
END
H、IMPORT
文法格式:
IMPORT 标号 {[WEAK]}
IMPORT僞指令用于通知編譯器要使用的标号在其他的源檔案中定義,但要在目前源檔案中引用,而且無論目前源檔案是否引用該标号,該标号均會被加入到當 前源檔案的符号表中。标 号在程式中區分大小寫,[WEAK] 選項表示當所有的源檔案都沒有定義這樣一個标号時,編譯器也不給出錯誤資訊,在多數情況下 将該标号置為0 ,若該标号為B或BL指令引用,則将B或BL指令置為NOP操作。
使用示例:
AREA Init ,CODE ,READONLY
IMPORT Main ;通知編譯器目前檔案要引用标号Main,但Main在其他源檔案中定 義。
END
I、EXTERN
文法格式:
EXTERN 标号 {[WEAK]}
EXTERN僞指令用于通知編譯器要使用的标号在其他的源檔案中定義,但要在目前源檔案中引用,如果目前源檔案實際并未引用該标号,該 标号就不會被加入 到目前源檔案的符号表中。标号在程式中區分大小寫, [WEAK] 選項表示當所有的源檔案都沒有定義這樣一個标号時,編譯器也不給出錯誤資訊,在多數情 況下将該标号置為0 ,若該标号為B或BL指令引用,則将B或BL指令置為NOP操作。
使用示例:
AREA Init ,CODE ,READONLY
EXTERN Main ;通知編譯器目前檔案要引用标号Main,但Main在其他源檔案中定 義。
END
J、GET(或INCLUDE)
文法格式:
GET 檔案名
GET僞指令用于将一個源檔案包含到目前的源檔案中,并将被包含的源檔案在目前位置進行彙編處理。可 以使用INCLUDE代替GET。
彙程式設計式中常用的方法是在某源檔案中定義一些宏指令,用EQU定義常量的符号名稱,用MAP和FIELD定義結構化的資料類型,然後用GET僞指令将這個 源檔案包含到其他的源檔案中。使用方法與C 語言中的"include” 相似。
GET僞指令隻能用于包含源檔案,包含目标檔案需要使用INCBIN僞指令
使用示例:
AREA Init ,CODE ,READONLY
GET a1.s ; 通知編譯器目前源檔案包含源檔案a1.s
GET C:\a2.s ; 通知編譯器目前源檔案包含源檔案C:\a2.s
END
K、INCBIN
文法格式:
INCBIN 檔案名
INCBIN僞指令用于将一個目标檔案或資料檔案包含到目前的源檔案中,被包含的檔案不作任何變動的存放在目前檔案中,編譯器從其後開始繼續處理。
使用示例:
AREA Init ,CODE ,READONLY
INCBIN a1.dat ; 通知編譯器目前源檔案包含檔案a1.dat
INCBIN C:\a2.txt ;通知編譯器目前源檔案包含檔案C:\a2.txt
END
L、RN
文法格式:
名稱 RN 表達式
RN僞指令用于給一個寄存器定義一個别名。采用這種方式可以友善程式員記憶該寄存器的功能。其中,名稱為給寄存器定義的别名,表達式為寄存器的編碼。
使用示例:
Temp RN R0 ;将R0定義一個别名Temp
M、ROUT
文法格式:
{名稱} ROUT
ROUT僞指令用于給一個局部變量定義作用範圍。在程式中未使用該僞指令時,局部 變量的作用範圍為所在的AREA,而使用ROUT後,局部變量的作為範圍為目前ROUT和下一個ROUT之間。
嵌入式arm彙編指令這是最全的了,都記住了嗎?記不住也沒事,收藏起來可以備以後來使用,但是必須要了解才行。