ARM匯編的一些編寫和調用規范總結

ARM匯編在格式上有少數硬性要求,在排版上幾乎沒什么硬性要求,都不多,以下分別說明。

格式要求?

ARM 匯編有一些格式上的硬性要求,這些規則由匯編器(如 GNU 的gas、ARM 官方的armasm)強制執行,違反會導致編譯錯誤。以下是核心硬性要求:

1.?指令格式:操作碼與操作數的順序

  • 必須遵循 “操作碼 目標操作數,源操作數”?的順序(與 x86 匯編相反)。
    例如:
    ADD R0, R1, R2    ; 正確:R0 = R1 + R2(目標在前,源在后)
    ; 錯誤寫法:ADD R1, R2, R0(順序顛倒)
    
  • 立即數前必須加?#,寄存器前必須加?R(或?r,大小寫不敏感):
    MOV R0, #10       ; 正確:R0 = 10
    ; 錯誤寫法:MOV 0, 10(缺少R和#)
    

2.?標簽定義:必須以冒號?:?結尾

  • 標簽(用于跳轉或數據引用)必須以?:?結尾,且單獨占一行(或行首):
    loop:             ; 正確:定義loop標簽B loop        ; 跳轉至loop
    ; 錯誤寫法:loop B loop(標簽未加:)
    

3.?段定義:必須通過偽指令聲明

  • 代碼、數據必須放在明確的段中,通過?.text(代碼段)、.data(數據段)等偽指令聲明:
    .text             ; 正確:代碼段開始
    main:MOV R0, #0.data             ; 正確:數據段開始
    var: .word 100
    ; 錯誤:無段聲明直接寫指令或數據
    

4.?注釋格式:必須用特定符號開頭

  • GNU 匯編器(gas)中,注釋以?@?開頭;ARM 匯編器(armasm)支持?;?或?@
    MOV R0, #0    @ 正確:GNU風格注釋(推薦)
    MOV R1, #1    ; 正確:ARM匯編器兼容的注釋
    

5.?指令集模式匹配

  • ARM 指令集(32 位)和 Thumb 指令集(16/32 位混合)不能混用,需通過偽指令聲明模式:
    .arm             ; 聲明ARM模式(32位指令)
    ADD R0, R1, R2   ; 32位ARM指令.thumb           ; 聲明Thumb模式(16/32位指令)
    ADD R0, R1       ; 16位Thumb指令(操作數限制更嚴格)
    ; 錯誤:在Thumb模式下使用ARM特有的32位指令
    

6.?對齊要求:數據和指令的地址對齊

  • 數據類型需按大小對齊(如?.word?占 4 字節,需 4 字節對齊):
    .align 2         ; 強制4字節對齊(2^2=4)
    var: .word 0x12345678  ; 正確:地址為4的倍數
    ; 錯誤:未對齊時,某些架構可能無法訪問數據
    
  • 指令對齊:Thumb 指令需 2 字節對齊,ARM 指令需 4 字節對齊(匯編器通常自動處理,但復雜場景需手動用?.align?控制)。

7.?偽指令格式:必須以?.?開頭

  • 匯編器偽指令(如段定義、數據定義)必須以?.?開頭:
    .global main     ; 正確:聲明全局符號
    .word 100        ; 正確:定義4字節數據
    ; 錯誤:global main(缺少.)
    

8.?寄存器使用規范

  • 特殊寄存器(如?PCLRSP)有固定用途,不能隨意當作普通寄存器使用:
    MOV PC, LR       ; 正確:用LR恢復PC實現返回
    ; 錯誤:MOV LR, #10(隨意修改LR會破壞返回地址)
    

總結

ARM 匯編的硬性要求主要體現在:指令格式、標簽定義、段劃分、注釋符號、指令集模式、對齊規則?等方面。這些規則確保匯編器能正確解析代碼,生成符合目標架構的機器碼。不同匯編器(如gasarmasm)可能有細微差異,但上述核心規則是通用的。

排版建議

ARM 匯編對排版(格式布局)沒有像高級語言那樣嚴格的語法約束,但良好的排版習慣能提高代碼可讀性,且部分匯編器對特定元素的位置有隱性要求。以下是需要注意的排版規則和建議:

一、硬性排版要求(違反會報錯)

  1. 標簽必須位于行首
    標簽(帶:的符號)必須放在一行的開頭,不能縮進,否則匯編器會將其識別為指令而非標簽:

    loop:             ; 正確:標簽在行首B loop        ; 指令縮進(推薦); 錯誤示例:標簽前有空格error_label:    ; 匯編器會報錯(無法識別為標簽)
    
  2. 指令和偽指令不能與標簽同行
    標簽必須單獨占一行,不能跟在指令或偽指令后面

    data: .word 100   ; 錯誤:標簽與偽指令同行; 正確寫法:
    data:.word 100
    
  3. 操作數之間的逗號必須緊跟前一個操作數
    指令的操作數之間用逗號分隔,逗號后可加空格,但逗號不能單獨換行:

    ADD R0, R1, R2    ; 正確
    ADD R0,R1,R2      ; 正確(無空格也可); 錯誤示例:逗號后換行
    ADD R0, 
    R1, R2            ; 匯編器會將第二行識別為獨立指令,導致錯誤
    

二、推薦排版規范(提高可讀性)

  1. 指令和偽指令縮進
    標簽不縮進,指令、偽指令和注釋縮進(通常用 4 個空格或 1 個 Tab),使代碼結構清晰:

    main:push {lr}        ; 縮進指令mov r0, #0       ; 縮進指令.data            ; 偽指令也建議縮進
    var:.word 100
    
  2. 注釋與代碼分隔
    注釋盡量放在指令右側,或單獨占一行,與代碼保持一定距離(如用多個空格分隔):

    ; 推薦:注釋與代碼用空格分隔
    MOV R0, #10        @ 設置返回值為10; 不推薦:注釋緊貼代碼,可讀性差
    MOV R0,#10@返回值
    
  3. 同類指令對齊
    操作碼、操作數、注釋分別對齊,形成列結構,尤其適合批量處理的指令:

    MOV R0, #0         @ 初始化參數1
    MOV R1, #100       @ 初始化參數2
    MOV R2, #255       @ 初始化參數3
    
  4. 空行分隔邏輯塊
    用空行分隔不同功能的代碼塊(如初始化、循環、函數調用等),增強層次感:

    main:push {lr}; 初始化參數mov r0, #5mov r1, #3; 調用加法函數bl addpop {pc}
    
  5. 大小寫統一
    寄存器(R0/r0)、指令(ADD/add)、偽指令(.text/.TEXT)的大小寫不影響匯編器解析,但建議統一風格(如大寫指令、小寫寄存器):

    ; 推薦:風格統一
    add r0, r1, r2     @ 小寫指令和寄存器; 不推薦:大小寫混亂
    Add R0, r1, R2
    

三、匯編器的靈活性

  • 多數 ARM 匯編器(如gas)對空格、換行不敏感,只要語法正確,即使排版混亂也能編譯通過(但可讀性極差)。
  • 唯一的例外是標簽必須在行首,這是幾乎所有匯編器都嚴格要求的排版規則。

總結

ARM 匯編的硬性排版要求極少,僅需遵守 “標簽行首”“操作數逗號不換行” 等規則;但推薦的排版規范(縮進、對齊、空行等)能極大提升代碼的可維護性,尤其在復雜程序中更為重要。良好的排版習慣是匯編開發的基本素養。

AAPCS(Procedure Call Standard for the ARM Architecture)是ARM 架構的過程調用標準,定義了 ARM 程序中函數調用時必須遵循的一套規則,確保不同語言(如 C 和匯編)、不同編譯單元之間的函數調用能夠正確交互。

AAPCS調用規范

簡單說,AAPCS 的核心作用是:規定函數調用時參數如何傳遞、返回值如何存儲、寄存器如何使用、棧如何維護,避免因調用規則不統一導致程序崩潰。

AAPCS 的核心內容

1.?參數傳遞規則

  • 前 4 個參數:通過寄存器?r0-r3?傳遞(稱為 “參數寄存器”)。
    • 例如:func(a, b, c, d)?中,a→r0b→r1c→r2d→r3
  • 第 5 個及以后的參數:從右向左依次壓入棧(棧增長方向為低地址)。
    • 例如:func(a, b, c, d, e)?中,e?先壓棧,再壓入其他超出 4 個的參數。
  • 參數類型適配
    • 32 位數據(int、指針等)直接放入寄存器或棧。
    • 64 位數據(long long、double)占用兩個連續寄存器(如?r0-r1)或棧空間。
    • 結構體等大型數據:通常通過指針傳遞(放入?r0),或按規則拆分到寄存器 / 棧。

2.?返回值存儲規則

  • 32 位返回值(int、float、指針等):存入?r0
  • 64 位返回值(long long、double):存入?r0-r1(低 32 位在?r0,高 32 位在?r1)。
  • 大型返回值(如結構體):調用者預先在棧上分配空間,將空間地址通過?r0?傳遞給被調函數,被調函數將結果寫入該地址。

3.?寄存器使用規范

寄存器分為調用者保存寄存器被調用者保存寄存器,職責明確:

  • 調用者保存寄存器r0-r3r12):
    • 用途:傳遞參數、臨時計算。
    • 規則:被調函數可以隨意修改,調用者若需保留這些寄存器的值,需在調用前手動壓棧保存。
  • 被調用者保存寄存器r4-r11r14=LR):
    • 用途:保存局部變量、函數上下文。
    • 規則:被調函數若使用這些寄存器,必須在函數入口處壓棧保存,退出前恢復(確保調用者的上下文不被破壞)。
  • 特殊寄存器
    • r13(SP):棧指針,必須保持 4 字節或 8 字節對齊(依架構而定)。
    • r15(PC):程序計數器,不可手動修改(通過分支指令間接更新)。

