English 中文(简体)
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 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.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签