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…