4.?棧的使用規則

  • 棧對齊:函數調用前后,棧指針(SP)必須保持 8 字節對齊(確保 64 位數據訪問正確)。
  • 棧幀結構:通常包含以下部分(從高地址到低地址):
    高地址 → 調用者的棧幀被調用者保存的寄存器(r4-r11等)局部變量臨時數據/參數(第5個及以后的參數)
    低地址 → SP(棧指針)
    
  • 棧增長方向:向低地址增長(壓棧時 SP 減小,出棧時 SP 增大)。

5.?其他重要規則

  • Thumb 與 ARM 指令集兼容:混合使用時需確保調用跳轉符合指令集切換規范(如用?BX LR?而非?MOV PC, LR)。
  • 位置無關代碼(PIC):函數調用需支持動態地址重定位(通過相對尋址實現)。
  • 浮點參數:通過 VFP(向量浮點單元)寄存器?s0-s15?傳遞,遵循類似整數寄存器的規則。

為什么需要 AAPCS?

如果沒有統一的調用標準,會導致:

  • C 函數調用匯編函數時,參數傳遞方式不匹配(如 C 存r0,匯編讀r1)。
  • 寄存器被意外修改(如匯編函數修改了r4但未恢復,導致 C 函數的局部變量錯亂)。
  • 棧對齊錯誤(導致硬件無法訪問 64 位數據,觸發異常)。

