How to get the size of a C global array into an assembly program written for the AVR architecture compiled with GCC?
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 开发者_JAVA技巧the buffer in my assembly file at compile time?
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.
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.
uint8_t buffer[32];
const uint8_t* buf_end;
buf_end = buffer+sizeof(buffer);
then
cpi r29, buf_end
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.
uint32_t sizeofbuffer = sizeof(buffer);
then
cpi r29, buffer+sizeofbuffer
This should work.
精彩评论