嵌入式系統/ARM 微處理器
ARM 架構是一種廣泛使用的 32 位 RISC 處理器架構。事實上,ARM 系列約佔所有 32 位 CPU 的 75%,約佔所有嵌入式 32 位 CPU 的 90%。ARM 有限公司將幾個流行的微處理器核心授權給許多供應商(ARM 不出售物理微處理器)。最初,ARM 代表高階精簡指令集機器。
ARM 提供的一些核心
- ARM7TDMI
- ARM9
- ARM11
一些基於 ARM 的處理器的示例
- 英特爾 X-Scale(PXA-255 和 PXA-270),用於 Palm PDA
- 飛利浦 LPC2000 系列 (ARM7TDMI-S 核心),LPC3000 系列 (ARM9 核心)
- Atmel AT91SAM7 (ARM7TDMI 核心)
- 意法半導體 STR710 (ARM7TDMI 核心)
- 飛思卡爾 MCIMX27 系列 (ARM9 核心)
最便宜的 ARM 處理器(LPC2000 系列)的價格已降至 5 美元以下,低於許多 16 位和 8 位微處理器的價格。
在 ARM Thumb 程式碼中,16 個暫存器 r0 - r15 通常在所有 ARM 程式碼中具有相同的角色
- r0 - r3,稱為 a1 - a4:引數/臨時/結果暫存器。
- r4 - r9,稱為 v1 - v6:變數
- r10,稱為 sl:堆疊限制
- r11,稱為 fp:幀指標(通常在 Thumb 程式碼中不使用)
- r12,稱為 ip
- r13,稱為 sp:堆疊指標
- r14,稱為 lr:連結暫存器
- r15,稱為 pc:程式計數器
ARM Thumb 的標準 C 呼叫約定是:[1]
當返回地址放置在 pc (r15) 中時,從子程式返回時,sp、fp、sl 和 v1-v6 暫存器必須包含與呼叫子程式時相同的
每個執行環境都對堆疊在記憶體中下降的範圍有限制——“最小 sp”。
為了讓中斷(可能在任何時候發生)有空間工作,在任何時刻,sp 和“最小 sp”之間的記憶體必須不包含對正在執行的程式
應用程式及其庫支援程式碼負責檢測和處理堆疊溢位的系統稱為“顯式堆疊限制”。在這樣的系統中,sl 暫存器必須始終
子程式可以隨意覆蓋 a1-a4、ip 和 lr。
如果子程式返回一個不超過一個字的簡單值,則該值必須在 a1 (r0) 中。
如果子程式返回一個簡單的浮點值,則該值編碼在 a1 中;或者 {a1, a2} 中;或者 {a1, a2, a3} 中,以
Thumb 函式最簡單的入口和退出序列是:[1]
an_example_Thumb_subroutine:
PUSH {save-registers, lr} ; one-line entry sequence
; ... first part of function ...
BL subroutine_name ;Must be in a space of +/- 4 MB
; ... rest of function goes here, perhaps including other function calls
; ...
POP {save-registers, pc} ; one-line exit sequence
ARM 的標準 C 呼叫約定由 ARM PLC 詳細說明。[2]
32 位 ARM 函式最簡單的入口和退出序列與 Thumb 函式非常相似:[3][4][5]
an_example_ARM32_subroutine:
PUSH {r4-r11, lr} ; one-line function prologue
; ... first part of function ...
BL subroutine_name ;Must be in a space of +/- 4 MB
; ... rest of function goes here, perhaps including other function calls
; ...
POP {r4-r11, pc} ; one-line exit sequence (function epilogue)
使用相同指令的備用助記符,
an_example_ARM32_subroutine:
; Push the return address (in LR) and the work registers
; "store multiple registers, full descending"
STMFD sp!,{r4-r11, lr} ; aka PUSH {r4-r11, lr}
; (A "sp" alone would leave the stack pointer unchanged.
; We must use "sp!" to update the stack pointer appropriately.)
; ... first part of function ...
BL subroutine_name ;Must be in a space of +/- 4 MB
; ... rest of function goes here, perhaps including other function calls
; ...
; Pop the return address (into PC) and the work registers
; and return automatically.
; "load multiple registers, full descending"
LDMFD sp!,{r4-r11, pc} ; aka POP {r4-r11, pc}
BL(分支並連結)指令將返回地址儲存在連結暫存器 LR(r14)中,並將程式計數器 PC(r15)載入到子程式地址。典型
通常,r4-r11 用於儲存當前正在執行的例程的區域性變數。
暫存器 r4-r11 是“子程式保留暫存器”——當子程式將返回地址放置在 pc (r15) 中時,從子程式返回時,暫存器 r4-r11
典型的子程式(如上所示)會立即將這些暫存器的值壓入堆疊。這釋放了 r4-r11 以儲存當前正在執行的子程式的區域性
最佳化的 ARM 編譯器會儲存和恢復 r4-r11 和 r14(如果有)的精確子集,這些子集實際上被該子程式修改了,因為儲存和
子程式可以隨意覆蓋 r0-r3、r12 和連結暫存器 lr (r14)。
前四個暫存器 r0-r3 用於將引數值傳遞給子程式,並從函式返回結果值。
使用 BL 指令可以輕鬆進行正常的函式呼叫。一個人輸入
BL destination_subroutine
彙編器和連結器會自動執行“正確的事情” - 插入適當的(32 位長)ARM32 BL 指令用於 ARM32 到 ARM32 或 ARM32 到 Thumb 的呼叫,或插入適當的(32 位長)[6] Thumb BL 指令用於 Thumb 到 Thumb 或 Thumb 到 ARM32 的指令。
(一些混合呼叫和一些長分支需要連結器插入程式碼,用臨時值覆蓋 scratch register r12。 連結器究竟是如何做到的可能會令人困惑,尤其是在混合使用 BX 和 BLX 指令時。[7][8])
進一步閱讀
[edit | edit source]- ↑ a b ARM. ARM 軟體開發工具包. 1997. 第 9 章:ARM 過程呼叫標準。 第 10 章:Thumb 過程呼叫標準。
- ↑ "ARM 架構過程呼叫標準"
- ↑ RealView 編譯工具開發者指南 "在 C、C++ 和 ARM 組合語言之間呼叫"
- ↑ [1] 第 59 頁“堆疊和子程式”部分
- ↑ "為巢狀子程式堆疊暫存器"
- ↑ [infocenter.arm.com/help/topic/com.arm.doc.ddi0234b/i107462.html "帶有連結的 Thumb 分支 (BL)"]
- ↑ "Arm/Thumb:在 Thumb 程式碼中使用 BX,呼叫 Thumb 函式,或跳轉到另一個函式中的 Thumb 指令"
- ↑ "Arm / Thumb 互操作"
- 嵌入式系統/組合語言
- Embedded_Systems/Mixed_C_and_Assembly_Programming#ARM
- ARM 微控制器維基
- "ARM 概述" 位於 OS Dev 維基
- ARM 組合語言速覽
- GCC ARM 改進專案 位於塞格德大學
- ARM Linux 專案:適用於所有基於 ARM 的機器的 Linux
- ARM
- ARM 開發人員討論論壇
- ARM Cortex-M3 技術參考手冊
- ARM 彙編器 由 Richard Murray 提供