IARM 內嵌組語基本規則
- 使用
__asm("...") 關鍵字。
- 多行指令以
\n 換行符分隔,字串常數自動連接。
- 最後一行指令後 不需 加分號,但整個
__asm 陳述式結尾需加分號。
- 註解在字串內無效,建議在 C 程式碼中用
// 說明。
範例:高效記憶體填充
void QuickCopy(INT32U *addr, INT32U len, INT32U data) {
__asm(
"STMFD SP!, { R4 - R11 }\n" // 保存 R4-R11 到堆疊
"ADD R1, R0, R1\n" // R1 = 結束位址
"MOV R4, R2\n" // R4-R11 皆載入填充值
"MOV R5, R2\n"
"MOV R6, R2\n"
"MOV R7, R2\n"
"MOV R8, R2\n"
"MOV R9, R2\n"
"MOV R10, R2\n"
"MOV R11, R2\n"
"LOOP:\n"
"STMIA R0!, { R4 - R11 }\n" // 批量存儲 8 個字 (32 bytes)
"CMP R1, R0\n" // 比較是否到達結束
"BNE LOOP\n" // 未結束則繼續
"LDMIA SP!, { R4 - R11 }\n" // 恢復寄存器
"BX LR\n" // 返回
);
}
參數對應 (ARM EABI 呼叫慣例)
| C 參數 | 寄存器 | 範例含義 |
| addr | R0 | 目標起始位址 |
| len | R1 | 長度 (元素數) |
| data | R2 | 填充值 |
指令解析
STMFD SP!, {R4-R11}:Full Descending 堆疊推入多寄存器。
STMIA R0!, {R4-R11}:Store Multiple Increment After,將 R4-R11 連續存入 R0 指向的記憶體,並自動遞增 R0。
BX LR:Branch and Exchange,返回呼叫者 (支援 Thumb/ARM 切換)。
常見錯誤與注意點
- 忘記 \n:指令會連成一行導致語法錯誤。
- 字串未正確閉合:每行雙引號需成對,C 編譯器會自動連接相鄰字串常數。
- 破壞呼叫慣例寄存器:若修改 R4-R11, R13(SP), R14(LR) 必須保存/恢復。
- 條件跳轉標籤:標籤需以冒號結尾 (如
LOOP:),跳轉指令不帶冒號。
適用場景
- 高效能記憶體操作 (memcpy/memset 替代)。
- 存取特殊功能暫存器 (SFR)。
- 精確計時/延遲迴圈。
- 啟動代碼、中斷服務程式 (ISR) 序言/結語。
- 上一篇文章: C 語言 main 函數若宣告為 static 會發生什麼?
- 下一篇文章: C 語言經典氣泡排序法實作與優化
Copyright ©
程式碼之家 All Rights Reserved