ARM體系結構與介面技術——ARM指令集
阿新 • • 發佈:2022-04-17
ARM彙編框架
xx.s
.text @表示當前為程式碼段 .global _start @將_start定義成全域性符號 _start: @彙編的入口 MOV R1,#1 MOV R2,#2 MOV R3,#3 .end @彙編的結束
ARM彙編概述
彙編中的符號
- 指令:能夠編譯成一條32位的機器碼,並且能被CPU識別和執行。
- 偽指令:本身不是指令,編譯器可以將其替換成若干條指令
- 不會生成指令,只是在編譯階段告訴編譯器怎麼編譯,類似C語言的條件編譯
ARM的指令
- 資料處理指令:進行數學運算、邏輯運算
- 跳轉指令:實現程式的跳轉,本質就是修改PC暫存器
- Load/Store指令:訪問(讀寫)記憶體
- 狀態暫存器傳送指令:用於訪問(讀寫)CPSR暫存器
- 軟中斷指令:觸發軟中斷
- 協處理器指令:操作協處理器的指令
指令基本格式
<操作碼> <目標暫存器>, <第一操作暫存器>, <第二運算元>
ARM指令集
資料處理指令
.text .global _start _start: @ 資料搬運指令 MOV R1,#1 @把一個數搬運到一個暫存器 MOV R2,R1 @從一個暫存器搬運到另一個暫存器 MVN R0,#0xFF @按位取反再搬運 @MOV PC,#0 @搬運一個數到PC暫存器,程式會跳轉 @ 立即數,本質是包含在指令中的數,屬於指令的一部分 @ 所以立即數不能太大,範圍在0-255之間。 @ MOV R0, #0x12345678 @0x12345678這不是立即數,不能被編譯成功 @ 0xFFFFFFFF這不是立即數,但是能被編譯成功 @ 這一條是偽指令,編譯器會把他替換成同樣效果的指令。 MOV R0, #0xFFFFFFFF @ MVN R0,#0x00 @ 加法指令 ADD R3,R1,R2 @ R3 = R1 + R2ADD R3,R2,#5 @ R3 = R2 + 5 @ 不合法的指令 @ ADD R3,#5,R2 @第一暫存器不能放數 @ 減法指令 SUB R1,R2,R3 @ R1 = R2 - R3 RSB R1,R2,#3 @ R1 = 3 - R2 逆向減法指令 @ 乘法指令 MUL R1,R2,R3 @ R1 = R2 * R3 @ 按位與 AND R1,R2,R3 @ R1 = R2 & R3 @ 按位或 ORR R1,R2,R3 @ R1 = R2 | R3 @ 按位異或 EOR R1,R2,R3 @ R1 = R2 ^ R3 @ 移位 LSL R1,R2,R3 @ R1 = R2 << R3, R2左移R3位,給R1 LSR R1,R2,R3 @ R1 = R2 >> R3, R2右移R3位,給R1 @ 位清零 BIC R1, R2, #0xF @ 第二運算元(0xF)中的哪一位,就將第一操作暫存器中的哪一位清零,然後放入目標暫存器 @ 資料運算指令的格式擴充套件 MOV R1,R2,LSL #1 @ R1 = (R2 << 1) @ 資料運算指令對條件位的影響,CPSR NZVC @ 預設情況下資料運算不會對條件為產生影響,當指令加字尾S後可以影響 MOV R1,#3 SUBS R2,R1,#5 @ 兩個64位的資料做加法運算 @ 0x00000001 FFFFFFFF @ 0x00000002 00000005 MOV R1,#0xFFFFFFFF MOV R2,#0x00000001 MOV R3,#0x00000005 MOV R4,#0x00000002 ADDS R5,R1,R3 @溢位時條件位溢位位會自動置1 ADC R6,R2,R4 @ R6 = R2 + R4 + 'C',在執行的過程中,會把條件位的溢位位加上 @ 帶借位的減法指令 @ 0x00000002 00000001 @ 0x00000001 00000005 MOV R1,#0x00000001 MOV R2,#0x00000002 MOV R3,#0x00000005 MOV R4,#0x00000001 SUBS R5,R1,R3 SBC R6,R2,R4 @ 本質: R6 = R2 - R4 - '!C',即執行的過程中,會把條件位的溢位位取反再減 stop: B stop .end
跳轉指令
.text .global _start _start: @ 方式一:直接去修改PC暫存器的值 @ MOV R1,#1 @ MOV R2,#2 @ MOV R3,#3 @ MOV PC,#0x18 @ MOV R4,#4 @ 這條指令被跳過 @ MOV R6,#6 @ 方式二:通過跳轉指令B @ 本質也是修改PC @ MOV PC,LR 跳轉失敗,它會跳轉回:跳轉指令,因為B跳轉指令,沒有儲存返回地址給LR @MAIN: @ MOV R1,#1 @ B FUNC @ MOV R2,#2 @ MOV R3,#3 @FUNC: @ MOV R4,#4 @ MOV PC,LR @ 方式三:通過跳轉指令BL @ 跳轉的同時,會修改CPSR的跳轉狀態位的值,並且儲存返回的地址給LR MAIN: MOV R1,#1 MOV R2,#2 BL FUNC MOV R3,#3 MOV R4,#4 FUNC: MOV R5,#5 MOV PC,LR stop: B stop .end
ARM條件碼(不算指令)
@條件碼 .text .global _start _start: MAIN: MOV R1,#1 MOV R2,#1 @比較指令 CMP R1,R2 @沒有目標暫存器,結果自動儲存在狀態暫存器CPSR的NZCV @本質就是一條減法指令,SUBS,只是沒有將運算的結果存入暫存器 @如果R1==R2,Z=1,產生0 @如果R1!=R1,Z=0 @如果R1<R2,Z=0且C=0,產生了借位 @如果R1<=R2,C=0或Z=1 @如果R1>R2,C=1且Z=0 @如果R1>=R2,C=1或Z=1 BEQ FUNC @EQ是一個條件碼助記符字尾,大多數指令都可以加字尾 MOV R3,#3 @該條指令會被跳過 FUNC: MOV R4,#4 @程式會跳轉到這裡 .end
ARM條件碼和助記符字尾
ARM記憶體訪問指令
記憶體訪問指令1
@記憶體訪問指令 .text .global _start _start: @ 寫記憶體 MOV R1,#0xFFFFFFFF MOV R2,#0x40000000 @0x40000000 是可讀可寫的記憶體地址 @STR R1,[R2] @把R1暫存器中的資料儲存到R2指向的記憶體空間4個位元組 STRB R1,[R2] @把R1暫存器中的資料儲存到R2指向的記憶體空間 @ 讀記憶體 LDR R3,[R2] @把R2指向的記憶體空間的資料讀取到R3 .end
ARM指令的定址方式
@ ARM定址方式 .text .global _start _start: @ 方式一:立即定址 @ 回顧一下立即數,立即定址即直接使用指令機器碼中的立即數 MOV R1,#1 ADD R1,R2,#1 @ 方式二:暫存器取址 ADD R1,R2,R3 @ 方式三:暫存器移位定址 MOV R1,R2, LSL #1 @ 方式四:暫存器間接定址 STR R1, [R2] @...還有很多,ARM一共九種 .end
記憶體訪問指令2
@ 記憶體訪問指令2 @ 基於ARM指令的定址方式 @ 基址加變址定址 .text .global _start _start: MOV R1, #0xFFFFFFFF MOV R2, #0x40000000 MOV R3, #4 @ 前索引: @STR R1, [R2,#4] @ 將R1暫存器中的資料寫入到R2+4指向的記憶體空間:0x40000004 @ R2的值並不會改變,對比自動索引 @STR R1, [R2,R3] @ 將R1暫存器中的資料寫入到R2+R3指向的記憶體空間:0x40000004 @STR R1, [R2,R3,LSL #1] @ 將R1暫存器中的資料寫入到R2+(R3<<1)指向的記憶體空間:0x40000008 @***************************************************************** @ 後索引: STR R1, [R2], #8 @ 將R1暫存器中的資料寫入到R2指向的記憶體空間:0x40000000 @ 然後R2自增8 @ 自動索引: STR R1, [R2,#8]! @ 將R1暫存器中的資料寫入到R2+8指向的記憶體空間:0x40000008 @ 然後R2自增8 .end
END