当前位置: 首页 > news >正文

【ARM64 常见汇编指令学习 12 -- ARM 汇编函数 的学习】

文章目录

    • 1.1 ARM 汇编函数简介
      • 1.1.1 ARM 汇编标签 Label
      • 1.1.2 ARM 汇编函数属性指令
      • 1.1.3 UEFI 中的函数宏:ASM_FUNC
        • 1.1.3.1 UEFI ASM_FUNC 实现汇编函数
      • 1.1.4 UEFI 预编译前缀宏 ASM_PFX

上篇文章:ARM64 常见汇编指令学习 11 – ARM 汇编宏 .macro 的学习

1.1 ARM 汇编函数简介

ARM汇编中的函数定义并不像高级语言那样有特定的语法,但通常可以通过 标签(label)子程序调用指令 (如BL,BLX) 来实现类似于函数的功能。

例如,下面的代码定义了一个名为 my_function 的 “函数”,它接受一个参数(通过寄存器r0传递),将其值增加 1后返回:

my_function: add r0, r0, #1 bx lr

在这里,my_function 是一个标签,表示这个函数的入口点。add r0, r0, #1是函数的主体,它将寄存器 r0 的值增加 1。最后,bx lr是函数的退出语句,它将执行权返回给调用者。

这个函数可以通过 BL 指令来调用,例如:

mov r0, #5 
bl my_function

在这里,mov r0, #5 将值5加载到寄存器r0中,然后bl my_function跳转到my_function标签处执行代码,同时将返回地址(即下一条指令的地址)保存到链接寄存器lr中。

需要注意的是,这只是最基本的情况。在实际的ARM汇编代码中,函数可能会更复杂,包括更多的寄存器操作、保存和恢复现场、处理函数调用堆栈等。

1.1.1 ARM 汇编标签 Label

在ARM汇编中,标签(Label)是用来标记代码中某一位置的一种机制。标签后面通常跟着一个冒号(:),然后在其后可以是一条或多条汇编指令。我们可以使用标签来作为跳转指令(如b,beq等)的目标,或者作为数据的引用。

例如下面的代码:

start: mov r0, #10 add r1, r0, #5 loop: subs r0, r0, #1 bne loop

在这个代码中,"start"和"loop"就是两个标签。我们可以看到,在"loop"标签后面,有一个循环,它会一直执行,直到r0的值为0为止。

注意,不能在两个不同的地方定义相同名字的标签。而且,标签名是大小写敏感的,也就是说,"Loop"和"loop"是两个不同的标签。

1.1.2 ARM 汇编函数属性指令

在 ARM 汇编中,“.global”,“.section”,".type"都是汇编器指令,它们用于指示汇编器如何处理随后的汇编代码。

  • .global”:它用于声明一个全局标签,也就是说这个标签可以在其他的汇编文件中引用。例如,".global my_func"声明了一个名为my_func的全局标签。

  • .section”:它用于指定接下来的代码或数据应该放在哪个段(section)中。例如,“.section .text"指定接下来的代码应该放在名为".text"的段中。在链接过程中,链接器会将同名的段合并在一起。在”.section"指令后面通常会跟着一个段名,以及一些可选的段属性,如 ,“ax” 段属性,表示这个段是可以执行的(‘x’)和可以读写的(‘a’)。

  • .type”:它用于指定一个符号(通常是一个标签)的类型,这对链接器解析符号的方式有所影响。例如,“.type my_func, %function"指定 my_func 是一个函数类型的符号。”%function"是 GNU汇编器的一个预定义符号类型,表示这个符号是一个函数。这对链接器以及某些调试工具是有用的,它们可以通过这个类型信息来正确地处理这个符号

以下是一个简单的函数定义的例子:

.global    my_func 
.type      my_func, %function 
.section   .text my_func: mov r0, #1 bx lr

在这个例子中,我们定义了一个名为 my_func 的全局函数,这个函数在.text段中,函数的功能是将1放入r0寄存器,然后返回。

1.1.3 UEFI 中的函数宏:ASM_FUNC

见:edk2/ArmPkg/Include/AsmMacroIoLibV8.h

#define _ASM_FUNC(Name, Section)    \.global   Name                  ; \.section  #Section, "ax"        ; \.type     Name, %function       ; \Name:#define ASM_FUNC(Name)  _ASM_FUNC(ASM_PFX(Name), .text. ## Name)

#Section 中的 # 的作用是讲将 Section 字符串化,就是将 _ASM_FUNC 中的 .text 转换成字符串;

1.1.3.1 UEFI ASM_FUNC 实现汇编函数

