1. 程式人生 > >專題3-ARM彙編指令詳解

專題3-ARM彙編指令詳解

1、彙編概述

1)為什麼要學習使用匯程式設計序?

bootloader在硬體初始化(啟動程式碼)時用的組合語言,因為效率更高。linux核心中某些對執行效率要特殊要求的地方也會使用匯編語言。

2)ARM彙編分類

目前常用的ARM彙編指令有兩種:
(1)ARM標準彙編:適用於ARM公司的彙編器,適合在windows平臺上使用,如ADS中使用。MOV:指令是大寫的

(2)GNU彙編:適用於GNU交叉編譯工具鏈中的彙編器,適合於linux平臺開發。mov:指令是小寫的

(3)彙編程式框架
這裡寫圖片描述
_start:表示程式的入口(表明屬於資料段.section .text ;簡潔的彙編程式碼可以省去.section)
要用.global全域性變數來修飾
然後編寫一個簡單的start.S和Makefile,用eclipse類似實現簡單的除錯。
start.S:

.text
.global _start
_start:
@mov指令範例  在彙編中是用@來註釋的
    mov r1,#1
    mov r2:#2
    mov r3,#3

Makefile:

all:start.o
    arm-linux-ld -Ttext 0x30000000 -o start.elf $^
%.o:%.S
    arm-linux-gcc -g -o [email protected] s^ -c
clean:
    rm *.o *.elf

注意上面連結器引數的使用:-Ttext 0x30000000 直接程式執行起始地址,可以省去編寫連結器指令碼。

2、指令分類學習
1)算術和邏輯指令
1.1 mov 傳送
1.2 mvn 傳送取反的值
1.3 sub
1.4 and
1.5 orr
1.6 bic 位清除 例如:bic r1,r0,#0b1011

2)比較指令
1.1 cmp比較的結果會影響狀態暫存器CPSR的N 和 Z位
這裡寫圖片描述
執行完mov r1,#2 cmp r1,#2 後:
這裡寫圖片描述
CPSR最高0x0110,因為兩者相等,故N為0,Z為1

1.2 tst:按位與 結果影響CPSR的Z位,結果為0,則Z為1,反之為0

3)跳轉類指令
1.1 b:跳轉(分支),b條件,如果沒有條件,就直接跳
例如:

mov r1,#6
mov r2,#5
cmp r1,r2
bgt branch1   @if(r1>r2) 則跳轉到branch1執行;gt是條件執行,是大於的意思
add r3,r1,r2  @else 則順序執行
b end
branch1:
sub r3,r1,r2 end: nop

1.2 bl:帶連結返回的跳轉

mov r1,#2
cmp r1,#1
bl fun1   @如果是b,也能跳轉到fun1,但是跳完後不能返回到接下來要執行的地址,而bl可以把下一句的地址儲存到lr中,方便在完成跳轉之後能回到跳轉前的位置。

mov r1,#2
mov r1,#3

fun1:
mov r1,#2
mov r2,#3
mov pc,lr

4)移位指令(注意用法

1.1 lsl:算術移位
用法:
這裡寫圖片描述

1.2 ror:迴圈右移(可以觀察暫存器的變化)
用法:
這裡寫圖片描述

5)程式狀態字訪問指令(不允許mov等指令操作指令,涉及到狀態暫存器必須使用msr與mrs來操作)

1.1 msr:將通用暫存器的值搬到狀態暫存器

1.2 mrs:與前面相反

這裡寫圖片描述

6)儲存器訪問指令
1.1 ldr:將記憶體的值賦值到暫存器(執行完ldr後發現,r2中的值變為了0xff)

這裡寫圖片描述

1.2 str:與上面相反(將r1賦值為0x30001000,為記憶體的地址,然後再下面的memory中手動新增檢視記憶體地址為0x30001000的值的變化)

這裡寫圖片描述

3、偽指令

4、協處理訪問指令