日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

经常使用ARM汇编指令

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 经常使用ARM汇编指令 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一面學習,一面總結,一面記錄。

以下是整理在網上找到的一些資料,簡單整理記錄一下,方便以后查閱。


ARM處理器的指令集能夠分為跳轉指令、數據處理指令、程序狀態寄存器(PSR)處理指令、載入/存儲指令、協處理器指令和異常產生指令6大指令。


一、跳轉指令


跳轉指令用于實現程序流程的跳轉,在ARM程序中有下面兩種方法能夠實現程序流程的跳轉。
Ⅰ.使用專門的跳轉指令。

Ⅱ.直接向程序計數器PC寫入跳轉地址值。通過向程序計數器PC寫入跳轉地址值,能夠實如今4GB的地址空間中的隨意跳轉,在跳轉之前結合使用MOV LR,PC等類似指令,能夠保存將來的返回地址值。從而實如今4GB連續的線性地址空間的子程序調用。


ARM指令集中的跳轉指令能夠完畢從當前指令向前或向后的32MB的地址空間的跳轉,包含下面4條指令:


1、B指令


B指令的格式為:
B{條件} 目標地址
B指令是最簡單的跳轉指令。一旦遇到一個B指令。ARM處理器將馬上跳轉到給定的目標地址,從那里繼續運行。注意存儲在跳轉指令中的實際值是相對當前PC 值的一個偏移量,而不是一個絕對地址,它的值由匯編器來計算(參考尋址方式中的相對尋址)。它是24位有符號數,左移兩位后有符號擴展為32 位,表示的有效偏移為26 位(前后32MB的地址空間)。下面指令:
B??? Label???????????? ;程序無條件跳轉到標號Label處運行
CMP R1,#0????? ;當CPSR寄存器中的Z條件碼置位時,程序跳轉到標號Label處運行

BEQ Label??????


2、BL指令


BL指令的格式為:
BL{條件} 目標地址
BL是還有一個跳轉指令,但跳轉之前。會在寄存器R14中保存PC的當前內容,因此。能夠通過將R14的內容又一次載入到PC中,來返回到跳轉指令之后的那個 指令處運行。

該指令是實現子程序調用的一個基本但經常使用的手段。
以 下指令:
BL?? Label???????? ;當程序無條件跳轉到標號Label處運行時,同一時候將當前的 PC值保存到

;R14(LR)中


3、BLX指令


BLX指令的格式為:
BLX 目標地址

BLX指令從ARM指令集跳轉到指令中所指定的目標地址,并將處理器的工作狀態有ARM狀態切換到Thumb狀態,該指令同一時候將PC的當前內容保存到寄存 器R14中。因此,當子程序使用Thumb指令集。而調用者使用ARM指令集時,能夠通過BLX指令實現子程序的調用和處理器工作狀態的切換。

同一時候,子程 序的返回能夠通過將寄存器R14值拷貝到PC中來完畢。


4、BX指令


BX指令的格式為:
BX{條件} 目標地址
BX指令跳轉到指令中所指定的目標地址。目標地址處的指令既能夠是ARM指令,也能夠是Thumb指令。

二、數據處理指令


數據處理指令可分為數據傳送指令、算術邏輯運算指令 和比較指令等。


數據傳送指令用于在寄存器和存儲器之間進行數據的雙向傳輸。
算術邏輯運算指令完畢經常使用的算術與邏輯的運算,該類指令不但將運算結果保存在目的寄存器中,同一時候更新CPSR中的對應條件標志位。
比較指令不保存運算結果。僅僅更新CPSR中對應的條件標志位。

數據處理指令共下面16條。


1、MOV指令(傳送)


MOV指令的格式為:
MOV{條件}{S} 目的寄存器。源操作數
MOV指令可完畢從還有一個寄存器、被移位的寄存器或將一個馬上數載入到目的寄存器。當中S選項決定指令的操作是否影響CPSR中條件標志位的值,當沒有S 時指令不更新CPSR中條件標志位的值。
指令演示樣例:
MOV R1。R0??????????????????? ;將寄存器R0的值傳送到寄存器R1
MOV PC。R14????????????????? ;將寄存器R14的值傳送到 PC,經常使用于子程序返回

MOV R1。R0。LSL#3????;將寄存器R0的值左移3位后傳送到R1


2、MVN指令(求反)


MVN指令的格式為:
MVN{條件}{S} 目的寄存器。源操作數
MVN指令可完畢從還有一個寄存器、被移位的寄存器、或將一個馬上數載入到目的寄存器。與MOV指令不同之處是在傳送之前按位被取反了,即把一個被取反的值 傳送到目的寄存器中。

當中S決定指令的操作是否影響CPSR中條件標志位的值。當沒有S時指令不更新CPSR中條件標志位的值。
指令演示樣例:

MVN R0,#0????????????。將 馬上數0取反傳送到寄存器R0中,完畢后R0=-1


3、CMP指令(比較)


CMP指令的格式為:
CMP{條件} 操作數1,操作數2
CMP指令用于把一個寄存器的內容和還有一個寄存器的內容或馬上數進行比較。同一時候更新CPSR中條件標志位的值。該指令進行一次減法運算。但不存儲結果,僅僅 更改條件標志位。 標志位表示的是操作數1與操作數2的關系(大、小、相等),比如,當操作數1大于操作操作數2,則此后的有GT后綴的指令將能夠運行。
指令演示樣例:
CMP?? R1,R0???????;將寄存器R1的值與寄存器R0的值相減,并依據 結果設置CPSR的標
。志位

CMP R1,#100???;將寄存器R1的值與馬上數100相減。并根 據結果設置CPSR的標志位


4、CMN指令(負數比較)


CMN指令的格式為:
CMN{條件} 操作數1,操作數2
CMN指令用于把一個寄存器的內容和還有一個寄存器的內容或馬上數取反后進行比較,同一時候更新CPSR中條件標志位的值。該指令實際完畢操作數1和操作數2相 加。并依據結果更改條件標志位。
指令演示樣例:
CMN?? R1。R0?????;將寄存器R1的值與寄存器R0的值相加。并依據 結果設置CPSR
。的標志位

