Предположим, что у нас есть следующий фрагмент кода C для avr-8bit:
int v1=1;
int v2=2;
v2=v2+v1;
Я ожидал следующую разборку
ldi r18, 1;
ldi r19, 2;
add r19, r18;
но после того как я побежал:
avr-gcc -mmcu=atmega2560 Test.c -o Test.elf
и
avr-objdump -S Test.elf > Test.lss
Я получил следующую разборку
ldi r24, 0x01 ; 1
ldi r25, 0x00 ; 0
std Y+2, r25 ; 0x02
std Y+1, r24 ; 0x01
ldi r24, 0x02 ; 2
ldi r25, 0x00 ; 0
std Y+4, r25 ; 0x04
std Y+3, r24 ; 0x03
ldd r18, Y+3 ; 0x03
ldd r19, Y+4 ; 0x04
ldd r24, Y+1 ; 0x01
ldd r25, Y+2 ; 0x02
add r24, r18
adc r25, r19
std Y+4, r25 ; 0x04
std Y+3, r24 ; 0x03
Есть ли кто-нибудь, кто может помочь мне понять результат дизассемблера?
Редактировать: Используя char сборка становится:
ldi r24, 0x01
std Y+1, r24
ldi r24, 0x02
std Y+2, r24
ldd r25, Y+2
ldd r24, Y+1
add r24, r25
std Y+2, r24
Когда есть стандартная инструкция?
-O3
может выдавать неработающий код? [цитата нужна] (и нет, код C, который вызывает неопределенное поведение, а затем разрывается с некоторыми настройками оптимизации, не считается)Когда я нашел пример кода, я сделаю свой комментарий ответом - другие уже объяснили проблему.
Много встроенного кода, с которым я работаю, определяет дополнительные типы, которые зависят от их размера, например, «uint8, uint16, uint32» для неподписанных целых. Таким образом, вы всегда точно знаете, с какой переменной вы имеете дело. Особенно в маленьких встроенных, подписанных, плавающих, "int" неопределенного размера / подписи в лучшем случае будет стоить циклов процессора и в худшем случае вызвать серьезные ошибки.
Вот наши текущие #defines:
источник
Ваш код на C использует 16-битные целочисленные переменные (int). Компилятор не может прочитать ваши мысли, поэтому он компилирует именно то, что находится в исходном файле. Итак, если вы хотите 8-битные переменные, вы должны использовать соответствующий тип.
В результате вы все равно получите хранение значений в памяти (хотя и более простое). Я не очень хорош в C, но, IMHO, есть несколько вариантов назначения переменной для некоторого регистра, если вы хотите, чтобы некоторые переменные были в регистрах вместо RAM. Что-то вроде:
Обратите внимание, что не все регистры доступны для таких приемов.
Итак, заключение? Напишите свои программы в сборке. Они всегда будут меньше, быстрее и удобнее для чтения / поддержки.
источник