歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

ARM匯編偽指令

GNU平台無關

符號定義偽指令

.global,.local,.set,.equ

.global

使得符號對連接器可見,變為對整個工程可用的全局變量

.global symbol

.local

表示符號對外部不可見,只對本文件可見

.local symbol

.set

給一個全局變量或局部變量賦值,和.equ的功能一樣

.set symbol expr
.set start, 0x40
.set start, 0x50
mov r1, #start      ;r1裡面是0x50

.equ

.set一樣,只是格式不同

symbol .equ  expr
start  .equ, 0x40
start  .equ, 0x50
mov r1, #start      ;r1裡面是0x50

數據定義偽指令

.byte,.short,.long,.quad,.float,.string,.asciz,.ascii,.rept

.byte

在存儲器中分配1個字節,用指定的數據對存儲單元進行初始化

label:  .byte   expr    ;label是程序標號,expr可以是-128~255的數字,也可是字符
a:  .byte   #1  ;等價於C中的char a=1;

.short

在存儲器中分配2個字節,用指定的數據對存儲單元進行初始化

a: .short 0x1234

.word / .long

在存儲器中分配4個字節,用指定的數據對存儲單元進行初始化

a: .word 0x12345678

.long

在存儲器中分配個字節,用指定的數據對存儲單元進行初始化

.quad

在存儲器中分配8個字節,用指定的數據對存儲單元進行初始化

a: .quad 0x12345678 ;等價於C中的long a=0x1234567812345678

.float

在存儲器中分配4個字節,用指定的浮點數據對存儲單元進行初始化

a: .float 1.11

.space/.skip

用於分配一塊連續的存儲區域並初始化為指定的值,如果後面的填充值省略不寫則在後面填充為0;

label: .space size,expr     ;expr可以是4字節以內的浮點數 
a:  space 8, 0x1

.string

定義一個字符串,默認是string8,還有string16,string32,string64

a: .space "hello world!"

.rept

重復執行接下來的指令,以.rept開始,以.endr結束

.rept cnt   ;cnt是重復次數
...
.endr

匯編控制偽操作

流程控制偽指令主要yy.if .else .endif .macro .endm .exitm

.if .else .endif

.if logical-expression
...
.elseif logical-expression2
...
.else
...
.endif

.macro .endm .exitm

該偽指令可以將一段代碼定義為一個整體,稱為宏指令,然後就可以在程序中通過宏指令多次調用該段代碼,而.exitm指令用來退出當前的宏指令,宏指令可以使用一個或多個參數,當宏操作被展開時,這些參數被相應的值替換。
包含在.macro。endm之間的指令序列稱為宏定義體。在宏定義體的第一行應聲明宏的原型,包含宏名所需的參數,然後就可以在匯編程序中通過宏名來調用該指令序列,在源程序被編譯時,匯編器將宏調用展開,用宏定義中的指令序列代替程序中的宏調用,並將實際參數的值傳遞給宏定義中的形式參數

.macro macroname macargs ...
;code
.endm

雜項

.align      用於使程序當前位置滿足一定的對齊方式
.section    用來定義一個段的偽指令
.data       用來定義一個數據段
.text       用來定義一個代碼段
.include    用來包含一個頭文件   
.arm        定義以下代碼使用arm指令集編譯
.code 32    同.arm
.code 16    同.thumb
.thumb      定義以下代碼使用thumb指令集編譯
.extern     用於聲明一個外部符號,用於兼容性其他匯編
.weak       用於聲明一個弱符號,如果這個符號沒有定義,編譯就忽略,而不會報錯
.end        表示匯編結束

GNU平台相關

ADR

把標簽所在的地址加載到寄存器中,這個指令將基於PC相對偏移的地址值或基於寄存器相對偏移的地址值讀取到寄存器中。當地址值是字節對齊的時候,取值范圍是-255~255B;當地址值是字對齊的時候,取值范圍為-1020~1020B。當地址值是16字節對齊時,取值范圍更大。 該指令等價於add <reg>, pc , offset

ADR <reg> <label>

ADRL

用於將中等范圍地址讀取到寄存器中

ADRL <reg> <label>

LDR

裝載一個32位的常數和一個地址寄存器

LDR reg, =expr

reg:目標寄存器
expr:32位常量表達式。匯編器根據expr的取值情況,對LDR偽指令做如下處理:

  1. 當expr表示的指令地址值沒有超過MOV指令或MVN指令的地址取值范圍時,匯編器用一對MOV和MVN代替LDR指令
  2. 當超過了的時候,匯編器將常數放入緩存吃,同時用一條基於PC的LDR讀取該常數
LDR R3,=0xff0
;將常熟0xff0讀到內存中相當於MOV R3, #0xff0

LDR R1,=0xfff   
;將常數0xfff讀到內存,
;相當於LDR R1,[pc, offset_to_litpool]  ... litpool DCD 0xfff

LDR R2, =place  
;將place標號的地址讀入到R1中
;相當於LDR R1,[pc, offset_to_litpool]  ... litpool DCD place

Copyright © Linux教程網 All Rights Reserved