[ARM][汇编] 01.基础概念

目录

1.全局标号

1.1.使用方法

1.1.1.声明全局标号

1.1.2.定义全局标号

1.1.3.引用全局标号

1.2.全局标号与局部标号的区别

1.3.注意事项

2.局部标号

2.1.使用方法

2.1.1.定义局部标号

2.1.2.跳转引用

2.2.局部标号与全局标号的对比

2.3.注意事项

3.符号定义伪指令

3.1.变量与数据定义

3.1.1.定义字节 - DCB

3.1.2.定义字 - DCW

3.1.3.定义双字 - DCD

3.2.内存分配与对齐

3.2.1.预留内存空间 - SPACE

3.2.2.内存对齐 - ALIGN

3.2.3.设置起始地址 - ORG

3.3.符号重定义与别名

3.3.1.定义常量 - EQU

3.3.2.定义变量 - SET

3.3.3.宏定义 - MACRO、MEND

3.4.代码段与数据段控制

3.4.1.定义段 - AREA

3.5.外部符号引用

3.5.1.声明外部符号 - IMPORT

3.5.2.导出符号 - EXPORT

3.6. 注意事项

4.程序控制伪指令

4.1.程序入口 - ENTRY

4.2.程序结束 - END

5.条件编译伪指令


1.全局标号

ARM 汇编中,全局标号是可在整个程序范围内被引用的标识符,代表了内存中的一个特定地址,能够指向代码中的某条指令,也可以指向数据段里的某个数据项,全局标号通过 .global 或 .globl 伪指令来声明,其作用如下:

  • 跨文件引用:大型项目中,程序往往会被分割成多个源文件,全局标号能让不同源文件之间相互引用特定的代码或数据,从而实现模块化编程。

  • 链接器识别:链接器在将多个目标文件链接成一个可执行文件时,会利用全局标号来确定不同模块之间的跳转地址和数据引用,保证程序的正确执行。

1.1.使用方法

1.1.1.声明全局标号

使用 .global 或 .globl 伪指令将一个标号 <label> 声明为全局标号,语法如下:

@ 方式一:
.global <label>@ 方式二:
.globl <label>

1.1.2.定义全局标号

全局标号声明后,就可以在代码中定义它,例如,以下代码定义了一个名为 _start 的全局标号,它通常作为程序的入口点:

@ 声明全局标号 _start全局标号
.global _start@ _start 定义
_start:MOV R0, #1MOV R7, #1SWI 0

1.1.3.引用全局标号

在其他文件或代码段中,可直接引用已经声明的全局标号,例如,在另一个文件中调用上述代码中的 _start 标号:

.extern _start @ 引用全局标号 _startB _start   @ 跳转至该全局标号处执行

其中 .extern 伪指令用于声明外部全局标号,表示该标号在其他文件中定义

1.2.全局标号与局部标号的区别

  • 作用域:

    • 全局标号:作用域是整个程序,可以在任何文件或者代码段中被引用。

    • 局部标号:作用域仅限于当前文件或代码段,不能在其他文件中被引用。

  • 声明方式:

    • 全局标号:需要使用 .global 或 .globl 伪指令进行声明。

    • 局部标号:直接在代码中定义,无需额外的声明指令。

1.3.注意事项

  • 命名冲突:使用全局标号时,要确保标号名称在整个程序中是唯一的,避免出现命名冲突,否则,链接器在链接过程中会报错。

  • 标号类型:全局标号既可以指向代码,也可以指向数据,在引用标号时,要明确其类型,确保正确使用。

  • 链接顺序:在链接多个目标文件时,链接器会按照指定的顺序处理这些文件,要保证引用全局标号的文件在链接时能够找到定义该标号的文件。

2.局部标号

ARM 汇编中,局部标号是一种仅在特定范围内有效的标号,与全局标号相对。局部标号仅能在当前文件或代码段内被引用,它代表内存中的一个特定地址,可指向代码中的某条指令,也可指向数据段里的某个数据项,局部标号有如下特点:

  • 作用域局限:局部标号的作用范围仅限于定义它的文件或代码段,在其他文件中无法引用,这使得局部标号具有较好的封装性,能避免不同文件之间的标号命名冲突。

  • 使用灵活:局部标号通常用于标记代码中的临时位置,比如循环的起始和结束位置、条件分支的跳转点等,方便代码的编写和维护。

  • 无需额外声明:和全局标号不同,局部标号不需要使用 .global 或 .globl 伪指令声明,直接在代码中定义即可。

