如何在 ARM 汇编器中使用 C 定义
如何在 ARM 汇编代码中使用外部定义,例如 LONG_MIN 和 LONG_MAX?
假设 my_arm.h 看起来像这样:
int my_arm(int foo);
假设我有一个 my_main.c 如下:
...
#include <limits.h>
#include "my_arm.h"
...
int main (int argc, char *argv[])
{
int foo=0;
...
printf("My arm assembler function returns (%d)\n", my_arm(foo));
...
}
my_arm.s 看起来像这样:
.text
.align 2
.global my_arm
.type my_arm, %function
my_arm:
...
ADDS r1, r1, r2
BVS overflow
...
overflow:
LDR r0, LONG_MAX @ this is probably wrong, how to do it correctly?
BX lr @ return with max value
倒数第二行,我不确定如何正确加载,我隐约记得在某处读过,那我必须在 .global 中定义 LONG_MAX,但无法再找到工作示例的链接。
我正在使用arm-linux-gnueabi-gcc版本4.3.2进行编译
==================
更新:感谢建议!不幸的是,我仍然遇到语法问题。
首先,我在 my_arm.S 中创建了一个小头文件 mylimits.h (目前与 .S 位于同一目录中),
#define MY_LONG_MIN 0x80000000
我添加了以下内容:
...
.include "mylimits.h"
...
ldr r7, =MY_LONG_MIN @ when it was working it was ldr r7, =0x80000000
...
这种方法有两个问题。
首先是最大的问题:符号 MY_LONG_MIN 无法识别...所以有些东西仍然不对
第二:.include 的语法不允许我包含
,我必须添加mylimits.h 中的内容似乎有点混乱,但我想,没关系:)
有什么指示吗?
我可以访问 ARM 系统开发人员指南设计和优化系统软件[2004] 和 ARM 架构 参考手册[2000],我的目标是 XScale-IXP42x Family rev 2 (v5l)。
How can I use external defines such as LONG_MIN and LONG_MAX in ARM assembler code?
Let's say my_arm.h looks like this:
int my_arm(int foo);
Let's say I have a my_main.c as follows:
...
#include <limits.h>
#include "my_arm.h"
...
int main (int argc, char *argv[])
{
int foo=0;
...
printf("My arm assembler function returns (%d)\n", my_arm(foo));
...
}
And my_arm.s looks like this:
.text
.align 2
.global my_arm
.type my_arm, %function
my_arm:
...
ADDS r1, r1, r2
BVS overflow
...
overflow:
LDR r0, LONG_MAX @ this is probably wrong, how to do it correctly?
BX lr @ return with max value
The second to last line, I am not sure how to load correctly, I vaguely remember reading somewhere, that I had to define LONG_MAX in .global, but can't find the link to a working example anymore.
I am compiling with arm-linux-gnueabi-gcc version 4.3.2
==================
UPDATE: Appreciate the suggestions! Unfortunately, I am still having trouble with syntax.
First, I made a little header file mylimits.h (for now in same dir as .S)
#define MY_LONG_MIN 0x80000000
in my_arm.S i added the following:
...
.include "mylimits.h"
...
ldr r7, =MY_LONG_MIN @ when it was working it was ldr r7, =0x80000000
...
Two problems with this approach.
First the biggest problem: the symbol MY_LONG_MIN is not recognized...so something is still not right
Second: syntax for .include does not let me include <limits.h>
, I would have to add that in mylimits.h, seems a bit kludgy, but I suppose, that is ok :)
Any pointers?
I have access to ARM System Developer’s Guide Designing and Optimizing System Software[2004] and ARM Architecture
Reference Manual[2000], my target is XScale-IXP42x Family rev 2 (v5l) though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常,小写文件扩展名
.s
暗示汇编程序不应通过 c 预处理器,而大写扩展名.S
暗示它应该通过。不过,这取决于您的编译器是否遵循此约定(gcc 端口通常这样做),因此请检查其文档。
(编辑:请注意,这意味着您可以使用 #include 指令 - 但请记住,您要包含的大多数文件通常不是有效的汇编程序(除非它们完全由
#define
itions 组成),因此您可能必须编写自己的头文件,即)5年后编辑:
请注意,armcc v5编译器在linux下遵循此行为...但在windows上则不然。
Often the lowercase file extension
.s
implies that assembler should not be passed through the c preprocessor, whereas the uppercase extension.S
implies that it should.It's up to your compiler to follow this convention though (gcc ports normally do), so check its documentation.
(EDIT: note that this means you can use #include directives - but remember that most of the files you would include would not normally be valid assembler (unless they consist entirely of
#define
itions), so you may have to write your own header that is)edit 5 years later:
Note that the armcc v5 compiler follows this behaviour under linux... but not on windows.
如果您使用 gcc 及其汇编器,则很简单:使用最后的
.S
命名文件,然后在开头添加#include
并使用无论您在哪里需要常量,例如ldr r0, SOMETHING
;我用 x86 做了测试,因为它是我所拥有的,但同样有效,因为它是 gcc 功能。If you are using gcc and its assembler, it is straightforward: name the file with final
.S
, then add at the beginning#include <limits.h>
and use wherever you need the constant, e.g.ldr r0, SOMETHING
; I did tests with x86 since it is what I have, but the same works since it is a gcc feature.我最终做的是这样的:
在 my_main.c 中,
然后在 my_arm.S 中
它看起来很复杂,而且确实如此(加上这种方法的可移植性增益是值得怀疑的)。
必须有一种方法可以在汇编中直接访问 LONG_MAX。这样我很乐意接受作为完整的答案。
What I ended up doing is this:
in my_main.c
then in my_arm.S
It looks convuluted and it is(plus the portability gains are questionable in this approach).
There must be a way to access LONG_MAX directly in assembly. Such a way I would gladly accept as the full answer.
我已经看到,简单地向 gcc 提供汇编源代码与 Gas 就可以让你在汇编程序中做类似 C 的事情。当你遇到必须使用 gcc 作为 Gas 前端才能让某些东西工作的情况时,实际上有点可怕,但那是另一个故事了。
I have seen simply feeding gcc the assembler source vs gas will allow you to do C like things in assembler. It is actually a bit scary when you come across situations where you must use gcc as a front end to gas to get something to work, but that is another story.
使用 --cpreproc 作为 armasm 选项并添加
到 my_arm.s 中。
它适用于 Keil ARM
use --cpreproc for armasm option and add
into my_arm.s.
it works for Keil ARM