CMN R1。#100??;將寄存器R1的值與馬上數100相加。并依據 結果設置CPSR的標志位


5、TST指令(測試)


TST指令的格式為:
TST{條件} 操作數1,操作數2
TST指令用于把一個寄存器的內容和還有一個寄存器的內容或馬上數進行按位的與運算,并依據運算結果更新CPSR中條件標志位的值。操作數1是要測試的數 據。而操作數2是一個位掩碼。該指令一般用來檢測是否設置了特定的位。


指令演示樣例:
TST?? R1。#%1????????????。用于測試在寄存器R1中是否設置了最低位(%表 示二進制數)
TST R1,#0xffe?????????? ;將寄存器R1的值與馬上數0xffe按位與。并依據 結果設置CPSR

;的標志位


6、TEQ指令(測試相等)


TEQ指令的格式為:
TEQ{條件} 操作數1,操作數2
TEQ指令用于把一個寄存器的內容和還有一個寄存器的內容或馬上數進行按位的異或運算,并依據運算結果更新CPSR中條件標志位的值。該指令通經常使用于比較操作數1和操作數2是否相等。
指令演示樣例:
TEQ?? R1。R2????????? ;將寄存器R1的值與寄存器R2的值按位異或。并依據結果 設置CPSR

;的標志位


7、ADD指令(相加)


ADD指令的格式為:
ADD{條件}{S} 目的寄存器,操作數1。操作數2
ADD指令用于把兩個操作數相加,并將結果存放到目的寄存器中。

操作數1應是一個寄存器。操作數2能夠是一個寄存器。被移位的寄存器,或一個馬上數。
指令演示樣例:
ADD???? R0,R1,R2????????????????? 。 R0 = R1 + R2
ADD???? R0,R1,#256??????????????? ; R0 = R1 + 256

ADD???? R0,R2。R3。LSL#1?????? 。 R0 = R2 + (R3 << 1)


8、ADC指令(帶進位相加)


ADC指令的格式為:
ADC{條件}{S} 目的寄存器,操作數1,操作數2
ADC指令用于把兩個操作數相加,再加上CPSR中的C條件標志位的值,并將結果存放到目的寄存器中。它使用一個進位標志位。這樣就能夠做比32位大的數 的加法,注意不要忘記設置S后綴來更改進位標志。操作數1應是一個寄存器。操作數2能夠是一 個寄存器,被移位的寄存器,或一個馬上數。
下面指令序列完畢兩個128位數的加法。第一個數由高到低存放在寄存器R7~R4。第二個數由高到低存放在寄存器R11~R8,運算結果由高到低存放在寄 存器R3~R0:
ADDS??? R0,R4。R8????????? 。 加低端的字
ADCS??? R1,R5,R9????????? ; 加第二個字,帶進位
ADCS??? R2,R6。R10??????? 。 加第三個字,帶進位

ADC????? R3,R7。R11??????? ; 加第四個字,帶進位


9、SUB指令(相減)


SUB指令的格式為:
SUB{條件}{S} 目的寄存器。操作數1。操作數2
SUB指令用于把操作數1減去操作數2,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2能夠是一個寄存器,被移位的寄存器,或一個馬上 數。該指令可用于有符號數或無符號數的減法運算。


指令演示樣例:
SUB???? R0,R1,R2???????????????? ; R0 = R1 - R2
SUB???? R0,R1,#256??????????? ; R0 = R1 - 256

SUB???? R0,R2,R3,LSL#1????? ; R0 = R2 - (R3 << 1)


10、~~~~C指令


~~~~C指令的格式為:
~~~~C{條件}{S} 目的寄存器,操作數1。操作數2
~~~~C指令用于把操作數1減去操作數2,再減去CPSR中的C條件標志位的反碼,并將結果存放到目的寄存器中。操作數1應是一個寄存器。操作數2能夠 是一個寄存器。被移位的寄存器。或一個馬上數。該指令使用進位標志來表示借位,這樣就能夠做大于32位的減法,注意不要忘記設置S后綴來更改進位標志。該指令可用于有符號數或無符號數的減法運算。
指令演示樣例:

SUBS??? R0,R1,R2??????? ;R0 = R1 - R2 - 。C,并依據結果設置CPSR的進位標志位


11、R~~~~指令


R~~~~指令的格式為:
R~~~~{條件}{S} 目的寄存器。操作數1。操作數2
R~~~~指令稱為逆向減法指令,用于把操作數2減去操作數1,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2能夠是一個寄存器,被移位 的寄存器。或一個馬上數。該指令可用于有符號數或無符號數的減法運算。


指令演示樣例:
R~~~~???? R0。R1,R2???????????????????????? ; R0 = R2 – R1
R~~~~???? R0。R1,#256???????????????????? 。 R0 = 256 – R1

R~~~~???? R0。R2,R3。LSL#1?????????? 。 R0 = (R3 << 1) - R2


12、RSC指令(反向帶進位減)


RSC指令的格式為:
RSC{條件}{S} 目的寄存器,操作數1,操作數2
RSC指令用于把 操作數2減去操作數1,再減去CPSR中的C條件標志位的反碼,并將結果存放到目的寄存器中。

操作數1應是一個寄存器,操作數2能夠是一個寄存器。被移位 的寄存器,或一個馬上數。

該指令使用進位標志來表示借位,這樣就能夠做大于32位的減法。注意不要忘記設置S后綴來更改進位標志。該指令可用于有符號數或 無符號數的減法運算。


指令演示樣例:

RSC???? R0,R1,R2?????????? ;R0 = R2 – R1 - !

C


13、AND指令(邏輯位 與)


AND指令的格式為:
AND{條件}{S} 目的寄存器。操作數1,操作數2
AND指令用于在兩個操作數上進行邏輯與運算。并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2能夠是一個寄存器。被移位的寄存器,或一個 馬上數。

該指令經常使用于屏蔽操作數1的某些位。


指令演示樣例:

AND R0,R0。#3????????? 。該指令保持R0的0、1位,其余位清零。


14、ORR指令(邏輯位 或)


