? ? ? ?大家好,今天給大家分享,GNU匯編的語法。
第一:匯編簡介
? ? ? ? GNU 匯編語法適用于所有的架構,并不是 ARM 獨享的,GNU 匯編由一系列的語句組成,
每行一條語句,每條語句有三個可選部分,如下:
label:instruction @ comment
label 即標號,表示地址位置,有些指令前面可能會有標號,這樣就可以通過這個標號得到
指令的地址,標號也可以用來表示數據地址。注意 label 后面的“:”,任何以“:”結尾的標識
符都會被識別為一個標號。
instruction 即指令,也就是匯編指令或偽指令。
@符號,表示后面的是注釋,就跟 C 語言里面的“/*”和“*/”一樣,其實在 GNU 匯編文
件中我們也可以使用“/*”和“*/”來注釋。
注意:ARM 中的指令、偽指令、偽操作、寄存器名等可以全部使用大寫,也可以全部使用
第二:處理器內部數據傳輸方法
1、MOV 指令
MOV 指令用于將數據從一個寄存器拷貝到另外一個寄存器,或者將一個立即數傳遞到寄
存器里面,使用示例如下:
MOV R0,R1? ? ? ? @將寄存器 R1 中的數據傳遞給 R0,即 R0=R1
MOV R0, #0X12? ? @將立即數 0X12 傳遞給 R0 寄存器,即 R0=0X12
2、MRS 指令
MRS 指令用于將特殊寄存器(如 CPSR 和 SPSR)中的數據傳遞給通用寄存器,要讀取特殊
寄存器的數據只能使用 MRS 指令!使用示例如下:
MRS R0, CPSR? ? ? @將特殊寄存器 CPSR 里面的數據傳遞給 R0,即 R0=CPSR
3、MSR 指令
MSR 指令和 MRS 剛好相反,MSR 指令用來將普通寄存器的數據傳遞給特殊寄存器,也就
是寫特殊寄存器,寫特殊寄存器只能使用 MSR,使用示例如下:
MSR CPSR, R0? ? ? @將 R0 中的數據復制到 CPSR 中,即 CPSR=R0
BL 指令相比 B 指令,在跳轉之前會在寄存器 LR(R14)中保存當前 PC 寄存器值,所以可以通過將 LR 寄存器中的值重新加載到 PC 中來繼續從跳轉之前的代碼處運行,這是子程序調用一個基本但常用的手段。比如 Cortex-A 處理器的 irq 中斷服務函數都是匯編寫的,主要用匯編來實現現場的保護和恢復、獲取中斷號等。但是具體的中斷處理過程都是 C 函數,所以就會存
在匯編中調用 C 函數的問題。而且當 C 語言版本的中斷處理函數執行完成以后是需要返回到
irq 匯編中斷服務函數,因為還要處理其他的工作,一般是恢復現場。這個時候就不能直接使用
B 指令了,因為 B 指令一旦跳轉就再也不會回來了,這個時候要使用 BL 指令,示例代碼如下:
BL 指令示例
push {r0, r1} @保存 r0,r1
?cps #0x13
@進入 SVC 模式,允許其他中斷再次進去
bl system_irqhandler
@加載 C 語言中斷處理函數到 r2 寄存器中
?cps #0x12 @進入 IRQ 模式
?pop {r0, r1}
?str r0, [r1, #0X10] @中斷執行完成,寫 EOIR
上述代碼中就是執行 C 語言版的中斷處理函數,當處理完成以后是需要返回來繼續
執行下面的程序,所以使用了 BL 指令。