Здравствуйте уважаемые форумчане!
У меня проблемка нарисовалась с поддержкой ядер AVR с размером памяти 256к. При обращении к библиотечным функциям с переменным числом параметров (например fprint) компилятор встраивает вызовы к встроенным макросам пролог/эпилог (__prologue_saves__ / __epilogue_restores__ - если быть точным) из библиотеки libgcc.a. Беда в том, что данные для этих макросов, которые готовятся на этапе вызова функций, совершенно не учитывают размера памяти больше чем 128к (64к слов), то есть, инициализируются регистры Z (ZH,ZL), а в макросах используеться инструкция EIJMP, для полноценной работы которой надо еще установить регистр EIND.
Вот и получается, что если библиотечные функции с переменным числов параметров располагаються в адресах выше чем 128к, то вся програма перестает работать.
Решение проблемы - или исправлять libgcc.a (что для меня слишком сложно - я программирующий апаратчик) или заставить линкер располагать эти функции в нижних адресах (а как это сделать я не смог разобраться)...
Может кто подскажет другой вариант?
Я перепробовал все версии WinAVR начиная с 20070122, привожу фрагменты листинга (при компиляции нету ни ошибок ни предупреждений):
Вот одна из библиотечных функций:
00020896 <fprintf_P>:
20896: a0 e0 ldi r26, 0x00 ; 0
20898: b0 e0 ldi r27, 0x00 ; 0
// здесь загружается адрес возврата
// из __prologue_saves__ - это должен быть
// адрес инструкции "ldd r16, Y+8" - 0х0208а2
// а у нас только 0х0451 х 2 = 0х08а2,
// а старшая часть адреса 0х02 нигде не фиксируется!!
2089a: e1 e5 ldi r30, 0x51 ; 81
2089c: f4 e0 ldi r31, 0x04 ; 4
2089e: 0d 94 d9 0c jmp 0x219b2 ; 0x219b2 <__prologue_saves__+0x1c>
208a2: 08 85 ldd r16, Y+8 ; 0x08
208a4: 19 85 ldd r17, Y+9 ; 0x09
а вот злополучная __prologue_saves__ :
00021996 <__prologue_saves__>:
21996: 2f 92 push r2
...
219b4: 1f 93 push r17
219b6: cf 93 push r28
219b8: df 93 push r29
219ba: cd b7 in r28, 0x3d ; 61
219bc: de b7 in r29, 0x3e ; 62
219be: ca 1b sub r28, r26
219c0: db 0b sbc r29, r27
219c2: 0f b6 in r0, 0x3f ; 63
219c4: f8 94 cli
219c6: de bf out 0x3e, r29 ; 62
219c8: 0f be out 0x3f, r0 ; 63
219ca: cd bf out 0x3d, r28 ; 61
219cc: 19 94 eijmp // естественно после этой инструкции мы "улетаем"
// по адресу 0х0008а2 (проверено в отладчике)!
Help!