如何将C全局数组的大小放入为GCC编译的AVR架构编写的汇编程序中?

发布于 2024-08-19 17:05:28 字数 402 浏览 13 评论 0原文

我有一个包含以下内容的 .c 文件。

uint8_t buffer[32]

我有一个 .S 文件,我想在其中执行以下操作。

cpi r29, buffer+sizeof(buffer)

cpi 的第二个参数必须是立即值,而不是位置。但不幸的是 sizeof() 是一个 C 运算符。两个文件都被编译为单独的目标文件,然后链接在一起。

如果我执行 avr-objdump -x file.c 等操作,我会得到缓冲区的大小。所以它已经在目标文件中可用。

如何在编译时访问汇编文件中的缓冲区大小?

I have a .c file with the following.

uint8_t buffer[32]

I have a .S file where I want to do the following.

cpi r29, buffer+sizeof(buffer)

The second argument for cpi must be an immediate value, not a location. But unfortunately sizeof() is a C operator. Both files are compiled to separate object files and linked together afterwards.

If I do avr-objdump -x file.c, amongst other things, I get the size of the buffer. So it is already available in the object file.

How do I access the size of the buffer in my assembly file at compile time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

琴流音 2024-08-26 17:05:28

为什么不简单地将数组的长度放入 #define 中——即仅

#define BUFFER_SIZE 32

#include (.include) 头文件中 使用在 cS 文件中。

Why not simply put the length of the array into a #define -- i.e. just use

#define BUFFER_SIZE 32

in a header file you #include (.include) in both the c and S file.

樱娆 2024-08-26 17:05:28

在链接器运行之前,另一个文件中符号的大小将不可见;此时汇编程序已经完成。获得您想要的*的唯一方法是使其成为两个文件都包含的常量。

* 假设您需要它作为汇编程序立即值。

The size of a symbol in another file won't be visible until the linker runs; by this time the assembler is already finished. The only way to get what you want* is by making it a constant, included by both files.

* assuming you need it to be an assembler immediate value.

澉约 2024-08-26 17:05:28
uint8_t buffer[32];
const uint8_t* buf_end;
buf_end = buffer+sizeof(buffer);

然后

cpi r29, buf_end
uint8_t buffer[32];
const uint8_t* buf_end;
buf_end = buffer+sizeof(buffer);

then

cpi r29, buf_end
沦落红尘 2024-08-26 17:05:28

如果您可以告诉您的 C 编译器可靠地在 uint32_t buffer[32]; 之后立即放置一些标签(或变量)buffer_end,您的汇编语言代码就可以使用该< code>buffer_end 引用,而不是笨拙地让链接器添加两个值。

如果您在 .S 文件中定义缓冲区,那么做类似的事情很容易,但在 .c 文件中就不那么容易了。

FWIW,.o 文件可能包含一些大小信息。我从一个带有二进制数据的文件生成一个 .o 文件,用于我的一个系统:

$ avr-objcopy -B avr -I binary -O elf32-avr --readonly-text --rename-section .data=.text,contents,alloc,load,readonly,code foo.bin foo.o

这给了我一个 foo.o ,它在 nm foo 之后生成以下内容。 o

00000c00 T _binary_foo_bin_end
00000c00 A _binary_foo_bin_size
00000000 T _binary_foo_bin_start

如果 _binary_foo_bin_size 的类型可以适应您的情况,那么它可能会很有用 - 如果您毕竟需要 buffer_end 标签上的大小。

顺便说一句,如果您正在为具有超过 256 字节 SRAM 的 AVR 芯片之一编写代码,您的代码可能需要正确使用 lo8/hi8 宏测试所有 16 个地址位。

If you can tell your C compiler to reliably put some label (or variable) buffer_end immediately after the uint32_t buffer[32];, your assembly language code can just use that buffer_end reference instead of awkwardly having the linker add two values.

It is easy to do something like that if you define your buffer in a .S file, but not so easy in a .c file.

FWIW, it may be possible that .o files contain some size information. I generate a .o file from a with with binary data for one of my systems:

$ avr-objcopy -B avr -I binary -O elf32-avr --readonly-text --rename-section .data=.text,contents,alloc,load,readonly,code foo.bin foo.o

This gives me a foo.o which produces the following after nm foo.o:

00000c00 T _binary_foo_bin_end
00000c00 A _binary_foo_bin_size
00000000 T _binary_foo_bin_start

The type of _binary_foo_bin_size might be useful if it can be adapted to your case - if you do need the size over the buffer_end label after all.

BTW, if you are writing for one of the AVR chips which have more than 256 bytes of SRAM, your code will probably need to make proper use of the lo8/hi8 macros to test all 16 address bits.

带刺的爱情 2024-08-26 17:05:28
uint32_t sizeofbuffer = sizeof(buffer);

那么

cpi r29, buffer+sizeofbuffer

这应该可行。

uint32_t sizeofbuffer = sizeof(buffer);

then

cpi r29, buffer+sizeofbuffer

This should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文