//x0 postcode value
ASM_FUNC (PostCode_S)mov x24, x1mov x1, #0x87000000str x0,[x1]mov x1, x24ret

1.1.4 UEFI 预编译前缀宏 ASM_PFX

关于宏 ASM_PFX 的定义如下(edk2/MdePkg/Include/Base.h):

//
// For symbol name in assembly code, an extra "_" is sometimes necessary
/////
/// Private worker functions for ASM_PFX()
///
#define _CONCATENATE(a, b)   __CONCATENATE(a, b)
#define __CONCATENATE(a, b)  a ## b///
/// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix
/// on symbols in assembly language.
///
#define ASM_PFX(name)  _CONCATENATE (__USER_LABEL_PREFIX__, name)

从上面的定义可以看出最后是给 ASM_PFX(name) 中的 name 加了一个 __USER_LABEL_PREFIX__ 前缀。

GNU C中,“__USER_LABEL_PREFIX__” 是一个预定义宏,它的值代表了在该编译环境中用户定义的标签前缀。

在某些平台和编译器中,用户定义的函数和变量在汇编层面需要添加一个前缀。例如,在许多 UNIX 系统中,用户定义的标签需要添加一个下划线"_"作为前缀。

例如,如果你在 C 代码中定义了一个函数"my_function",那么在生成的汇编代码中,这个函数的名称会变成"_my_function"。

在这种情况下,“__USER_LABEL_PREFIX__“的值就会被定义为”_”。然而,在不需要添加前缀的环境中,"__USER_LABEL_PREFIX__"的值就会被定义为空。

这个宏在处理跨平台代码时很有用,特别是需要直接编写汇编代码时,可以通过这个宏来正确地引用C函数或变量,避免平台差异带来的问题。

例如:

void my_function(void); 
asm(".global " __user_label_prefix__ "my_function");

这段代码在需要添加前缀的环境中会被扩展为".global _my_function",而在不需要添加前缀的环境中会被扩展为".global my_function"。

在 UEFI 的代码edk2/MdePkg/Include/AArch64/ProcessorBind.h中可以看到 __USER_LABEL_PREFIX__ 定义为空:

#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__
#endif

上篇文章:ARM64 常见汇编指令学习 11 – ARM 汇编宏 .macro 的学习

相关文章:

【ARM64 常见汇编指令学习 12 -- ARM 汇编函数 的学习】

文章目录 1.1 ARM 汇编函数简介1.1.1 ARM 汇编标签 Label1.1.2 ARM 汇编函数属性指令1.1.3 UEFI 中的函数宏:ASM_FUNC1.1.3.1 UEFI ASM_FUNC 实现汇编函数 1.1.4 UEFI 预编译前缀宏 ASM_PFX 上篇文章:ARM64 常见汇编指令学习 11 – ARM 汇编宏 .macro 的…...

linux下软件安装 - 与GPT对话

1 cmake 没有uninstall 你是对的,CMake 默认情况下并没有提供 make uninstall 目标。这是因为 make install 操作是在特定的目录下进行安装的,CMake 不知道安装到了哪里以及哪些文件被安装了。因此,没有直接支持的 make uninstall 目标来进行卸载。 如果你想要卸载通过 mak…...

idea 2023 新版ui中git的相关操作

前两个月换了新电脑,下了最新版的idea发现可以切换一套新的ui了 切换新ui肯定不太习惯,很多操作都得重新摸索一下 在这里记录几个git相关的操作 忽略我下面截图中当前项目是js的后端项目…… 切换ui 首先说一下怎么切换新旧版ui,我这里就…...

vue3—SCSS的安装、配置与使用