ORR指令的格式為:
ORR{條件}{S} 目的寄存器,操作數1,操作數2
ORR指令用于在兩個操作數上進行邏輯或運算,并把結果放置到目的寄存器中。操作數1應是一個寄存器。操作數2能夠是一個寄存器,被移位的寄存器。或一個 馬上數。該指令經常使用于設置操作數1的某些位。
指令演示樣例:

ORR R0,R0,#3??????? ;該指令設置R0的0、1位,其余位保持不變。


15、EOR指令(邏輯位 異或)


EOR指令的格式為:
EOR{條件}{S} 目的寄存器。操作數1,操作數2
EOR指令用于在兩個操作數上進行邏輯異或運算,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2能夠是一個寄存器。被移位的寄存器,或一 個馬上數。

該指令經常使用于反轉操作數1的某些位。
指令演示樣例:

EOR R0。R0,#3??????? 。該指令反轉R0的0、1位,其余位保持不變。


16、BIC指令(位清零)


BIC指令的格式為:
BIC{條件}{S} 目的寄存器。操作數1。操作數2
BIC指令用于清除操作數1的某些位,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2能夠是一個寄存器。被移位的寄存器,或一個馬上數。

操作數2為32位的掩碼。假設在掩碼中設置了某一位。則清除這一位。未設置的掩碼位保持不 變。
指令演示樣例:
BIC R0。R0。#%1011??? ;該指令清除R0中的位 0、1、和 3,其余的位保持不變。

三、乘法指令與乘加指令


ARM 微處理器支持的乘法指令與乘加指令共同擁有6條,可分為運算結果為32位和運算結果為64位兩類,與前面的數據處理指令不同,指令中的全部操作數、目的寄存器 必須為通用寄存器,不能對操作數使用馬上數或被移位的寄存器,同一時候,目的寄存器和操作數1必須是不同的寄存器。

乘法指令與乘加指令共同擁有下面6條:


1、MUL指令(相乘)


MUL指令的格式為:
MUL{條件}{S} 目的寄存器。操作數1,操作數2
MUL指令完畢將操作數1與操作數2的乘法運算,并把結果放置到目的寄存器中。同一時候能夠依據運算結果設置CPSR中對應的條件標志位。

當中。操作數1和操 作數2均為32位的有符號數或無符號數。


指令演示樣例:
MUL R0,R1。R2??????????? ;R0 = R1 × R2

MULS R0,R1。R2?????? ???? ;R0 = R1 × R2,同一時候設置CPSR中的相關條件標志位


2、MLA指令(帶累加的相乘)


MLA指令的格式為:
MLA{條件}{S} 目的寄存器。操作數1。操作數2,操作數3
MLA指令完畢將操作數1與操作數2的乘法運算,再將乘積加上操作數3,并把結果放置到目的寄存器中,同一時候能夠依據運算結果設置CPSR中對應的條件標志 位。當中,操作數1和操作數2均為32位的有符號數或無符號數。


指令演示樣例:
MLA?? R0,R1,R2,R3??????????? ;R0 = R1 × R2 + R3

MLAS R0,R1。R2。R3??????????? ;R0 = R1 × R2 + R3。同一時候設置CPSR中的相關條件標志位


3、SMULL指令


SMULL指令的格式為:
SMULL{條件}{S}?? 目的寄存器Low,目的寄存器High,操作數1,操作數2
SMULL指令完畢將操作數1與操作數2的乘法運算,并把結果的低32位放置到目的寄存器Low中,結果的高32位放置到目的寄存器High中。同一時候能夠 依據運算結果設置CPSR中對應的條件標志位。當中,操作數1和操作數2均為32位的有符號數。
指令演示樣例:
SMULL?? R0,R1,R2,R3???? 。R0 = (R2 × R3)的低32位

??????????????????????????????????????????????? 。R1 = (R2 × R3)的高32位


4、SMLAL指令


SMLAL指令的格式為:
SMLAL{條件}{S}?? 目的寄存器Low,目的寄存器High。操作數1,操作數2
SMLAL指令完畢將操作數1與操作數2的乘法運算,并把結果的 低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,結果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同 時能夠依據運算結果設置CPSR中對應的條件標志位。當中,操作數1和操作數2均為32位的有符號數。
對于目的寄存器Low,在指令運行前存放64位加數的低32位,指令運行后存放結果的低32位;對于目的寄存器High,在指令運行前存放64位加數的高32位,指令運行后存放結果的高32位。


指令演示樣例:
SMLAL?? R0,R1。R2,R3?????? ;R0 = (R2 × R3)的低32位 + R0

???????????????????????????????????????????????? ;R1 = (R2 × R3)的高32位 + R1


5、UMULL指令


UMULL指令的格式為:
UMULL{條件}{S}?? 目的寄存器Low。目的寄存器High。操作數1,操作數2
UMULL指令完畢將操作數1與操作數2的乘法運算。并把結果的低32位放置到目的寄存器Low中。結果的高32位放置到目的寄存器High中,同一時候能夠 依據運算結果設置CPSR中對應的條件標志位。當中。操作數1和操作數2均為32位的無符號數。
指令演示樣例:
UMULL?? R0,R1,R2。R3?????? 。R0 = (R2 × R3)的低32位

???????????????????????????????????????????????? 。R1 = (R2 × R3)的高32位


6、UMLAL指令


UMLAL指令的格式為:
UMLAL{條件}{S}?? 目的寄存器Low,目的寄存器High,操作數1。操作數2
UMLAL指令完畢將操作數1與操作數2的乘法運算,并把結果的 低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,結果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High 中,同 時能夠依據運算結果設置CPSR中對應的條件標志位。當中。操作數1和操作數2均為32位的無符號數。


對于目的寄存器Low。在指令運行前存放64位加數的低32位,指令運行后存放結果的低32位。對于目的寄存器High,在指令運行前存放64位加數的高32位。指令運行后存放結果的高32位。
指令演示樣例:
UMLAL?? R0,R1,R2。R3???????? ?? ;R0 = (R2 × R3)的低32位 + R0

?????????????????????????????????????????????????????? 。R1 = (R2 × R3)的高32位 + R1


四、程序狀態寄存器訪問指令


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、LDR指令


LDR指令的格式為:

