1. 程式人生 > >stm32 開發中startup.s文件中常見的命令功能

stm32 開發中startup.s文件中常見的命令功能

only port main函數 聲明 字符 字數 strong 操作 ali

由於C的普及以及編譯器的發展,越來越多的軟件工程師在編程時很少有機會接觸到匯編語言。在ARM的開發中,我們不可避免的會遇到啟動文件的編寫,在KEIL環境中一般采用了startup.s的文件作為啟動代碼,很多工程師一見到這個文件就很頭痛,這裏我簡單地介紹一些常見的匯編指令、偽指令,希望對大家有所幫助,下次見到.s文件時也不會覺得那麽難以接受。

提醒下大家,在匯編代碼中是不區分大小寫的,這點和C語言不太一樣,所以一下的指令在很多時候是用小寫的。不過我個人意見是匯編最好全部用大寫字母,這樣方便閱讀。

本筆記有很多是基礎的知識,適合一些初級的工程師學習。很多指令和語法是匯編通用的,如果你耐心的全部看完,相信一定對你的開發工作有幫助。

1. REQUIRE8和PRESERVE8

在定義堆棧的時候,我們經常會看到REQUIRE8和PRESERVE8偽指令,這兩個指令是告訴編譯器保證8字節對齊。因為ARM的編譯器默認是4字節對齊的,而在堆棧的操作中很多時候我們會用到LDRD和STRD這樣的雙字傳送指令,所以這裏的存儲器就要求要8字節對齊。

實際操作中,REQUIRE8和PRESERVE8並不會直接完成對齊的操作,而只是更改編譯器中的編譯屬性,真正的對齊操作是由ALIGN來完成的。

2. AREA

AREA 偽指令用來定義一個存儲器的區域,一般我們把它叫做段(sector).其語法格式如下:

AREA 段名稱 屬性1,屬性2, ……

需要註意的是如果段名稱是由數字或者特殊字符開頭,則需要用||把段名稱括起來。例如 |3_Code| 或者|.code|

屬性部分用來表示該存儲器段的相關屬性,多個屬性之間用逗號隔開,常用的屬性如下:

- NOINIT : 非初始化

- CODE :用於定義代碼段,定義了該屬性則默認READONLY屬性

- DATA : 用於定義數據段,定義了該屬性則默認READWRITE屬性

- READWRITE/READONLY : 用來標示本段是只讀還是可讀可寫

- ALIGN : 存儲器的訪問的對齊, 一般定義為ALIGN = N,其中N表示對齊的字數,例如:

ALIGN = 2表示對齊方式是2的2次方,即4字節對齊

ALIGN = 3 標示對齊方式是2的3次方, 即8字節對齊

- COMMON : 該屬性用來定義一個通用的存儲區,不包含任何代碼和數據。在不同源文件中定義的COMMON區域共享一個存儲區域。

3. THUMB(CODE16)、ARM(CODE32)

這兩個偽指令通知編譯器,其後的指令為16位的Thumb指令還是32位的ARM指令。由於ARM7的內核支持這兩種指令模式,而且允許在同一個代碼中,對這兩個模式進行切換,所以在使用ARM和Thumb指令混合編程的代碼中,用這兩條偽指令來切換。

在Cortex-M系列內核中,由於采用了Thumb2的指令集,所以不存在切換ARM的指令模式。

4. EXPORT,IMPORT,EXTERN

這兩個偽指令用來聲明或引用一個全局的變量(函數)標號。在匯編和C的混合編程代碼中,可以通過這兩個偽指令來傳遞變量(函數)標號。其中EXPORT也可以用GLOBAL代替。

需要註意的是雖然匯編語言不區分大小寫,但變量(函數)的標號是區分大小寫的。

IMPORT的用法和EXTERN類似。它們主要的區別在於如果外部文件未定義本標號,是否添加到本源文件的符號表中,對一般的程序員來講不用關心這個差別。

如果在EXPORT和IMPORT 後面有[WEAK]的參數,表明本指令聲明的標號如果在其他地方遇到同名的標號,本標號的優先級最低。

5. SPACE

SPACE用來保留一個指定大小的存儲空間。該語句比較簡單,例如:

SPACE 100

表示在本指令開始的地址劃分出一個100字節大小的空間。

6. SPACE

SPACE用來保留一個指定大小的存儲空間。該語句比較簡單,例如:

SPACE 100

表示在本指令開始的地址劃分出一個100字節大小的空間

7. ENTRY

ENTRY用於指定匯編程序的入口點,有點像C語言中的main函數。一個完整的匯編應用程序至少需要一個ENTRY。

8. INCBIN

有時候我們會遇到這樣的問題,我有一個圖片或數據編譯成了BIN文件,這樣我如何把它嵌入到我的程序中來呢? INCBIN這個偽指令就給我們帶來這樣的用處,它可以把一段已經編譯好的BIN文件包含到當前的源文件中,被包含的文件不做任何改動。

例如:

我們要把一個編譯好的字符串加入源文件來,我們可以這樣寫:

EXPORT string_1 ; 聲明這個字符串的標號,方便其他程序調用

String_1

INCBIN string_1.bin ; 載入該字符的bin文件

在*.c的文件中,我們可以直接調用String_1[]這個數組。

9. GET, INCLUDE

GET和INCLUDE類似,它們用於將一個源文件包含到當前的源文件中,並將被包含的源文件在當前位置進行匯編處理。這個和C語言中的”#include”類似

10. END

END偽指令用來通知編譯器到了源程序的結尾。他和ENTRY相對應,一個應用程序只應該有一個END。

以上內容摘自Triton.Zhang。

stm32 開發中startup.s文件中常見的命令功能