Привет Igor!
02 Mar 06 19:34, Igor Ulanov писал Alex Mogilnikov:
AM>> Покажи пример кода. Со слов что-либо комментировать трудно. AM>> Опять же, не следует ожидать от оптимизатора абсолютно идеального AM>> результата. Если на счету каждая инструкция, пиши на ассемблере.
IU> В том конкретном случае оптимальность не на первом месте. IU> Вот С: IU> uint8_t Read_byte_microlan(void) IU> { ....... IU> }
IU> Вот результат компиляции: IU> uint8_t Read_byte_microlan(void) IU> { ......
В исходном сишном коде я насчитал семь вызовов функций, а в ассемблерном коде не вижу ни одного. Ты что, объявил все эти функции инлайновыми? Как-то это не согласуется с оптимизации по размеру... И ассемблерный текст какой-то странный, не похож на то, что обычно генерит gcc. Вот какой код получился у меня:
Read_byte_microlan: /* prologue: frame size=0 */ push r17 push r28 /* prologue end (size=2) */ ldi r28,lo8(0) ldi r17,lo8(7) .L6: lsr r28 rcall cli rcall microlan_port_down ldi r24,lo8(4) ldi r25,hi8(4) rcall _delay_us rcall microlan_port_up ldi r24,lo8(13) ldi r25,hi8(13) rcall _delay_us lds r24,PINB sbrc r24,0 subi r28,lo8(-(-128)) .L5: rcall sei ldi r22,lo8(0x3d75c28f) ldi r23,hi8(0x3d75c28f) ldi r24,hlo8(0x3d75c28f) ldi r25,hhi8(0x3d75c28f) rcall _delay_ms subi r17,lo8(-(-1)) sbrs r17,7 rjmp .L6 mov r24,r28 clr r25 /* epilogue: frame size=0 */ pop r28 pop r17 ret /* epilogue end (size=3) */
IU> При входе в функцию компилятор заранее инициализирует значения для IU> делау в шести регистрах. К тому же несколько регистров обнуляет IU> командой - mov rx,r1 а несколько ldi rx,0.
По-поводу этих двух команд: они дают одинаковый результат, т.к. avr-gcc обычно в r1 держит 0, и в коде так его и называет - __zero_reg__. Кстати, у меня он им ни разу не воспользовался. Откуда берется ldi rx,0 из моего варианта кода понятно - это загрузка старшего байта константы.
IU> В общем-то конечно терпимо, просто видимо наложилось одно на IU> другое, плюс конец рабочего дня...
IU>>> Программа перестала делать то, что выполняла раньше. AM>> Даю 99.9% за то, что ошибка в программе. IU> Да, так и оказалось. Забыл, что начал изменять программу, когда IU> оторвали от нее. Вчера SVN поставил, поэтому надеюсь, что от подобных IU> случаев буду застрахован.
Сделал ты все правильно, но застрахован не будешь. :) Во-первых, свои ошибки вообще трудно заметить. Во-вторых, ошибка может быть весьма хитрой. В-третьих, она может оказаться вообще не в твоем коде, а в какой-нибудь библиотеке. Вот, кажется, при переходе с gcc-3.1 на gcc-3.3 я получил мертвое зависание при старте давно отлаженной программы. Оказалось, проблема была в библиотечном ctrend.c, имеющем такое содержание:
======== crtend.c ======== typedef void (*fptr)(void);
static fptr ctor_end[1] __attribute__((section(".ctors"), __unused__)) = { 0 }; static fptr dtor_end[1] __attribute__((section(".dtors"), __unused__)) = { 0 }; ==========================
Поскольку ctor_end и dtor_end нигде не использовались, оптимизатор gcc-3.2 их просто выкинул (gcc-3.1 оставлял), в результате таблица конструкторов глобальных объектов оказалась без завершающего нуля, и стартап вис при попытке выполнить мусор.
AM>> 3.4.5 работает без нареканий. Четвертую ветку пока не пробовал. IU> У меня оказывается еще старее - 3.4.3
Фигня, некоторые до сих пор 2.96 используют. А вот четвертую ветку любопытно попробовать, но, наверное, для ARM, т.к. avr я уже практически не использую...
Всего наилучшего, [Team PCAD 2000] Алексей М. ... Владею дыроколом на уровне пользователя.