2.1.使用方法

2.1.1.定义局部标号

局部标号由标号名和一个 : 组成,以下代码定义了一个名为 fun_1 的局部标号:

fun_1:MOV R0, #10CMP R0, #20BLE fun_1b  ; 跳转到标号 1 处(向后跳转)

在这个例子中,fun_1 就是一个局部标号,fun_1b 表示向后跳转到标号 fun_1 处。

2.1.2.跳转引用

局部标号主要用于跳转指令,通过指定标号和跳转方向(向前或向后)实现代码的跳转

跳转方向通过 f(forward,向前)或 b(backward,向后)指定,例如:

    MOV R1, #0
fun_2:ADD R1, R1, #1CMP R1, #8BLT fun_2b  ; 若 R1 < 8,向后跳转到标号 fun_2 处继续执行

上面的代码中,当 R1 中的值小于 8 时,向后跳转至标号 fun_2 处继续执行

    MOV R0, #15CMP R0, #8BGT fun_1f  ; 如果 R0 大于 8,向前跳转到标号 fun_3 处继续执行MOV R1, #20
fun_3:ADD R2, R0, R1MOV R7, #1SWI 0  ; 退出程序

上面的代码中,当 R0 中的值大于 8 时,向前跳转至标号 fun_3 处继续执行

2.2.局部标号与全局标号的对比

  • 作用域:

    • 全局标号:作用域是整个程序,可以在任何文件或代码段中被引用。

    • 局部标号:作用域仅限于当前文件或者代码段,不能在其他文件中被引用。

  • 声明方式:

    • 全局标号:需要使用 .global 或 .globl 伪指令进行声明。

    • 局部标号:直接在代码中定义,无需额外的声明指令。

  • 使用场景:

    • 全局标号:常用于定义程序的入口点、公共函数、全局变量等,方便不同文件之间的调用和引用。

    • 局部标号:主要用于标记代码中的临时位置,如循环、分支等,方便代码的控制和跳转。

2.3.注意事项

  • 标号重复使用:由于局部标号的作用域仅限于当前文件或代码段,同一个局部标号可以在不同的代码段中重复使用,但在同一个代码段中不能重复定义。

  • 跳转方向:在使用局部标号进行跳转时,要明确指定跳转方向(f 或 b),否则可能会导致跳转错误。

3.符号定义伪指令

在汇编中,如果要定义变量,则需要用到特定的符号定义伪指令,同时,汇编中也提供了一些伪指令用于修改变量的值或者实现类似 C 语言中宏定义 #define 的功能

3.1.变量与数据定义

3.1.1.定义字节 - DCB

  • 作用:在内存中定义一个或多个字节(8 位)数据,可用于存储字符、数值或二进制数据:

label: DCB value1, value2, ...
  • 示例:

; 定义字符串(ASCII 码)
message: DCB 'H', 'e', 'l', 'l', 'o', 0; 定义数值数组
data_array: DCB 10, 20, 30, 40, 50; 定义二进制数据
flags: DCB 0x01, 0x02, 0x04, 0x08

3.1.2.定义字 - DCW

  • 作用:定义 16 位数据(半字),常用于存储短整数或 16 位常量:

label: DCW value1, value2, ...
  • 示例:

; 定义 16 位整数数组
short_nums: DCW 1000, 2000, 3000; 定义 16 位常量
max_value: DCW 0xFFFF

3.1.3.定义双字 - DCD

  • 作用:定义 32 位数据(双字),常用于存储整数、地址或指针:

label: DCD value1, value2, ...
  • 示例:

; 定义 32 位整数数组
int_array: DCD 1, 2, 3, 4, 5; 定义地址常量
device_addr: DCD 0x40000000; 定义函数指针
func_ptr: DCD my_function  ; 指向 my_function 函数的地址

3.2.内存分配与对齐

3.2.1.预留内存空间 - SPACE

  • 作用:在内存中预留指定字节数的未初始化空间,常用于创建缓冲区:

label: SPACE size_in_bytes
  • 示例:

; 预留 100 字节的缓冲区
buffer: SPACE 100; 预留 4 字节空间(初始值未定义)
temp_var: SPACE 4

3.2.2.内存对齐 - ALIGN

  • 作用:强制后续代码或数据按指定字节对齐(如 2、4、8 字节),优化内存访问效率:

.ALIGN alignment  ; alignment 为 2 的幂(如 2、4、8)
  • 示例:

; 按 4 字节对齐(地址为 4 的倍数)
.ALIGN 4
my_table: DCD 1, 2, 3, 4  ; 确保起始地址是 4 的倍数

3.2.3.设置起始地址 - ORG

  • 作用:指定后续代码或数据在内存中的起始地址,用于定位特定区域:

ORG 0x10000         ; 从地址 0x10000 开始放置数据
config_data:DCB 0x01, 0x02  ; 配置数据将位于 0x10000

3.3.符号重定义与别名

3.3.1.定义常量 - EQU

  • 作用:为常量或表达式定义符号名,类似 C 语言的 #define:

symbol EQU expression
  • 示例:

; 定义数值常量
MAX_SIZE EQU 100
TIMEOUT EQU 5000; 定义寄存器别名
GPIO_BASE EQU 0x40020000
LED_PIN EQU 5; 使用表达式
DELAY_VAL EQU MAX_SIZE * 2

3.3.2.定义变量 - SET

  • 作用:定义可修改的符号值,类似变量,但在汇编时确定具体值:

symbol SET expression
  • 示例:

count SET 0        ; 初始值为 0
count SET count+1  ; 递增(汇编时计算)

3.3.3.宏定义 - MACRO、MEND

  • 作用:定义可复用的代码片段,类似函数但在汇编时展开:

MACRO
$label macro_name $param1, $param2...              ; 宏体(使用 $param1 等参数)
MEND
  • 示例:

MACRO
$label DELAY $countMOV r0, #$count
delay_loop:SUBS r0, r0, #1BNE delay_loop
MEND; 使用宏
DELAY 100            ; 插入 100 次循环的延迟代码

3.4.代码段与数据段控制

3.4.1.定义段 - AREA

  • 作用:将代码或数据分组到不同的内存区域(如 .text、.data、.bss):

AREA name, attributes
  • 示例:

; 代码段(只读、可执行)
AREA my_code, CODE, READONLY
ENTRY             ; 程序入口点
MOV r0, #1        ; 代码指令; 数据段(已初始化数据)
AREA my_data, DATA, READWRITE
my_variable DCD 100  ; 初始值为 100; BSS 段(未初始化数据,仅占位)
AREA my_bss, NOINIT, READWRITE
buffer SPACE 1024  ; 预留 1024 字节未初始化空间

3.5.外部符号引用

3.5.1.声明外部符号 - IMPORT

  • 作用:声明当前文件中使用的、但定义在其他文件中的符号(如函数、变量):

IMPORT printf        ; 声明 printf 函数在其他文件中定义...LDR r0, =messageBL printf        ; 调用外部函数

3.5.2.导出符号 - EXPORT

  • 作用:声明当前文件中定义的符号可被其他文件引用(类似 C 语言的 extern):

EXPORT my_function   ; 导出函数供其他文件使用
my_function:...

3.6. 注意事项

  1. 符号作用域:在 AREA 内定义的符号仅在该区域可见,跨区域需使用全局声明(如 .global)。

  2. 对齐要求:某些架构(如 ARM)要求特定类型的访问(如 32 位数据)必须按 4 字节对齐,否则会触发异常。

  3. 汇编时计算:EQU 和 SET 的值在汇编时确定,无法在运行时修改。

4.程序控制伪指令

4.1.程序入口 - ENTRY

伪指令 ENTRY 标记程序的起始执行地址,通常位于 .text 段:

AREA MyCode, CODE, READONLY
ENTRY                  ; 程序从此处开始执行B main             ; 跳转到主函数

4.2.程序结束 - END

程序结束伪指令 END 标记汇编程序结束,告诉汇编器停止处理后续代码:

END

5.条件编译伪指令

IF、ELSE、ENDIF 使程序可以根据条件选择性地包含或排除代码段,类似 C 语言的 #ifdef:

