1.49k likes | 1.7k Views
第 六 章 ARM 微處理器的指令集. DMATEK CO.,LTD 深圳市長高科技有限公司. 本章節將對 ARM 指令集中的六大類指令進行詳細的說明與描述。 本章的主要內容有: - 介紹跳躍指令 - 說明資料處理指令 - 介紹乘法相關指令 - 介紹程式狀態存取指令 - 說明載入與儲存指令 - 資料交換指令 - 位移位元指令 - 輔助運算器操作指令 - 異常產生指令 - 介紹虛擬指令. 6-1 跳躍指令 : 跳躍指令用於實現程式流程的跳躍,在 ARM 程式中有兩種方法可以實現程式流程的跳躍: — 使用專門的跳躍指令。
E N D
第六章ARM微處理器的指令集 DMATEK CO.,LTD 深圳市長高科技有限公司
本章節將對ARM指令集中的六大類指令進行詳細的說明與描述。本章節將對ARM指令集中的六大類指令進行詳細的說明與描述。 本章的主要內容有: - 介紹跳躍指令 - 說明資料處理指令 - 介紹乘法相關指令 - 介紹程式狀態存取指令 - 說明載入與儲存指令 - 資料交換指令 - 位移位元指令 - 輔助運算器操作指令 - 異常產生指令 - 介紹虛擬指令
6-1 跳躍指令: • 跳躍指令用於實現程式流程的跳躍,在ARM程式中有兩種方法可以實現程式流程的跳躍: —使用專門的跳躍指令。 —直接向程式計數器PC寫入跳躍位址值。 • 透過向PC程式計數器寫入跳躍位址值,可以實現在4GB的位址空間中的任意跳躍,在跳躍之前結合使用,如MOV LR,PC等類似指令,可以保存儲存將來的返回位址值,從而實現在4GB連續的線性位址空間的副程式的呼叫使用。 • ARM指令集中的跳躍指令可以完成從當前指令向前或向後的32MB的位址空間的跳躍,包括以下4條指令:
■ B,Branch,跳躍指令 ■ BL,Branch with Link,包含返回的跳躍指令,也即是呼叫副程式。 ■ BLX,Branch and Exchange Instruction Set包含返回和狀態切換的跳躍指令 ■ BX,Branch with Link and Exchange Instruction Set,包含狀態切換的跳躍指令 以下,稍微介紹這幾個指令: • B指令 • B指令的格式為: • B{條件} 目標位址
B指令是最簡單的跳躍指令。一旦遇到一個 B指令,ARM 處理器將立即跳躍到所設定的目的位址,並從那裏繼續執行。注意到,儲存在跳躍指令中的實際值是相對當前PC值的一個偏移量,而不是一個絕對位址,這個值可由組譯器來計算出來(參考定址方式中的相對定址)。而其是 24 位元有號數,在左移兩位元後,有號數擴展為 32 位,且增加至PC的值上,因此,這個指令可以設定32表示的有效偏移為 26 位(前後32MB的位址空間)。以下指令: B Label ;程式無條件跳躍到標號Label處執行 CMP R1,#0 ;當CPSR暫存器中的Z條件碼置位元時, 程 式跳躍到標號Label處執行 BEQLabel
1. BL指令 BL指令的格式為: BL{條件} 目標位址 BL 是另一個跳躍指令,但跳躍之前,會在暫存器R14中保存儲存PC的當前內容,因此,可以透過將R14 的內容重新載入到PC中,來返回到跳躍指令之後的那個指令處執行。該指令是實現副程式調用的一個基本但常用的手段。以下指令: BL Label ;當程式無條件跳躍到標號Label處執行時,同時將當前的PC值保存儲存到R14中
2. BLX指令 BLX指令的格式為: BLX 目標位址 BLX指令從ARM指令集跳躍到指令中所指定的目標位址,並將處理器的工作狀態有ARM狀態切換到Thumb狀態,該指令同時將PC的當前內容保存儲存到暫存器R14中。因此,當副程式使用Thumb指令集,而調用者使用ARM指令集時,可以透過BLX指令實現副程式的調用和處理器工作狀態的切換。同時,副程式的返回可以透過將暫存器R14值複製到PC中來完成。
3. BX指令 BX指令的格式為: BX{條件} 目標位址 BX指令跳躍到指令中所指定的目標位址,目標位址處的指令既可以是ARM指令,也可以是Thumb指令。 接下來我們利用ADS及AXD來測試BL的指令,如下圖6-1所示,當執行到BL時,會跳到Delay裡面的副程式,而沒去執行圖中第8行,等副程式執行完畢後,才會再跳回主程式接第8行繼續執行下去。圖6-1第7行,副程式執行完畢,跳回主程式的語法。
圖6-1執行BL程式指令結果示意圖 BL執行前 BL執行後
6-2 資料處理指令: • 資料的算術運算指令和資料處理指令的特徵是兩個運算元一起經過運算,產生一個結果,指令執行影響旗標暫存器。資料的算術運算要求有兩個運算元,規定一個運算元的尋址方式必須是暫存器類型,另一個可以是暫存器類型、常數類型或者移位元定址方式。 • ARM的資料處理指令可分為資料傳送指令、算術邏輯運算指令、比較測試指令、乘法與乘加指令等。 • 資料傳送指令用於在暫存器和記憶體之間進行資料的雙向傳輸。 • 算術邏輯運算指令完成常用的算術與邏輯的運算,該類指令不但將運算結果保存儲存在目的暫存器中,同時更新CPSR中的相應條件旗標位元。 • 比較測試指令不保存儲存運算結果,只更新CPSR中相應的條件旗標位元。 • 乘法指令與乘加指令可分為運算結果為32位和運算結果為64位兩類,與前面的資料處理指令不同,指令中的所有運算元、目的暫存器必須為通用暫存器,不能對運算元使用常數或被移位的暫存器,同時,目的暫存器和運算元1必須是不同的暫存器。
資料處理指令包括: — MOV 資料傳送指令 — MVN 資料取補數傳送指令 — CMP 比較指令 — CMN 反值比較指令 — TST 位元測試指令 — TEQ 相等測試指令 — ADD 加法指令 — ADC 帶進位元加法指令 — SUB 減法指令 — SBC 帶借位減法指令 — RSB 逆向減法指令 — RSC 帶借位的逆向減法指令 — AND 邏輯AND指令 — ORR 邏輯OR指令 — EOR 邏輯異或指令 — BIC 位元清除指令
1. MOV指令 MOV指令的格式為: MOV{條件}{S}目的暫存器,源運算元來源運算元 MOV指令的功能為: MOV指令可完成從另一個暫存器、被移位的暫存器或將一個常數載入到目的暫存器。如果指令中使用兩個相同的暫存器,指令的作用則相當於NOP的功能。指令中S選項決定指令的操作是否影響CPSR中條件旗標位元的值,當沒有S時指令不更新CPSR中條件旗標位元的值。
指令示例: MOV R1, R0 ;將暫存器R0的值傳送到暫存器R MOV PC, R14 ;將暫存器R14的值傳送到PC,常用於副程式返回 MOV R1, R0, LSL#3 ;將暫存器R0的值左移3位後傳送到R1 旗標位元: 如果指令中設置S位元,執行時則設置N和Z旗標;並且如果使用移位元定址方式,則C旗標位元設置為被移出的最後一位;本指令執行不影響V旗標。 使用AXD執行MOV指令產生的結果,如下圖6-2所示,第5行指令,是將0x1234的數值寫到R0暫存器,然後執行6行MOV的指令,將R0的值傳送到R1,所以在執行MOV後,可以從下圖6-2可以看到R0的值傳送到R1的暫存器位置。
圖6-2執行MOV程式指令結果示意圖 執行MOV前 執行MOV後
2. MVN指令 MVN指令的格式為: MVN{條件}{S}目的暫存器,源運算元來源運算元 MVN指令的功能為: MVN指令可完成從另一個暫存器、被移位的暫存器或將一個常數載入到目的暫存器。與MOV指令不同之處是在傳送之前按位元被取補數了,即把一個被取補數的值傳送到目的暫存器中。其中,S決定指令的操作是否影響CPSR中條件旗標位元的值,當沒有S時指令不更新CPSR中條件旗標位元的值。 指令示例: MVN R0, #0 ;將常數0取補數傳送到暫存器R0中,完成後R0=-1
旗標位元: 如果指令中設置S位元,執行時則影響N和Z旗標;並且如果使用移位元定址方式,則C旗標設置為被移出的最後一位;本指令執行不影響V旗標。 使用AXD執行MVN指令產生的結果,如下圖6-3所示,在執行第6行程式之前,R0的暫存器的值是0x00000000,沒有數值,執行第6行指令時,MVN會先取反向,所以執行完第6行程式,R0暫存器的值取反向為0XFFFFFFFF,如下圖6-3執行後的畫面。
圖6-3執行MOV程式指令結果示意圖 執行MVN前 執行MVN後
CMP指令 CMP指令的格式為: CMP{條件}運算元1,運算元2 CMP指令的功能為: CMP指令用於把一個暫存器的內容和另一個暫存器的內容或常數進行比較,同時更新CPSR中條件旗標位元的值。該指令進行一次減法運算,但不儲存結果,只更改條件旗標位元旗標位元表示的是運算元1與運算元2的關係(大、小、相等),例如,當運算元1大於操作運算元2時,則此後的有GT尾碼的指令將可以執行。顯然指令中不需要指定S尾碼即更改狀態旗標,如果設定S,尾碼則被忽略。
指令示例: CMP R1, R0 ;將暫存器R1的值與暫存器R0的值相減,並根據結果設置CPSR的旗標位元 CMP R1, #100 ;將暫存器R1的值與常數100相減,並根據結果設置CPSR的旗標位元 旗標位元: 指令執行結束設置N和Z位。 使用AXD執行CMP指令產生的結果,如下圖6-4所示,在執行前的CPSR的值是0x000000D3,將暫存器R1的值與R2的值相減,當執行完後,會根據結果來設定CPSR的條件旗標位元,所以值被改變如下0x200000D3。
圖6-4執行CMP指令結果示意圖 執行CMP前 執行CMP後
3. CMN指令 • CMN指令的格式為: CMN{條件}運算元1,運算元2 CMN指令的功能為: CMN指令用於把一個暫存器的內容和另一個暫存器的內容或常數取補數後進行比較,同時更新CPSR中條件旗標位元的值。該指令實際完成運算元1和運算元2相加,並根據結果更改條件旗標位元。 指令示例: CMN R1, R0 ;將暫存器Rl的值與暫存器R0的值相加,並根據結果設置CPSR的旗標位元 CMN R1, #100 ;將暫存器R1的值與常數100相加,並根據結果設置CPSR的旗標位元 旗標位元: 指令執行結束設置N和Z位。執行CMN後 使用AXD執行CMN指令產生的結果,如下圖6-5所示,在執行前的CPSR的值是0x000000D3,將暫存器R1的值與R2的值相加,當執行完後,會根據結果來設定CPSR的條件旗標位元,所以值被改變如下0x200000D3。
圖6-5執行CMN指令結果示意圖 執行CMN前 執行CMN後
4. TST指令 TST指令的格式為: TST{條件}運算元1,運算元2 TST指令的功能為: TST指令用於把一個暫存器的內容和另一個暫存器的內容或常數進行按位元與運算,並根據運算結果更新CPSR中條件旗標位元的值。運算元1是要測試的資料,而運算元2是一個位元遮罩,該指令一般用來檢測是否設置了特定的位。TST的S位總是設置的,也就是說,它總是影響旗標位元,不需要指定S尾碼。
指令示例: TST R1, #l ;用於測試在暫存器R1中是否設置了最低位元 TST R1, #0xffe ;將暫存器R1的值與常數0xffe按位元與,並根據結果設置CPSR的旗標位元 旗標位元: 在結果中設置N和Z旗標,如果使用移位元定址方式,則從它得到C旗標,不影響V旗標。 使用AXD執行TST指令產生的結果,如下圖6-6所示,在執行前的CPSR的值是0x000000D3,將暫存器R1的值與R2依序做AND邏輯運算,當執行完後,會根據結果來設定CPSR的條件旗標位元,所以值被改變如下0x400000D3。
圖6-6執行TST指令結果示意圖 執行TST前 執行TST後
5. TEQ指令 TEQ指令的格式為: TEQ{條件}運算元1,運算元2 TEQ指令的功能為: TEQ指令用於把一個暫存器的內容和另一個暫存器的內容或常數進行按位XOR運算,並根據運算結果更新CPSR中條件旗標位元的值。該指令通常用於比較運算元1和運算元2是否相等。 TEQ的作用與TST類似,區別是執行的計算是XOR,而不是AND。該指令提供了一種查看兩個運算元是否相同,而又不影響進位元旗標的方法。加上P尾碼的TEQ指令還可用於改變R15中的旗標(在26-bit模式中)。TEQ指令設置S位元。
指令示例: TEQ R1, R2 ;將暫存器R1的值與暫存器R2的值按位元XOR,並根據結果設置CPSR的旗標位元 旗標位元: 在結果中設置N和Z旗標,如果使用移位元定址方式,則從它得到C旗標,不影響V旗標 使用AXD執行TST指令產生的結果,如下圖6-7所示,在執行前的CPSR的值是0x000000D3,將暫存器R1的值與R2依序做XOR邏輯運算,當執行完後,會根據結果來設定CPSR的條件旗標位元,所以值被改變如下0x800000D3。
圖6-7執行TEQ指令結果示意圖 執行TEQ前 執行TEQ後
6. ADD指令 ADD指令的格式為: ADD{條件}{S}目的暫存器,運算元1,運算元2 ADD指令的功能為: 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) 旗標位元: 如果指令中使用S位元,指令執行結束則設置N和Z位,並從ALU獲取C和V旗標。 使用AXD執行ADD指令產生的結果,如下圖6-8所示,在執行前,R0暫存器的值0x0000000F,執行第6行執行,將R0暫存器的值加上0xF0放到R1的暫存器,所以執行完結果如下圖6-8執行後R1的暫存器的值為0x000000FF。
圖6-8執行ADD指令結果示意圖 執行ADD前 執行ADD後
7. ADC指令 ADC指令的格式為: ADC{條件}{S}目的暫存器,運算元1,運算元2 ADC指令的功能為: ADC指令用於把兩個運算元相加,再加上CPSR中的C條件旗標位元的值,並將結果存放到目的暫存器中。它使用一個進位元旗標位元,這樣就可以做比32位大的數的加法,注意,不要忘記設置S尾碼來更改進位元旗標。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。 以下指令序列完成兩個128位數的加法,第一個數由高到低存放在暫存器R7~R4,第二個數由高到低存放在暫存器Rll~R8,運算結果由高到低存放在暫存器R3~R0。
ADDS R0, R4, R8 ; 加低端的字 ADCS R1, R5, R9 ; 加第二個字,帶進位 ADCS R2, R6, R10 ; 加第三個字,帶進位 ADC R3, R7, R11 ; 加第四個字,帶進位 旗標位元: 如果指令中使用S位元,指令執行結束則設置N和Z位,並從ALU獲取C和V旗標。 使用AXD執行ADCS指令產生的結果,如下圖6-9所示,設置R0的值為0xFFFFFFFF,當執行ADCS第6行指令時,會將R0加上0xF0的值放到R1的位置,R1暫存器值改改為0x000000EF,CPSR的C旗標位的位元值,如下圖6-89所示,為0x200000D3。
圖6-9執行ADD指令結果示意圖 執行ADCS前 執行ADCS後 執行ADCS後
8. SUB指令 SUB指令的格式為: SUB{條件}{S}目的暫存器,運算元1,運算元2 SUB指令的功能為: 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) 旗標位元: 如果指令中使用S位元,指令執行結束則設置N和Z位,從ALU獲取C和V旗標。 使用AXD執行SUB指令產生的結果,如下圖6-10所示,執行前R0的暫存值的為0xFFFFFFFF,當執行第6行SUB的指令時,會將R0的值減去0XF0的數值,然後存放到R1的暫存器,執行SUB後,如下圖6-10執行後,R1暫存器的值為0XFFFFFF0F。
圖6-10執行SUB指令結果示意圖 執行SUB前 執行SUB後
9、SBC指令 SBC指令的格式為: SBC{條件}{S}目的暫存器,運算元1,運算元2 SBC指令的功能為: SBC指令用於把運算元l減去運算元2,再減去CPSR中的C條件旗標位元的反碼,並將結果存放到目的暫存器中。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令使用進位元旗標來表示借位,這樣就可以做大於32位的減法,注意,不要忘記設置S尾碼來更改進位元旗標。該指令可用於有符號數或無符號數的減法運算。 指令示例: SUBS R0, R1, R2 ;R0=R1.R2.!C,並根據結果設置CPSR的進位元旗標。
旗標位元: 如果指令中使用S位元,指令執行結束則設置N和Z位,從ALU獲取C和V旗標。 使用AXD執行SBCS指令產生的結果,如下圖6-11所示,執行前R0的暫存器為0x1234FFFF,設置CPSR的C旗標為1,然後執行SBCS第六行程式時,會將R0的暫存器值0x1234FFFF減去0xFFFFFFFF再減去C旗標位元的反值,並將結果存在R1中,執行結果如下圖6-11執行後所示,R1暫存器為0x12350000。
圖6-11執行SBCS指令結果示意圖 執行SBCS後
10、RSB指令 RSB指令的格式為: RSB{條件}{S}目的暫存器,運算元1,運算元2 RSB指令的功能為: RSB指令稱為逆向減法指令,用於把運算元2減去運算元1,並將結果存放到目的暫存器中。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令可用於有符號數或無符號數的減法運算。 指令示例: RSB R0, R1, R2 ;R0=R2-R1 RSB R0, R1, #256 ;R0=256-R RSB R0, R2, R3, LSL#1 ;R0=(R3<<1)-R2 旗標位元: 如果指令中使用S位元,指令執行結束則設置N和Z位,從ALU獲取C和V旗標。 使用AXD執行RSB指令產生的結果,如下圖6-12所示,R0暫存器的值為0x00000002,執行第6行RSB程式後,會將#250的值減去R0的值,丟到R1的暫存器中,而執行結果R1的暫存器的值即為0x000000F8。
圖6-12執行RSB指令結果示意圖 執行RSB前 執行RSB後
11、RSC指令 RSC指令的格式為: RSC{條件}{S}目的暫存器,運算元1,運算元2 RSC指令的功能為: RSC指令用於把運算元2減去運算元1,再減去CPSR中的C條件旗標位元的反碼,並將結果存放到目的暫存器中。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令使用進位元旗標來表示借位,這樣就可以做大於32位的減法,注意,不要忘記設置S尾碼來更改進位元旗標。該指令可用於有符號數或無符號數的減法運算。 指令示例: RSC R0, Rl, R2 ;R0=R2-R1-!C 旗標位元: 如果設置S位元,指令執行結束則設置N和Z位,從ALU獲取C和V旗標。 使用AXD執行RSCS指令產生的結果,如下圖6-13所示,R0暫存器的值為I0x000000FF,執行第6行程式時,#0數值會減去R0,再減去CPRS中的C旗標位元的反值,在儲存於R1的暫存器中,執行後R1的值為0XFFFFFF00,RSCS的N就表示借示的值。
圖6-13執行RSCS指令結果示意圖 執行RSCS前 執行RSCS後 執行RSCS後
13、AND指令 AND指令的格式為: AND{條件}{S}目的暫存器,運算元1,運算元2 AND指令的功能為: AND指令用於在兩個運算元上進行邏輯與運算,並把結果存放到目的暫存器中。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令常用於遮罩運算元1的某些位。 指令示例: AND R0, R0, #3 ;該指令保持R0的位元0、1,其餘位清為零 旗標位元: 如果指令中使用S位元,指令執行結束則更改N和Z位元,C旗標位元從使用的移位器中得到,不影響V旗標。 使用AXD執行指令AND產生的結果,如下圖6-14所示,執行前R0暫存器為0x000000FF,執行第6行程式時,R0與#3做AND的邏輯運算,執行後將資料儲存在R0,所以暫存器R0的值為執行後的結果為0x00000003。
圖6-14執行AND指令結果示意圖 執行AND前 執行AND後
13、ORR指令 ORR指令的格式為: ORR{條件}{S}目的暫存器,運算元1,運算元2 ORR指令的功能為: ORR指令用於在兩個運算元上進行邏輯或運算,並把結果存放到目的暫存器中。運算元l應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令常用於設置運算元1的某些位。 指令示例: ORR R0, R0, #3 ;該指令設置R0的位元0、1,其餘位保持不變 旗標位元: 如果指令中使用S位元,指令執行結束則更改N和Z位元,C旗標位元從使用的移位器中得到,不影響V旗標。 使用AXD執行指令ORR產生的結果,如下圖6-15所示,執行前R0暫存器的值0x000000FF,執行第6行ORR指令時,R0與#0x300做OR的邏輯運算,並將執行結果回傳儲存於R0暫存器中,執行後 R0暫存器的值為0x000003FF。
圖6-15執行ORR指令結果示意圖 執行ORR前 執行ORR後
14、EOR指令 EOR指令的格式為: EOR{條件}{S}目的暫存器,運算元1,運算元2 EOR指令的功能為: EOR指令用於在兩個運算元上進行邏輯XOR運算,並把結果存放到目的暫存器中。運算元1應是一個暫存器,運算元2可以是一個暫存器、被移位的暫存器或一個常數。該指令常用於反轉運算元1的某些位。 指令示例: EOR R0, R0, #3 ;該指令反轉R0的0、1位元,其餘位元保持不變 旗標位元: 如果指令中使用S位元,指令執行結束則更改N和Z位元,C旗標位元從使用的移位器中得到,不影響V旗標。 使用AXD執行指令EOR產生的結果,如下圖6-16所示,執行前R0暫存器的值0x000000FF,執行第6行EOR指令時,R0與#3進行XOR的邏輯運算,並將執行結果回傳儲存於R0暫存器中,執行後 R0暫存器的值為0x000000F
圖6-16執行EOR指令結果示意圖 執行EOR前 執行EOR後