SCSS 安装 使用npm安装scss: npm install sass sass-loader --save-dev 配置 配置到全局 🌟附赠代码🌟 css: {preprocessorOptions: {scss: {additionalData:import "./src/Function/Easy_I_Function/Echarts/ToSeeEcharts/utill.…...

Godot 4 源码分析 - Path2D与PathFollow2D

学习演示项目dodge_the_creeps,发现里面多了一个Path2D与PathFollow2D 研究GDScript代码发现,它主要用于随机生成Mob var mob_spawn_location get_node(^"MobPath/MobSpawnLocation")mob_spawn_location.progress randi()# Set the mobs dir…...

ardupilot 中坐标变换矩阵和坐标系变换矩阵区别

目录 文章目录 目录摘要1.坐标变换矩阵与坐标系变换矩阵摘要 本节主要记录ardupilot 中坐标变换矩阵和坐标系变换矩阵的区别,这里非常重要,特别是进行姿态误差计算时,如果理解错误,很难搞明白后面算法。 1.坐标变换矩阵与坐标系变换矩阵 坐标变换矩阵的本质含义:是可以把…...

VR内容研发公司 | VR流感病毒实验虚拟现实课件

由广州华锐互动开发的《VR流感病毒实验虚拟现实课件》是一种新型的教学模式,可以为学生提供更加真实和直观的流感病毒分离鉴定实验操作体验,从而提高学生的实验技能和工作效率。 《VR流感病毒实验虚拟现实课件》涉及了生物安全二级实验室(BSL-2)和流感病…...

python——案例10:认识if、elif、else

案例10:认识if、elif、elsenumfloat(input("输入数值:")) #用户输入数字if num>0:print("正数")elif num0:print("零") else:print("负数")#输出结果如下:输入数值:-1 负数 输入数值…...

Hadoop中命令检查hdfs的文件是否存在

Hadoop中命令检查hdfs的文件是否存在 在Hadoop中,可以使用以下命令检查HDFS文件是否存在: hadoop fs -test -e 其中,是要检查的HDFS文件的路径。 如果文件存在,命令返回0;如果文件不存在,命令返回非0值…...

计算机网络用户接入层设计

用户接入层为用户提供访问核心网络的能力, 为用户提供共享/交换的带宽分配,按照业主要求,并考虑到端口密度的要求以及 设备的性能价格比,建议选用 Catalyst 3524XL和 Catalyst 3548XL 工作组交换 机,分别放置于配线间中。如同一配线间需两台以…...

全志F1C200S嵌入式驱动开发(应用程序开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 我们在开发soc驱动的时候,很多情况下也要验证下当前的驱动功能是否正确。当然除了验证驱动功能之外,我们还要编写业务代码和流程代码。这中间就和各行各业有关了,有的是算法,有…...

人工智能学习07--pytorch23--目标检测:Deformable-DETR训练自己的数据集

参考 https://blog.csdn.net/qq_44808827/article/details/125326909https://blog.csdn.net/dystsp/article/details/125949720?utm_mediumdistribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-125949720-blog-125326909.235^v38^pc_releva…...

Statefulset 实战 1

上一部分与大家分享到 Statefulset 与 RplicaSet 的区别,以及 Statefulset 的特点,能做的一些事情及一些注意事项 现在我们来尝试使用 Statefulset 来部署我们的应用,我们可以需要有应用程序,然后有持久化卷 开始使用 Statefuls…...

没有jodatime,rust怎么方便高效的操作时间呢?

关注我,学习Rust不迷路!! 当使用Rust进行日期操作时,可以使用 chrono 库。下面给出了二十个常见的日期操作的例子: 1. 获取当前日期和时间: use chrono::prelude::*;let current_datetime Local::now()…...

如何把pdf转成cad版本?这种转换方法非常简单

将PDF转换成CAD格式的优势在于,CAD格式通常是用于工程设计和绘图的标准格式。这种格式的文件可以在计算机上进行编辑和修改,而不需要纸质副本。此外,CAD文件通常可以与其他CAD软件进行交互,从而使得工程设计和绘图过程更加高效和精…...

MySQL常用函数方法

字符串函数 函数描述举例left(str, length)从左开始截取字符串,截取length个left(2023-08-04, 7) 2023-08right(str, length)从右开始截取字符串,截取length个 right(2023-08-04, 5) 08-04 substring(str, pos, length) substring(被截取字…...

Linux命令200例专栏导读:实用指南助你成为Linux大师

🏆作者简介,黑夜开发者,全栈领域新星创作者✌,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已…...

ICN6202 MIPIDSI转LVDS桥接芯片的功能及特征 调试文档资料

产品特征功能: 输入:MIPI DSI 支持MIPI D-PHY Version 1.00.00 和 MIPI DSI Version 1.02.00. 可接收MIPI DSI 18bpp RGB666 and 24bpp RGB888 packets 4 lane data1 lane clock 4对数据线可以选择1、2、3、4lane data 每对差分数据传输线最大可…...

vscode 格式问题

1、EditorConfig for VS Code 插件 shift alt f 格式化文件(VS Code格式化按键),如下图,每个缩进4空格 代码如下 创建文件名 .editorconfig root true [*] charset utf-8 indent_style space indent_size 2 end_of_…...

OPENCV C++(三)二值化灰度函数+调用摄像头+鼠标响应+肤色检测

RGB转灰度函数 cvtColor(image, gray, COLOR_BGR2GRAY); 图像 目标图像 rgb转灰度 大津法二值化函数 threshold(gray, result1, 84, 255, THRESH_OTSU); 灰度图,目标图,阈值,大于阈值的转换的像素值,方法为大津法 自适应二值…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

synchronized 学习

学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

今日科技热点速览

🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...