IF :DEF: DEBUG   ; 如果定义了 DEBUG 符号MOV r0, #1   ; 执行这段代码
ELSEMOV r0, #0   ; 若程序中未定义 DEBUG 符号则执行这段代码
ENDIF

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用远程桌面控制电脑

目的&#xff1a; 通过路由器使用pc控制台式机&#xff0c;实现了有线/无线pc与台式机的双向远程桌面控制 最核心就两条&#xff1a;get ip地址与被控制机器的账户与密码。 现象挺神奇&#xff1a;被控制电脑的电脑桌面处于休眠模式&#xff0c;此时强行唤醒被控电脑会导致中断…

Hive表JOIN性能问

在处理100TB的Hive表JOIN性能问题时&#xff0c;需采用分层优化策略&#xff0c;结合数据分布特征、存储格式和计算引擎特性。以下是系统性优化方案&#xff1a; 1. 数据倾斜优化&#xff08;Skew Join&#xff09; 1.1 识别倾斜键 方法&#xff1a;统计JOIN键的分布频率&…

MongoDB 的核心概念(文档、集合、数据库、BSON)是什么?

MongoDB 是一个面向文档的数据库&#xff0c;它的核心概念与传统的关系型数据库&#xff08;RDBMS&#xff09;有所不同。以下是它的四个主要核心概念&#xff1a; 文档 (Document) 定义&#xff1a; 文档是 MongoDB 中的基本数据单元。它类似于关系型数据库中的一行记录&#…

AI智慧公园管理方案:用科技重塑市民的“夜游体验”

AI智慧公园管理方案&#xff1a;多场景智能巡检与安全防控 一、背景与痛点分析 夏季夜间&#xff0c;公园成为市民休闲娱乐的核心场所&#xff0c;但管理难度随之激增&#xff1a; 宠物管理失控&#xff1a;未牵绳宠物进入园区&#xff0c;随地排泄、惊扰游客&#xff0c;甚…

Spring Cloud Gateway 聚合 Swagger 文档:一站式API管理解决方案

前言 在微服务架构中&#xff0c;随着服务数量的增加&#xff0c;API文档管理变得越来越复杂。每个微服务都有自己的Swagger文档&#xff0c;开发人员需要记住每个服务的文档地址&#xff0c;这无疑增加了开发难度。本文将介绍如何使用Spring Cloud Gateway聚合所有微服务的Sw…

尼康VR镜头防抖模式NORMAL和ACTIVE的区别(私人笔记)

1. NORMAL 模式&#xff08;常规模式&#xff09; 适用场景&#xff1a;一般手持拍摄&#xff0c;比如人像、静物、风景或缓慢平移镜头&#xff08;如水平追拍&#xff09;等。工作特性&#xff1a; 补偿手抖引起的小幅度震动&#xff08;比如手持时自然的不稳&#xff09;&am…

Babylon.js学习之路《四、Babylon.js 中的相机(Camera)与视角控制》

文章目录 1. 引言&#xff1a;为什么相机是 3D 场景的“眼睛”&#xff1f;1.1 相机的核心作用1.2 常见相机类型概览 2. 相机基础参数解析2.1 通用属性2.2 相机坐标系 3. 详解常用相机类型3.1 自由相机&#xff08;FreeCamera&#xff09;3.2 弧形旋转相机&#xff08;ArcRotat…

【Python】普通方法、类方法和静态方法的区分

Python 中普通方法、类方法和静态方法的区分 下面我将从多个维度对这三种方法进行详细对比&#xff0c;并通过示例说明它们的使用场景和区别。 1. 核心区别总结 特性普通方法(实例方法)类方法(classmethod)静态方法(staticmethod)定义装饰器无classmethodstaticmethod第一个…

geoserver发布arcgis瓦片地图服务(最新版本)

第一步&#xff1a;下载geoserver服务&#xff0c;进入bin目录启动 需要提前安装好JDK环境&#xff0c;1.8及以上版本 安装完成&#xff0c;页面访问端口&#xff0c;进入控制台界面,默认用户名密码admin/geoserver 第二步&#xff1a;下载地图 破解版全能电子地图下载器&…

Linux服务之lvs集群与dr模式部署