AAPCS 通過統一這些規則,確保不同語言、不同模塊的代碼能夠無縫協作,是 ARM 架構下混合編程(如 C 與匯編互調)的基礎。

實際開發中,編譯器(如 GCC)會自動遵循 AAPCS 生成代碼,手動編寫匯編時則需要嚴格遵守這些規則,才能確保函數調用正確。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92801.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92801.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92801.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FastAPI框架下集成智譜大模型的RAG流式響應服務框架

RAG(檢索增強生成)是結合檢索與生成式 AI 的技術框架。核心邏輯是先從外部知識庫精準檢索相關信息,再將其作為上下文輸入大模型生成回答。技術上依賴檢索引擎(如向量數據庫、BM25)、大語言模型(如 GPT、LLa…

基于深度學習的胸部 X 光圖像肺炎分類系統(三)

目錄 二分類胸片判斷: 1. 數據加載時指定了兩類標簽 2. 損失函數用了二分類專用的 3. 輸出層只有 1 個神經元,用了sigmoid激活函數 4. 預測時用 0.5 作為分類閾值 二分類胸片判斷: import numpy as np import matplotlib.pyplot as plt f…

深入理解 BIO、NIO、AIO

目錄 一、同步與非同步 二、阻塞與非阻塞 三、BIO(Blocking I/O,阻塞I/O) 四、NIO(Non-blocking I/O,非阻塞I/O) 五、AIO(Asynchronous I/O,異步I/O) 同步阻塞&…

電腦無法識別固態硬盤怎么辦?

隨著固態硬盤(SSD)越來越普及,不少用戶在給電腦更換、加裝SSD時會遇到一個讓人頭大的問題——電腦識別不了固態硬盤。可能是開不了機,或者在“此電腦”中找不到硬盤,甚至連系統安裝界面都提示“找不到驅動器”。這時候…

Kingbasepostgis 安裝實踐

文章目錄前言一、安裝準備1.1 部署方案規劃1.2 SELINUX、防火墻狀態檢查1.3 操作系統時間檢查1.4 創建用戶及密碼1.5 目錄創建1.6 操作系統參數配置1.6.1 配置limits.conf文件二、安裝2.1 上傳安裝包以及license授權文件2.2 拷貝安裝文件2.3 命令行方式安裝2.3.1簡介2.3.2 許可…

移動端設備能部署的llm

mlc-llm 內置RedPajama hf示例模型 TheBloke/Mistral-7B-Instruct-v0.2-GGUF https://github.com/mlc-ai/mlc-llm/tree/main llama.cpp https://github.com/ggml-org/llama.cpp reference --- MLC-LLM:大模型如何部署到瀏覽器 / 手機?完整流程復現…

Ubuntu硬盤掛載

一、在 Ubuntu 中,你可以用以下命令快速查看 所有已連接但尚未掛載的硬盤和分區:lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,UUID輸出中 MOUNTPOINT 為空的行,就是 未掛載的分區。sda ├─sda1 500M ext4 /boot ├─sda2 1.8T ntfs └─sda3 …

JavaScript -Socket5代理使用

axios 安裝兩個包 socks-proxy-agent,axios const { SocksProxyAgent } require(socks-proxy-agent); const axios require(axios);const socks5Axios axios.create();const socks5 () > {const socks5Agent new SocksProxyAgent("socks5://112.194.8…

[特殊字符] 從數據庫無法訪問到成功修復崩潰表:一次 MySQL 故障排查實錄

一次典型的 MySQL 故障排查與修復全過程,涵蓋登錄失敗、表崩潰、innodb_force_recovery 救援、壞表剔除與數據恢復等關鍵操作。一、問題背景某業務系統運行多年,數據庫使用的是 MySQL 8.0.18,近期在一次服務器重啟后,發現無法正常…

【Agent】API Reference Manual(API 參考手冊)

https://github.com/Intelligent-Internet/CommonGround/blob/main/docs/framework/03-api-reference.md 以下是這份 API Reference Manual(API 參考手冊) 的完整中文翻譯: API 參考手冊 版本:0.1 目錄 概覽 1.1 API 目的 1.2 通信協議與核心概念 HTTP API 2.1 POST /se…

LeetCode Hot 100 全排列

給定一個不含重復數字的數組 nums ,返回其 所有可能的全排列 。你可以 按任意順序 返回答案。示例 1:輸入:nums [1,2,3] 輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2:輸入:nums [0,1]…

AI大模型如何有效識別和糾正數據中的偏見?

當下,人工智能大模型已成為推動各行業發展的關鍵力量,廣泛應用于自然語言處理、圖像識別、醫療診斷、金融風控等領域,為人們的生活和工作帶來了諸多便利。然而,隨著其應用的不斷深入,數據偏見問題逐漸浮出水面&#xf…

如何通過內網穿透,訪問公司內部服務器?

“凌晨2點,銷售總監王姐在機場候機時突然接到客戶電話——對方要求立即查看產品庫存數據。她慌忙翻出筆記本電腦,卻發現公司內網數據庫沒有公網IP,VPN連接又卡在驗證環節……這樣的場景,是否讓你想起某個手忙腳亂的時刻&#xff1…

12. isaacsim4.2教程-ROS 導航

1. Teleport 示例 ROS 服務的作用: 提供了一種同步、請求-響應的通信方式,用于執行那些需要即時獲取結果或狀態反饋的一次性操作或查詢。 Teleport 服務在 ROS 仿真(尤其是 Gazebo)和某些簡單機器人控制中扮演著瞬移機器人或對象…

DeepSpeed-FastGen:通過 MII 和 DeepSpeed-Inference 實現大語言模型的高吞吐文本生成

溫馨提示: 本篇文章已同步至"AI專題精講" DeepSpeed-FastGen:通過 MII 和 DeepSpeed-Inference 實現大語言模型的高吞吐文本生成 摘要 隨著大語言模型(LLM)被廣泛應用,其部署與擴展變得至關重要&#xff0…

操作系統:操作系統的結構(Structures of Operating System)

目錄 簡單結構(Simple Structure) 整體式結構(Monolithic Structure) 什么是 Kernel(內核)? 層次結構(Layered Structure) 微內核結構(Microkernel&#x…

Python柱狀圖

1.各國GDP柱狀圖2.各國GDP時間線柱狀圖

FastGPT:企業級智能問答系統,讓知識庫觸手可及

在信息爆炸的時代,企業如何高效管理和利用海量知識?傳統搜索和文檔庫已難以滿足需求。FastGPT正成為企業構建智能知識核心的首選。一、FastGPT:不止于問答的智能知識引擎FastGPT 顛覆了傳統知識庫的局限,其核心優勢在于&#xff1…

探索 MyBatis-Plus

引言在當今的 Java 開發領域,數據庫操作是一個至關重要的環節。MyBatis 作為一款優秀的持久層框架,已經被廣泛應用。而 MyBatis-Plus 則是在 MyBatis 基礎上進行增強的工具,它簡化了開發流程,提高了開發效率。本文將詳細介紹 MyBa…