Павел В. (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, и тогда пипец, приехали. Предупрежден, значит вооружен. Вот только с ФТП вопрос остался...