LDR{條件} 目的寄存器,<存儲器地址>
LDR指令用于從存儲器中將一個32位的字數據傳送到目的寄存器中。該指令通經常使用于從存儲器中讀取32位的字數據到通用寄存器,然后對數據進行處理。

當程序計數器PC作為 目的寄存器時,指令從存儲器中讀取的字數據被當作目的地址。從而能夠實現程序流程的跳轉。該指令在程序設計 中比較經常使用,且尋址方式靈活多樣,請讀者認真掌握。


指令演示樣例:
LDR R0,[R1]??????????????? 。將存儲器地址為R1的字數據讀入寄存器R0。
LDR R0,[R1,R2]?????? ;將存儲器地址為R1+R2的字數據讀入寄存器R0。
LDR R0,[R1,#8]??????? ;將存儲器地址為R1+8的字數據讀入寄存器R0。
LDR R0,[R1,R2] !

??? ;將存儲器地址為R1+R2的字數據讀入寄存器R0,并將新地 址
;R1+R2寫入R1。


LDR R0,[R1,#8] !

?? ;將存儲器地址為R1+8的字數據讀入寄存器R0。并將新地址 R1
。+8寫入R1。


LDR R0,[R1]。R2??????? ;將存儲器地址為R1的字數據讀入寄存器R0,并將新地址 R1+
;R2寫入R1。
LDR R0,[R1。R2。LSL#2]! ;將存儲器地址為R1+R2×4的字數據讀入寄存器R0,并
;將新地址R1+R2×4寫入R1。


LDR R0。[R1],R2,LSL#2????? ;將存儲器地址為R1的字數據讀入 寄存器R0。并將新地

。址R1+R2×4寫入R1。


2、LDRB指令


LDRB指令的格式為:
LDR{條件}B 目的寄存器,<存儲器地址>
LDRB指令用于從存儲器中將一個8位的字節數據傳送到目的寄存器中。同一時候將寄存器的高24位清零。 該指令通經常使用于從存儲器中讀取8位的字節數據到通用寄存器,然后對數據進行處理。

當程序計數器PC作為目的寄存器時。指令從存儲器中讀取的字數據被當作目 的地址,從而能夠實現程序流程的跳轉。
指令演示樣例:
LDRB R0,[R1]???? 。將存儲器地址為R1的字節數據讀入寄存器 R0,并將R0的高24
。位清零。


LDRB R0。[R1,#8]?????? ;將存儲器地址為R1+8的字節數據讀入寄存器R0,并將 R0的

;高24位清零。


3、LDRH指令


LDRH指令的格式為:
LDR{條件}H 目的寄存器。<存儲器地址>
LDRH指令用于從存儲器中將一個16位的半字數據傳送到目的寄存器中,同一時候將寄存器的高16位清零。 該指令通經常使用于從存儲器中讀取16位的半字數據到通用寄存器,然后對數據進行處理。當程序計數器PC作為目的寄存器時。指令從存儲器中讀取的字數據被當作 目的地址,從而能夠實現程序流程的跳轉。
指令演示樣例:
LDRH?? R0。[R1]???????????? 。將存儲器地址為R1的半字數據讀入寄存器 R0,并將R0的高
;16位清零。
LDRH R0,[R1。#8]???? 。將存儲器地址為R1+8的半字數據讀入寄存器R0,并將R0 的
。高16位清零。


LDRH R0。[R1,R2]???? ;將存儲器地址為R1+R2的半字數據讀入寄存器R0。并將 R0的

;高16位清零。


4、STR指令


STR指令的格式為:
STR{條件} 源寄存器,<存儲器地址>
STR指令用于從源寄存器中將一個32位的字數據傳送到存儲器中。 該指令在程序設計中比較經常使用。且尋址方式靈活多樣。使用方式可參考指令LDR。
指令演示樣例:
STR R0。[R1],#8?????????? ;將R0中的字數據寫入以R1為地址的存儲器中。并 將新地址
。R1+8寫入R1。

STR R0,[R1,#8]????????? ;將R0中的字數據寫入以R1+8為地址的存儲器中。


5、STRB指令


STRB指令的格式為:
STR{條件}B 源寄存器,<存儲器地址>
STRB指令用于從源寄存器中將一個8位的字節數據傳送到存儲器中。該字節數據為源寄存器中的低8位。


指令演示樣例:
STRB??? R0。[R1]???????????? 。將寄存器R0中的字節數據寫入以R1為地 址的存儲器中。


STRB??? R0,[R1,#8]???? 。將寄存器R0中的字節數據寫入以R1+8為地址的存 儲器中。


6、STRH指令


STRH指令的格式為:
STR{條件}H 源寄存器,<存儲器地址>
STRH指令用于從源寄存器中將一個16位的半字數據傳送到存儲器中。該半字數據為源寄存器中的低16位。


指令演示樣例:
STRH?? R0,[R1]??????????? 。將寄存器R0中的半字數據寫入以R1為地址的 存儲器中。

STRH?? R0。[R1。#8]??? ;將寄存器R0中的半字數據寫入以R1+8 為地址的存儲器中。



六、批量數據載入/存儲指令。


ARM微處理器所支持批量數據載入/存儲指令能夠一次在一片連續的存儲器單元和多個寄存器之間傳送數據,批量載入指令 用于將一片連續的存儲器中的數據傳送到多個寄存器。批量數據存儲指令則完畢相反的操作。

經常使用的載入存儲指令例如以下:LDM(或STM)指令

LDM(或STM)指令的格式為:
LDM(或STM){條件}{類型} 基址寄存器{!}。寄存器列表{∧}
LDM(或STM)指令用于從由基址寄存器所指示的一片連續存儲器到寄存器列表所指示的多個寄存器之間傳送數據,該指令的常見用途是將多個寄存器的內容入棧或出棧。當中。{類型}為 下面幾種情況:
IA??? 每次傳送后地址加1;
IB????? 每次傳送前地址加1。
DA?? 每次傳送后地址減1;
DB?? 每次傳送前地址減1;
FD?? 滿遞減堆棧;
ED?? 空遞減堆棧。
FA?? 滿遞增堆棧;
EA?? 空遞增堆棧;
{!}為可選后綴,若選用該后綴,則當數據 傳送完成之后。將最后的地址寫入基址寄存器,否則基址寄存器的內容不改變。
基址寄存器不同意為R15,寄存器列表能夠為R0~R15的隨意組合。
{∧}為可選后綴,當指令為LDM且寄存器列表中包括R15。選用該后綴時表示:除了正常的數據傳送之外,還將SPSR拷貝到CPSR。

同一時候,該后綴還表 示傳入或傳出的是用戶模式下的寄存器,而不是當前模式下的寄存器。
指令演示樣例:
STMFD R13!,{R0,R4-R12,LR}??????? ;將寄存器列表中的寄存器(R0,R4到R12,LR)存入堆棧。


LDMFD R13!, {R0,R4-R12。PC}?????? ;將堆棧內容恢復到寄存器(R0,R4到R12,LR)。

七、數據交換指令


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、LSL(或ASL)


LSL(或ASL)的格式為:
通用寄存器。LSL(或ASL) 操作數?????
LSL(或ASL)可完畢對通用寄存器中的內容進行邏輯(或算術)的左移操作。按操作數所指定的數量向左移位,低位用零來填充。

當中,操作數能夠是通用寄存器,也能夠是馬上數(0~31)。


操作演示樣例

MOV?? R0, R1, LSL #2????????? ;將R1中的內容左移兩位后傳送到R0 中。


2、LSR


LSR的格式為:
通用寄存器,LSR 操作數?????
LSR可完畢對通用寄存器中的內容進行右移的操作。按操作數所指定的數量向右移位。左端用零來填充。當中,操作數能夠 是通用寄存器,也能夠是馬上數(0~31)。


操作演示樣例:

MOV?? R0, R1, LSR #2???????? ;將R1中的內容右移兩位后傳送到R0 中,左端用零來填充。


3、ASR


ASR的格式為:
通用寄存器。ASR 操作數?????
ASR可完畢對通用寄存器中的內容進行右移的操作。按操作數所指定的數量向右移位,左端用第31位的值來填充。

當中。操作數能夠是通用寄存器。也能夠是立 即數(0~31)。
操作演示樣例:

MOV??? R0, R1, ASR #2??????? 。將R1中的內容右移兩位后傳送到R0 中,左端用第31位的值來填充。


4、ROR


ROR的格式為:
通用寄存器,ROR 操作數?????
ROR可完畢對通用寄存器中的內容進行循環右移的操作,按操作數所指定的數量向右循環移位,左端用右端移出的位來填充。當中。操作數能夠是通用寄存器。也 能夠是馬上數(0~31)。顯然,當進行32位的循環右移操作時,通用寄存器中的值不改變。


操作演示樣例:

MOV??? R0, R1, ROR #2?????? 。將R1中的內容循環右移兩位后傳送到R0 中。


5、RRX


RRX的格式為:
通用寄存器。RRX 操作數?????
RRX可完畢對通用寄存器中的內容進行帶擴展的循環右移的操作。按操作數所指定的數量向右循環移位,左端用進位標志位C來填充。當中。操作數能夠是通用寄 存器,也能夠是馬上數(0~31)。


操作演示樣例:
MOV?? R0, R1, RRX #2???????? 。將R1中的內容進行帶擴展的循環右移兩位 后傳送到R0中。


?

九、協處理器指令


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處理器寄存器中。


十、異常產生指令


1、SWI指令


SWI指令的格式為:
SWI{條件} 24位的馬上數
SWI指令用于產生軟件中斷,以便用戶程序能調用操作系統的系統例程。操作系統在SWI的異常處理程序中提供對應的系統服務,指令中24位的馬上數指定用 戶程序調用系統例程的類型,相關參數通過通用寄存器傳遞,當指令中24位的馬上數被忽略時。用戶程序調用系統例程的類型由通用寄存器R0的內容決定,同 時。參數通過其它通用寄存器傳遞。


指令演示樣例:

SWI?? 0x02??????????????? 。該指令調用操作系統編號位02的系統例程。


2、BKPT指令


BKPT指令的格式為:
BKPT?? 16位的馬上數
BKPT指令產生軟件斷點中斷,可用于程序的調試。

ARM匯編偽指令


在ARM匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統的助記符不同。沒有相相應的操作碼。通常稱這些特殊指令助記符為偽指令。他們所完畢 的操作稱為偽操作。

偽指令在源程序中的作用是為完畢匯編程序作各種準備工作的,這些偽指令僅在匯編過程中起作用。一旦匯編結束,偽指令的使命就完 成。

?????

?????? 在ARM 的匯編程序中。有例如以下幾種偽指令:符號定義偽指令、數據定義偽指令、匯編控制偽指令、宏指令以及其它偽指令。


一、符號定義(Symbol Definition)偽指令????


符號定義偽指令用于定義ARM 匯編程序中的變量、對變量賦值以及定義寄存器的別名等操作。

????
常見的符號定義偽指令有例如以下幾種:???
??? — 用于定義全局變量的GBLA 、GBLL 和GBLS 。

???
??? — 用于定義局部變量的LCLA 、LCLL 和LCLS 。???
??? — 用于對變量賦值的SETA 、SETL 、SETS 。???

??? — 為通用寄存器列表定義名稱的RLIST 。????


1、GBLA、GBLL 和GBLS???
??? 語法格式:???
??? GBLA (GBLL 或GBLS )全局變量名???
??? GBLA 、GBLL 和GBLS 偽指令用于定義一個ARM 程序中的全局變量,并將其初始化。當中:???
??? GBLA 偽指令用于定義一個全局的數字變量,并初始化為0 ;???
??? GBLL 偽指令用于定義一個全局的邏輯變量。并初始化為F(假);???
??? GBLS 偽指令用于定義一個全局的字符串變量,并初始化為空;???
??? 因為以上三條偽指令用于定義全局變量。因此在整個程序范圍內變量名必須唯一。???
??? 使用演示樣例:???
??? GBLA Test1 ;?????????? 定義一個全局的數字變量。變量名為 Test1。???
??? Test1 SETA 0xaa 。?? 將該變量賦值為0xaa。???
??? GBLL Test2 ;??????????? 定義一個全局的邏輯變量,變量名為 Test2。

???
??? Test2 SETL {TRUE} ;將該變量賦值為真。

???
??? GBLS Test3 ;???????????? 定義一個全局的字符串變量,變量名為 Test3。???
??? Test3 SETS “Testing” 。將該變量賦值為"Testing”。

??

2、LCLA、LCLL 和LCLS???
??? 語法格式:???
??? LCLA (LCLL 或 LCLS )局部變量名???
??? LCLA 、LCLL 和LCLS 偽指令用于定義一個ARM 程序中的局部變量,并將其初始化。當中:???
??? LCLA偽指令用于定義一個局部的數字變量。并初始化為0 ;???
??? LCLL偽指令用于定義一個局部的邏輯變量。并初始化為F(假);???
??? LCLS偽指令用于定義一個局部的字符串變量,并初始化為空;???
??? 以上三條偽指令用于聲明局部變量。在其作用范圍內變量名必須唯一。???
??? 使用演示樣例:???
??? LCLA Test4 ;??????????? 聲明一個局部的數字變 量,變量名為Test4。??
??? Test3 SETA 0xaa 。?? 將該變量賦值為0xaa。

???
?? LCLL Test5 ;???????????? 聲明一個局部的邏輯變 量,變量名為Test5。???
??? Test4 SETL {TRUE} ;將該變量賦值為真。

???
??? LCLS Test6 。???????????? 定義一個局部的字 符串變量,變量名為Test6。???
??? Test6 SETS “Testing” 。將該變量賦值為 "Testing”。???

3、SETA、SETL 和SETS???
??? 語法格式:???
??? 變量名 SETA (SETL 或 SETS )表達式???
??? 偽指令 SETA 、SETL 、SETS 用于給一個已經定義的全局變量或局部變量賦值。???
??? SETA偽指令用于給一個數學變量賦值;???
??? SETL偽指令用于給一個邏輯變量賦值;???
??? SETS偽指令用于給一個字符串變量賦值;???
??? 當中,變量名為已經定義過的全局變量或局部變量,表達式為將要賦給變量的值。

???
??? 使用演示樣例:???
??? LCLA Test3 。???????????? 聲明一個局部的數字變量,變量名為 Test3。???
??? Test3 SETA 0xaa 。??? 將該變量賦值為0xaa。???
??? LCLL Test4 ;???????????? 聲明一個局部的邏輯變量。變量名為 Test4。???
??? Test4 SETL {TRUE} ;將該變量賦值為真。

???

4 、RLIST???
??? 語法格式:???
??? 名稱 RLIST { 寄存器列表 }???
??? RLIST偽指令可用于對一個通用寄存器列表定義名稱,使用該偽指令定義的名稱可在ARM 指令 LDM/STM中使用。在LDM/STM指令中,列表中的寄存器訪問次序為依據寄存器的編號由低到高。而與列表中的寄存器排列次序無關。

???
??? 使用演示樣例:???

??? RegList RLIST {R0-R5 。R8 ,R10} 。將寄存器列表名稱定義為 RegList 。可在ARM指令LDM/STM中通過該名稱訪問寄存器列表。???


二、數據定義(Data Definition)偽指令????


數據定義偽指令一般用于為特定的數據分配存儲單元,同一時候可完畢已分配存儲單元的初始化。????
常見的數據定義偽指令有例如以下幾種:???
??? — DCB 用于分配一片連續的字節存儲單元并用指定的數據初始化。

???
??? — DCW(DCWU)用于分配一片連續的半字存儲單元并用指定的數據初始化。

???
??? — DCD (DCDU)用于分配一片連續的字存儲單元并用指定的數據初始化。???
??? — DCFD(DCFDU)用于為雙精度的浮點數分配一片連續的字存儲單元并用指定的數據初始化。???
??? — DCFS(DCFSU)用于為單精度的浮點數分配一片連續的字存儲單元并用指定的數據初始化。???
??? — DCQ(DCQU)用于分配一片以8字節為單位的連續的存儲單元并用指定的數據初始化。

???
??? — SPACE 用于分配一片連續的存儲單元。???
??? — MAP 用于定義一個結構化的內存表首地址。???

??? — FIELD 用于定義一個結構化的內存表的數據域。???


1、DCB???
??? 語法格式:???
??? 標號 DCB 表達式???
??? DCB偽指令用于分配一片連續的字節存儲單元并用偽指令中指定的表達式初始化。當中,表達式能夠為0~255的數字或字符串。

DCB 也可用“=”取代。???
??? 使用演示樣例:???
??? Str DCB “This is a test” ;分配一片連續的字節存儲單元并初始化。
???
2、DCW(或DCWU)???
??? 語法格式:
??? 標號 DCW (或DCWU) 表達式???
??? DCW(或DCWU)偽指令用于分配一片連續的半字存儲單元并用偽指令中指定的表達式初始化。???
??? 當中。表達式能夠為程序標號或數字表達式。??
??? 用DCW分配的字存儲單元是半字對齊的。而用DCWU分配的字存儲單元并不嚴格半字對齊。

???
??? 使用演示樣例:???
??? DataTest DCW 1 ,2 。3 。分配一片連續的半字存儲單元并初始化。????

3、DCD(或DCDU)???
??? 語法格式:???
??? 標號 DCD(或DCDU) 表達式???
??? DCD(或DCDU)偽指令用于分配一片連續的字存儲單元并用偽指令中指定的表達式初始化。當中。表達式能夠為程序標號或數字表達式。DCD也可 用"&” 取代。???
??? 用DCD分配的字存儲單元是字對齊的。而用DCDU分配的字存儲單元并不嚴格字對齊。

???
??? 使用演示樣例:???
??? DataTest DCD 4 ,5 ,6 。分配一片連續的字存儲單元并初始化。


???
4、DCFD(或DCFDU)???
??? 語法格式:???
??? 標號 DCFD(或DCFDU) 表達式???
??? DCFD(或DCFDU)偽指令用于為雙精度的浮點數分配一片連續的字存儲單元并用偽指令中指定的表達式初始化。每一個雙精度的浮點數占領兩個字單元。

用 DCFD分配的字存儲單元是字對齊的。而用DCFDU分配的字存儲單元并不嚴格字對齊。???
??? 使用演示樣例:?????? FDataTest DCFD 2E115 ,-5E7 ;分配一片連續的字存儲單元并初始化 為指定的雙精度數。????

5、DCFS(或DCFSU)???
??? 語法格式:???
??? 標號 DCFS(或DCFSU) 表達式???
??? DCFS(或DCFSU)偽指令用于為單精度的浮點數分配一片連續的字存儲單元并用偽指令中指定的表達式初始化。每一個單精度的浮點數占領一個字單元。用 DCFS分配的字存儲單元是字對齊的。而用DCFSU分配的字存儲單元并不嚴格字對齊。

???
??? 使用演示樣例:???
??? FDataTest DCFS 2E5 ,-5E -7 。分配一片連續的字存儲單元并初始化為 指定的單精度數。????

6、DCQ(或DCQU)???
??? 語法格式:???
??? 標號 DCQ(或DCQU) 表達式???
??? DCQ(或DCQU)偽指令用于分配一片以8個字節(雙字)為單位的連續存儲區域并用偽指令中指定的表達式 初始化。 用DCQ分配的存儲單元是字對齊的,而用DCQU 分配的存儲單元并不嚴格字對齊。

???
??? 使用演示樣例:???
??? DataTest DCQ 100 ;分配一片連續的存儲單元并初始化為指定的值。
???
7、SPACE ??
??? 語法格式:???
??? 標號 SPACE 表達式???
??? SPACE偽指令用于分配一片連續的存儲區域并初始化為0 。當中,表達式為要分配的字節數。???
??? SPACE也可用“ % ”取代。???
??? 使用演示樣例:???
??? DataSpace SPACE 100 ;分配連續100字節的存儲單元并初始化為0 。

????

8、MAP???
??? 語法格式:???
??? MAP 表達式 { 。基址寄存器 }???
??? MAP偽指令用于定義一個結構化的內存表的首地址。MAP也可用“^” 取代。

???
??? 表達式能夠為程序中的標號或數學表達式,基址寄存器為可選項,當基址寄存器選項不存在時,表達式的值即為內存表的首地址。當該選項存在時。內存表的首地址 為表達式的值與基址寄存器的和。

???
??? MAP偽指令通常與FIELD偽指令配合使用來定義結構化的內存表。???
??? 使用演示樣例:???
??? MAP 0x100 ,R0 。定義結構化內存表首地址的值為0x100+R0 。
???
9、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。???
三、匯編控制(Assembly Control)偽指令????
匯編控制偽指令用于控制匯編程序的運行流程,經常使用的匯編控制偽指令包含下面幾條:???
??? — IF 、ELSE 、ENDIF???
??? — WHILE 、WEND???
??? — MACRO 、MEND???

??? — MEXIT


1、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????

2、WHILE、WEND???
??? 語法格式:???
??? WHILE 邏輯表達式???
??? 指令序列???
??? WEND???
??? WHILE 、WEND偽指令能依據條件的成立與否決定是否循環運行某個指令序列。當WHILE后面的邏輯表達式為真,則運行指令序列,該指令序列運行完成后。再推斷 邏輯表達式的值,若為真則繼續運行。一直到邏輯表達式的值為假。???
??? WHILE 、WEND偽指令能夠嵌套使用。???
??? 使用演示樣例:???
??? GBLA Counter ;?? 聲明一個全局的數學變量。變量名為Counter???
??? Counter SETA 3 。由變量Counter 控制循環次數???
??? ……???
??? WHILE Counter < 10???
??? 指令序列???

??? WEND????


3、MACRO、MEND???
??? 語法格式:???
??? $ 標號 宏名 $ 參數 1 。$ 參數 2 ,……???
??? 指令序列???
??? MEND???
??? MACRO 、MEND偽指令能夠將一段代碼定義為一個總體,稱為宏指令。然后就能夠在程序中通過宏指令多次調用該段代碼。當中,$標號在宏指令被展開時,標號會被替 換為用戶定義的符號。宏指令能夠使用一個或多個參數,當宏指令被展開時。這些參數被對應的值替換。???
??? 宏指令的使用方式和功能與子程序有些相似,子程序能夠提供模塊化的程序設計、節省存儲空間并提高執行速度。但在使用子程序結構時須要保護現場,從而添加了 系統的開銷。因此,在代碼較短且須要傳遞的參數較多時。能夠使用宏指令取代子程序。???
??? 包括在MACRO和MEND之間的指令序列稱為宏定義體,在宏定義體的第一行應聲明宏的原型(包括宏名、所需的參數),然后就能夠在匯編程序中通過宏名來 調用該指令序列。在源程序被編譯時,匯編器將宏調用展開,用宏定義中的指令序列取代程序中的宏調用,并將實際參數的值傳遞給宏定義中的形式參數。???
??? MACRO、MEND偽指令能夠嵌套使用。???

4、MEXIT???
??? 語法格式:???
??? MEXIT???

??? MEXIT用于從宏定義中跳轉出去。

??


四、其它經常使用的偽指令????


另一些其它的偽指令,在匯編程序中常常會被使用,包含下面幾條:????
??? — AREA
??? — ALIGN???
??? — CODE16 、CODE32???
??? — ENTRY???
??? — END???
??? — EQU???
??? — EXPORT(或GLOBAL )???
??? — IMPORT???
??? — EXTERN???
??? — GET(或INCLUDE )???
??? — INCBIN???
??? — RN???

??? — ROUT????


1、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 ,屬性為僅僅讀。????

2、ALIGN???
??? 語法格式:???
??? ALIGN { 表達式 { 。偏移量 }}???
??? ALIGN偽指令可通過加入填充字節的方式,使當前位置滿足一定的對齊方式。當中。表達式的值用于指定對齊方式,可能的取值為2的冪。如1 、2 、4 、8 、16 等。

若未指定表達式。則將當前位置對齊到下一個字的位置。

偏移量也為一個數字表達式,若使用該字段,則當前位置的對齊方式為:2的表達式次冪+偏移 量。

???
??? 使用演示樣例:???
??? AREA Init 。CODE ,READONLY ,ALIEN=3 ;指定后面的指令為8 字節對齊。

???
??? 指令序列???
??? END????

3、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 。
???
4、ENTRY???
??? 語法格式:???
??? ENTRY???
??? ENTRY偽指令用于指定匯編程序的入口點。

在一個完整的匯編程序中至少要有一個ENTRY(也能夠有多個,當有多個ENTRY時。程序的真正入口點由鏈 接器指定)。但在一個源文件中最多僅僅能有一個ENTRY(能夠沒有)。???
??? 使用演示樣例:???
??? AREA Init ,CODE ,READONLY???
??? ENTRY ; 指定應用程序的入口點???
??? ……????
5、END???
??? 語法格式:???
??? END???
??? END偽指令用于通知編譯器已經到了源程序的結尾。???
??? 使用演示樣例:???
??? AREA Init ,CODE ,READONLY???
??? ……??
??? END ;指定應用程序的結尾???

6、EQU???
??? 語法格式:???
??? 名稱 EQU 表達式 { ,類型 }???
??? EQU偽指令用于為程序中的常量、標號等定義一個等效的字符名稱,類似于C語言中的#define 。當中EQU可用“*”取代。名稱為EQU偽指令定義的字符名稱。當表達式為32位的常量時,能夠指定 表達式的數據類型,能夠有下面三種類型:???
??? CODE16 、CODE32 和DATA???
??? 使用演示樣例:???
??? Test EQU 50 。?????????????????????? 定義標號Test 的值為50。???
??? Addr EQU 0x55 ,CODE32 。 定義Addr的值為0x55 。且該處為32位的ARM指令。

????

7、EXPORT(或GLOBAL)???
??? 語法格式:???
??? EXPORT 標號 {[WEAK]}???
??? EXPORT偽指令用于在程序中聲明一個全局的標號,該標號可在其它的文件里引用。EXPORT 可用GLOBAL取代。標號在程序中區分大寫和小寫。[WEAK] 選項聲明其它的同名標號優先于該標號被引用。

???
??? 使用演示樣例:???
??? AREA Init ,CODE ,READONLY???
??? EXPORT Stest 。聲明一個可全局引用的標號Stest???

??? END????


8、IMPORT???
??? 語法格式:???
??? IMPORT 標號 {[WEAK]}???
??? IMPORT偽指令用于通知編譯器要使用的標號在其它的源文件里定義,但要在當前源文件里引用,并且不管當前源文件是否引用該標號。該標號均會被增加到當前源文件的符號表中。標 號在程序中區分大寫和小寫,[WEAK] 選項表示當全部的源文件都未定義這樣一個標號時。編譯器也不給出錯誤信息。在多數情況下將該標號置為0 ,若該標號為B或BL指令引用,則將B或BL指令置為NOP操作。???
??? 使用演示樣例:???
??? AREA Init ,CODE ,READONLY???
??? IMPORT Main ;通知編譯器當前文件要引用標號Main。但Main在其它源文件里定 義。


??? END????

9、EXTERN???
??? 語法格式:???
??? EXTERN 標號 {[WEAK]}???
??? EXTERN偽指令用于通知編譯器要使用的標號在其它的源文件里定義,但要在當前源文件里引用,假設當前源文件實際并未引用該標號,該 標號就不會被增加到當前源文件的符號表中。標號在程序中區分大寫和小寫, [WEAK] 選項表示當全部的源文件都未定義這樣一個標號時。編譯器也不給出錯誤信息。在多數情況下將該標號置為0 ,若該標號為B或BL指令引用,則將B或BL指令置為NOP操作。???
??? 使用演示樣例:???
??? AREA Init 。CODE 。READONLY???
??? EXTERN Main ;通知編譯器當前文件要引用標號Main,但Main在其它源文件里定 義。

???
??? END????

10、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????


11、INCBIN???
??? 語法格式:???
??? INCBIN 文件名稱???
??? INCBIN偽指令用于將一個目標文件或數據文件包括到當前的源文件里,被包括的文件不作不論什么變動的存放在當前文件里,編譯器從其后開始繼續處理。???
??? 使用演示樣例:???
??? AREA Init ,CODE ,READONLY???
??? INCBIN a1.dat ;???? 通知編譯器當前源文件包括文件a1.dat???
??? INCBIN C:\a2.txt ;通知編譯器當前源文件包括文件C:\a2.txt??
??? END????

12、RN???
??? 語法格式:???
??? 名稱 RN 表達式???
??? RN偽指令用于給一個寄存器定義一個別名。採用這樣的方式能夠方便程序猿記憶該寄存器的功能。當中,名稱為給寄存器定義的別名,表達式為寄存器的編碼。??
??? 使用演示樣例:???
??? Temp RN R0 ;將R0定義一個別名Temp????

13、ROUT??
??? 語法格式:???
??? {名稱} ROUT???
??? ROUT偽指令用于給一個局部變量定義作用范圍。

在程序中未使用該偽指令時,局部 變量的作用范圍為所在的AREA,而使用ROUT后,局部變量的作為范圍為當前ROUT和下一個ROUT之間。
?
?3. BNE 與? BEQ
TST???? R0, #0X8
BNE??? SuspendUp 。BNE指令是“不相等(或不為0)跳轉指令”:
LDR?? R1,#0x00000000
先進行and運算。假設R0的第四位不為1,則結果為零。則設置zero=1(繼續以下的LDR指令);
否則。假設R0的第四位為1。zero=0(跳到SuspendUp處運行)。
tst 和bne連用: 先是用tst進行位與運算。然后將位與的結果與0比較,假設不為0,則跳到bne緊跟著的標記(如bne sleep,則跳到sleep處)。


tst 和beq連用: 先是用tst進行位與運算。然后將位與的結果與0比較。假設為0,則跳到beq緊跟著的標記(如bne AAAA,則跳到AAAA處)。


轉載于:https://www.cnblogs.com/mengfanrong/p/5239930.html

總結

以上是生活随笔為你收集整理的经常使用ARM汇编指令的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。