習慣了使用C語言的情況下我發現自己對與匯編程序的符號和變量的理解很不深刻,今天抽空來學學加深理解。以ARM匯編來說,在匯編代碼中所有以"."開頭的指令都是匯編偽指令,他們不屬於ARM指令集。常常在匯編代碼中看到如下的使用方式但很少深入理解這樣的寫法的深層實現意義。究竟這兩種使用方式區別是什么呢?
.global xxxx
.word xxxx
查閱GNU的匯編偽指令說明后按我理解的我將兩者按如下的方式解釋:
.global
修飾標號為全局的,用法 .global xxx 這個符號可以被當前源文件以外的其他文件使用也可以被連接腳本(連接器)使用,xxx僅僅是一個標號對應一個地址並不是C中的一個變量。
無法對他取地址,因為他本身代表一個地址,僅僅是一個對應到一個編譯過程中的值的別名,類似C代碼中的define 定義的一樣,只是在鏈接時他的值是由連接器自動處理的。
匯編代碼使用僅能使用ldr,Rx,=xxx;而不能使用ldr,Rx,xxx
.word
匯編一個字的內存塊,用法 .word expressions 這個expressions 可以是一個數也可以是一個符號或表達式。 如果是一個數則這里直接放置的就是這個值。如果是一個標號則
這個標號最后值就會存放這里,標號的值就是這塊內存的地址。可以在C語言中直接使用extern uint32_t expressions來讀寫這個變量。
匯編中的使用同.global。expressions還可以是連接腳本中定義的符號。
這里 和word相同的功能的偽指令還有
.byte ;定義單字節數據
.hword/.short ;定義雙字節數據
.word/.long /.int ;定義4字節數據
.quad ;定義8字節數據
.float/.single ;定義32bit 浮點數
.double ;定義64bit浮點數
.ascii ;定義字符串以/0為結束符
例: .ascii "hello\0"
.asciz /.string ;定義字符串(非零結束符)
例: .string "hello"
.fill ;分配一段字節內存單元,用size長度value填充repeat次
例: .fill 10,2,6 ;將兩個字節長度的6重復填充10次
.zero ;分配一段字節內存單元,並用0填充內存
例: .zero 10 ;分配十個字節單元,並用0填充
.space/.skip ;分配一段內存單元,用value將內存單元初始化
例: .space 10,6 ;分配十個字節單元,並用6填充
實例代碼(來自liteos):
/* 修飾標號 __LOS_HEAP_ADDR_START__ 下同 */ .global __LOS_HEAP_ADDR_START__ .global __LOS_HEAP_ADDR_END__ /* 定義標號 __LOS_HEAP_ADDR_START__ 下同 */ __LOS_HEAP_ADDR_START__: .word __los_heap_addr_start__ __LOS_HEAP_ADDR_END__: .word __los_heap_addr_end__
符號(或標號)
僅存在程序構建過程而不存在於最終目標文件中,常常配合編譯和鏈接腳本使用,其保存的是地址信息。
變量
最終會在運行RAM中找到,如果是全局的就會一直存在。符號或標號指向一個地址,如下就是定義變量(連接器會預留這塊內存),__los_heap_addr_start__指向一塊內存,他的意思更像C語言中的變量實際對應特定地址的內存。
順帶查到的偽指令記一下:
.syntax
ARM架構下使用的定義匯編語法格式偽指令,用法 .syntax [unified | divided],其中divided為缺省值。 divided 此時使用舊的匯編風格,此時ARM和THUMB指令有着各自的語法。 使用unified時,ARM和THUMB指令使用統一的語法,有着以下的主要特性:
立即數不需要#前綴 可能會出現IT指令,如果出現,則根據后面的條件碼進行驗證。
在ARM模式下,它不會生成機器碼,而在THUMB模式下則會生成機器碼
對於ARM指令,條件碼總是出現在指令的最后;對於THUMB指令,條件碼可以被使用,但僅限於IT指令的范圍內 V6T2架構(及更高版本)的所有新指令都可用(這些指令中,divided語法僅支持少部分) 支持.N和.W后綴
.thumb 指定使用thumb指令集
.cpu 指定cpu類型如cortex-m0
.fpu 指點浮點計算指令的類型,有soft,softfp,hard 具體參考編譯器的幫助文檔一般在編譯器路徑的/share下有編譯器的幫助文檔。
.arch 指定代碼目標架構,如armv7-a
.type 指定符號類型
參考源碼地址:https://gitee.com/LiteOS/LiteOS/blob/master/targets/Cloud_STM32F429IGTx_FIRE/los_startup_gcc.S
參考博客:https://blog.csdn.net/gameit/article/details/13169307