Как получить размер глобального массива C в программу сборки, написанную для архитектуры AVR, скомпилированной с GCC? - PullRequest
1 голос
/ 01 февраля 2010

У меня есть .c файл со следующим.

uint8_t buffer[32]

У меня есть файл .S, в котором я хочу сделать следующее.

cpi r29, buffer+sizeof(buffer)

Второй аргумент для cpi должен быть непосредственным значением, а не местоположением. Но, к сожалению, sizeof() является оператором C. Оба файла скомпилированы в отдельные объектные файлы и впоследствии связаны между собой.

Если я сделаю avr-objdump -x file.c, среди прочего я получу размер буфера. Так что это уже доступно в объектном файле.

Как получить доступ к размеру буфера в файле сборки во время компиляции?

Ответы [ 5 ]

2 голосов
/ 01 февраля 2010

Размер символа в другом файле не будет виден до запуска компоновщика; к этому времени ассемблер уже закончен. Единственный способ получить то, что вы хотите *, это сделать его константой, включенной в оба файла.

* при условии, что вам нужно непосредственное значение ассемблера.

2 голосов
/ 01 февраля 2010

Почему бы просто не поместить длину массива в #define - т.е. просто использовать

#define BUFFER_SIZE 32

в заголовочном файле вы #include (.include) в файлах c и S.

1 голос
/ 01 февраля 2010
uint8_t buffer[32];
const uint8_t* buf_end;
buf_end = buffer+sizeof(buffer);

тогда

cpi r29, buf_end
0 голосов
/ 05 апреля 2010

Если вы можете сказать своему компилятору C надежно поместить некоторую метку (или переменную) buffer_end сразу после uint32_t buffer[32];, ваш код на ассемблере может просто использовать эту ссылку 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.

Кстати, если вы пишете для одного из чипов AVR, которые имеют более 256 байтов SRAM, ваш код, вероятно, должен будет правильно использовать макросы lo8 / hi8 для проверки всех 16 битов адреса.

0 голосов
/ 01 февраля 2010
uint32_t sizeofbuffer = sizeof(buffer);

тогда

cpi r29, buffer+sizeofbuffer

Это должно работать.

...