ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
19 мая
49262 Топик полностью
Павел В. (24.01.2006 23:07, просмотров: 1) ответил Павел В. на 3 вопроса по ИАРу АВР 4.12В...
Результаты собственных исследований... С непонятного перепугу ИАР делит адрес прямого вызова "CALL ADDR" на 2. Поясню. Итак, зачача: вызывать функцию по адресу 0х004. Ставим оптимизацию в "low", получается несколько некузяво, но вполне работоспособно: 152 (*(void(*)()) 0x0004)(); \ 00000000 E0E4 LDI R30, 4 \ 00000002 E0F0 LDI R31, 0 \ 00000004 9509 ICALL Команда "ICALL" кругом работает нормально, кстати. Теперь выставляем нормальную оптимизацию, получаем: 152 (*(void(*)()) 0x0004)(); \ 00000000 940E0002 CALL 0x04 И все. Хоть уписяйся! Пробовал ассемблерный файл - без разницы. Причем на нечетный адрес ругается сам компилятор "Address must be even". Т.е. ему же делить надо, а оно не делится! Короче, воркарраунд! копирайт мой :-))) Тупо множим все на два и подсовываем компилеру. Для адреса 0003, например: 152 (*(void(*)()) (0x0003*2))(); \ 00000000 940E0003 CALL 0x06 Код "940E0003" вызывает п/п с адреса 0003. Вуаля! Зачем это? Не знаю. Но если компилер пронюхает фиксированный адрес, он вместо ICALL подсунет в два раза меньшее напрямую в CALL, и тогда пипец, приехали. Предупрежден, значит вооружен. Вот только с ФТП вопрос остался...