目录 一.lvs相关概述 1.lvs集群的工作模式 2.lvs调度算法 3.ipvsadm工具 二.DR模式部署 一.lvs相关概述 1.lvs集群的工作模式 lvs-nat&#xff1a;修改请求报文的目标IP,多目标IP的DNAT lvs-dr&#xff1a;操纵封装新的MAC地址&#xff08;直接路由&#xff09;lvs-tu…

OFCMS代码审计-freemaker注入sql注入xxexss文件上传

环境搭建 下载地址&#xff1a;https://gitee.com/oufu/ofcms/repository/archive/V1.1.2?formatzip SSTI模板注入&#xff08;freemaker) FreeMarker模板注入实现远程命令执行 - Eleven_Liu - 博客园 在admin中找到这个 发现请求的是这个 找到他 <#assign value"f…

一键部署NSFW检测模型:快速识别并过滤敏感图片内容

以下是对nsfw_detector的简单介绍&#xff1a; nsfw_detector是一个 NSFW 内容检测器&#xff0c;支持快速docker私有部署&#xff0c;提供API服务低资源消耗&#xff0c;2GB内存即可运行该模型&#xff0c;多核CPU自动调度加速推理 - 可以识别多种文件类型&#xff1a;图片、…

【Redis】缓存穿透、缓存雪崩、缓存击穿

1.缓存穿透 是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;导致请求直接穿透缓存到达数据库&#xff0c;给数据库带来压力的情况。 常见的解决方案有两种&#xff1a; 缓存空对象&#xff1a;实现简单&#xff0c;维护方便&am…

【C】初阶数据结构15 -- 计数排序与稳定性分析

本文主要讲解七大排序算法之外的另一种排序算法 -- 计数排序 目录 1 计数排序 1&#xff09; 算法思想 2&#xff09; 代码 3&#xff09; 时间复杂度与空间复杂度分析 &#xff08;1&#xff09; 时间复杂度 &#xff08;2&#xff09; 空间复杂度 4&#xff09; 计…

mysql的一个缺点

最近再移植一个从oracle转mysql的项目&#xff0c;喜提一个报错&#xff1a; You cant specify target table A016 for update in FROM clause 对应的程序代码&#xff1a; public void setCurrent(String setId, String pk, String userId) throws SysException {String[]…

Ubuntu 上安装 FTP 服务、开放指定端口并创建用户

一、安装 FTP 服务&#xff08;vsftpd&#xff09; sudo apt update sudo apt install vsftpd -y二、修改 vsftpd 配置&#xff0c;使用 21000 端口 编辑配置文件&#xff1a; sudo nano /etc/vsftpd.conf修改或添加以下配置&#xff1a; 使用以下配置文件需要修改的地方:l…

用自写的jQuery库+Ajax实现了省市联动

1. 省市联动&#xff1a;在网页上&#xff0c;选择对应的省份之后&#xff0c;动态的关联出该省份对应的市。选择对应的市之后&#xff0c;动态地关联出城市对应的区。 2. 设计数据库表 t_area &#xff08;区域表&#xff09; id(PK-自增) code name pcode ------------…

【行为型之迭代器模式】游戏开发实战——Unity高效集合遍历与场景管理的架构精髓

文章目录 &#x1f504; 迭代器模式&#xff08;Iterator Pattern&#xff09;深度解析一、模式本质与核心价值二、经典UML结构三、Unity实战代码&#xff08;背包系统遍历&#xff09;1. 定义迭代器与聚合接口2. 实现具体聚合类&#xff08;背包物品集合&#xff09;3. 实现具…

18前端项目----Vue项目收尾优化|重要知识

收尾/知识点汇总 项目收尾二级路由未登录全局路由守卫路由独享守卫图片懒加载路由懒加载打包上线 重要知识点汇总组件通信方式1. props2. 自定义事件3. 全局事件总线4. 订阅与发布pubsub5. Vuex6. 插槽 sync修饰符attrs和listeners属性children和parent属性mixin混入作用域插槽…

【Linux】基础指令(Ⅱ)

目录 1. mv指令 2. cat指令 3.echo指令 补&#xff1a;输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳&#xff1a; 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法&#xff1a;mv [选项]... 源文件/目录 目标文件/目录 …