相關概念
棧是一種具有後進先出性質的資料組織方式,也就是說後存放的先取出,先存放的後取出。棧底是第乙個進棧的資料所處的位置,棧頂是最後乙個進棧的資料所處的位置。
根據sp指標指向的位置,棧可以分為滿棧和空棧。
1、滿棧:當堆疊指標sp總是指向最後壓入堆疊的資料。
2、空棧:當堆疊指標sp總是指向下乙個將要放入資料的空位置。
arm採用滿棧。
根據sp指標移動的方向,棧可以分為公升棧和降棧。
1、公升棧:隨著資料的入棧,sp指標從低位址->高位址移動。
2、降棧:隨著資料的入棧,sp指標從高位址->低位址移動。
arm採用降棧。
arm採用滿降棧。
簡單的講,棧幀(stack frame)就是乙個函式所使用的那部分棧,所有函式的棧幀串起來就組成了乙個完整的棧。棧幀的兩個邊界分別由fp(r11)和sp(r13)來限定。
棧的作用:
1、儲存區域性變數
2、傳遞引數
3、儲存暫存器值
初始化棧空間:
init_stack:
ldr sp, =0x54000000
@4是任意指定的,指向記憶體64m的位置
mov pc ,lr
bss段的作用:存放未初始化的全域性變數。
bss段初始化**:清空bss段
clean_bss: @清空未初始化資料段 bss段
ldr r1, =bss_start @在lds檔案中定義的變數
ldr r2, =bss_end
cmp r1, r2
moveq pc, lr
clean_loop:
movr0, #0
str r0, [r1], #4
cmp r1, r2
bne clean_loop
mov pc, lr
指令b和bl為相對跳轉,直接給pc指標賦值就是絕對跳轉,跳轉到c語言**需要使用絕對跳轉,使用ldr指令給pc指標複製。
採用c語言程式設計序:
在完成了棧和bss段的初始化之後,可以使用c語言
bl init_stack
bl clean_bss
ldr pc, =gboot_main
@bl light_led
c語言如下:
#define gpmcon (volatile unsigned long *)0x7f008820
#define gpmdat (volatile unsigned long *)0x7f008824
void gboot_main()
c語言與組合語言的特點:
組合語言:執行效率高;編寫繁瑣
c語言:可讀性強,移植性好,除錯方便
在對執行效率要求比較高,或者能夠更直接地控制處理器(例如cpsr暫存器)的情況下,可以採用c和彙編混合程式設計。
彙編呼叫c函式
在上一部分的gboot_main()函式就是彙編對c函式的呼叫,直接使用ldr指令,給pc賦值,把函式名賦值給pc指標即可。
c呼叫彙編函式
直接用標號作為函式名,引數為空,以上面的**為例,可以在c檔案中呼叫彙編函式,如:
.global light_led
void gboot_main()
但是,一定要注意:必須把彙編函式的標號先宣告為全域性的,否則c檔案找不到彙編檔案中的彙編函式標號。
c內嵌彙編
格式:
兩個下劃線+asm+兩個下劃線
1、彙編語句部分:彙編語句的集合,可以包含多條彙編語句,每條語句之間需要使用換行符 「\n」隔開或使用分號「 ; 」隔開,內容都要用引號套上。
2、輸出部分:在彙編中被修改的c變數列表。
3、輸入部分: 作為引數輸入到彙編中的變數列表。
4、破壞描述部分: 執行彙編指令會破壞的暫存器描述。
在c語言的asm塊中,需要使用//來表示注釋。
舉例1,向cpsr暫存器寫入內容:
%0表示第0號引數,凡是要讀的引數都要寫入輸入部分,」r」表示輸入的性質是乙個通用暫存器的值,具體是那個通用暫存器由系統自己選擇,value是輸入的變數的值。
舉例2,從cpsr暫存器中讀取內容
賦值給value。
舉例3,使用volatile來阻止優化
使用volatile來告訴編譯器,不要對接下來的這部分**進行優化。
舉例4,使用asm來內嵌點亮led程式
__asm__(
"ldr r1, =0x7f008820\n"
"ldr r0, =0x1111\n"
"str r0, [r1]\n"
"ldr r1, =0x7f008824 \n"
"mov r0, #0b0101\n"
"str r0, [r1]\n"::
: "memory"
);
讓QT跑在ARM開發板上
前幾個星期為了搭建乙個android跑qt的編譯環境,由於不熟悉android開發的環境,什麼jdk,ndk,sdk,ant一大堆全沒聽過的名詞開始出現,即使有大神的書做參考,花了兩天的時間還是沒能在windows上面搭建出來,最後在linux上quest花了不到兩個小時就搞定,也不知道是什麼原因。...
在開發板上增加中文環境
拷貝工具鏈裡的i18n目錄到 usr share下 在 usr lib 下建立乙個locale目錄,執行 localedef f utf 8 i zh cn zh cn.utf8命令。就能在 usr lib locale下建立乙個locale archive檔案。用locale a命令就能看到剛才加...
搭建nfs除錯arm開發板
嵌入式開發應用,如果每次都從新燒錄檔案系統比較浪費時間,所以使用nfs是個比較不錯的方法,linux作為nfs伺服器端,arm作為客戶端。1.ubuntu安裝配置nfs,並做本地測試 sudo apt get install nfs kernel server 1安裝好之後做配置,修改 etc ex...