assembly - 如何定义可在 C 中使用的 ARM 汇编函数
问题描述
我已经学习 C 几个月了,现在我开始更深入地研究低级语言 - ARM 汇编,所以,我决定从一个非常基本的项目开始,制作一个汇编文件 .S 定义一个阶乘函数,然后在C中调用和使用。所以我想问一下是否可以使用汇编来定义这样一个复杂的函数,并且可以用作C中的另一个函数?如果您不介意,请给我一个简单的 .S 文件示例,其中一个函数从标准输入 num1 和 num2 加载 2 个数字到寄存器,计算 num1*num2 并返回定义的结果,可以在 C 源代码中使用文件?
感谢您的阅读。如果这个问题是愚蠢的,至少,请给我一个方向,以便我可以自己跟随并找出它。
解决方案
要从 C 中使用用 Assembler 编写的函数,您主要需要:
- 在 C 中声明但不定义函数。
- 坚持 ARM 调用约定。
宣言
声明很容易,例如:
int add(int a, int b);
这是一个声明,因为它不包括函数体。当然,名称(在本例中为add)必须匹配。
如果在 C++ 中使用它,则必须添加extern "C"
:
extern "C" int add(int a, int b);
调用约定
调用约定定义了如何将参数传递给函数并从函数返回,以及必须保存哪些寄存器。你需要熟悉细节。可以在ARM (A32) 调用约定中找到简化的概述。
一个超短且非常简化的版本是:
- 前四个参数在 R0 中传递给 R3,其余的在堆栈中传递。
- 返回值在 R0 中返回。
- 必须保存和恢复 R0 至 R3 以外的寄存器。
上述函数的一个简单实现是:
add:
add r0, r0, r1
bx lr
a
在 R0b
中通过,在 R1 中通过。结果以R0
. R3 以上的寄存器不会被保存和恢复,因为它们没有被触及。
更广泛的版本如下所示:
add:
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #12
str r0, [fp, #-8]
str r1, [fp, #-12]
ldr r2, [fp, #-8]
ldr r3, [fp, #-12]
add r3, r2, r3
mov r0, r3
add sp, fp, #0
ldr fp, [sp], #4
bx lr
它基本上是add函数的调试版本:在堆栈上分配空间来存储并作为局部变量,帧指针寄存器 (fp) 指向局部变量。最后,一切都恢复了。a
b
推荐阅读
- java - 无法在 android studio 中解析符号 v7 和 appComapat Activity 导入
- php - 如何将包含空格的字符串作为参数传递给查询的 where 子句
- javascript - 你如何阅读和理解这个位移代码?
- javascript - 从vue js中的数组对象获取数组中的id
- python - 为什么 TikTok 网站会阻止 Selenium chromedriver?
- html - 如何根据容器的背景定位按钮?
- flutter - 无法获取 Flutter AppBar 主题变量
- django - 使用 axios 时,React 和 Nginx 会弄乱 url,API 调用不正确
- java - 为什么要在代码中插入大括号来调用TypeToken的getType方法?
- unity3d - 触发器 Collinder 不适用于 Input.GetKey