реклама на сайте
подробности

 
 
> Ошибки компилятора, или сам дурак?
Sergio66
сообщение Feb 12 2013, 09:35
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Имеется
IAR C/C++ Compiler for AVR
6.11.1 (6.11.1.50453)
Имеется код (см ниже). Проблема в том, что переменная, которая передается в качестве параметра в функцию, портится этой самой функцией. Переменная хранится а R25, передается нормально... Но вызываемая функция, использую данный регистр, не сохраняет его...
Вот код:
Код
37:                      if (LoadAppSec(currentFlash-1)) {
+00003C19:   2F09        MOV       R16,R25        Copy register
+00003C1A:   D136        RCALL     PC+0x0137      Relative call subroutine
+00003C1B:   2300        TST       R16            Test for Zero or Minus
+00003C1C:   F081        BREQ      PC+0x11        Branch if equal
.............................................................................


Вот эта функция - LoadAppSec -> RCALL PC+0x0137

CODE
415: bool LoadAppSec(UCHAR flash)
416: {
+00003D51: 938A ST -Y,R24 Store indirect and predecrement
+00003D52: 2F80 MOV R24,R16 Copy register
419: cnt = 0;
+00003D53: E000 LDI R16,0x00 Load immediate
+00003D54: E7E7 LDI R30,0x77 Load immediate
+00003D55: E0F2 LDI R31,0x02 Load immediate
+00003D56: D00B RCALL PC+0x000C Relative call subroutine
420: Beep();
+00003D57: DE79 RCALL PC-0x0186 Relative call subroutine
421: print_s_(Start_Load);
+00003D58: E60E LDI R16,0x6E Load immediate
+00003D59: E710 LDI R17,0x70 Load immediate
+00003D5A: DF9B RCALL PC-0x0064 Relative call subroutine
422: FLASH_READY_LED_ON;
+00003D5B: 9AC3 SBI 0x18,3 Set bit in I/O register
423: res = loader(flash);
+00003D5C: 2F08 MOV R16,R24 Copy register
+00003D5D: 940E3DA9 CALL 0x00003DA9 Call subroutine
424: FLASH_READY_LED_OFF;
+00003D5F: 98C3 CBI 0x18,3 Clear bit in I/O register
425: return res;
+00003D60: 9189 LD R24,Y+ Load indirect and postincrement
+00003D61: 9508 RET Subroutine return
@00003D62: ?Subroutine5


В данном случае, регистр R25 не трогается, потому и не сохраняется.
Далее вызывается функция CALL 0x00003DA9 (res = loader(flash))

CODE
+00003DA9: 9760 SBIW R28,0x10 Subtract immediate from word
+00003DAA: 2EE0 MOV R14,R16 Copy register
123: cnt = 0;
+00003DAB: E000 LDI R16,0x00 Load immediate
+00003DAC: E7E7 LDI R30,0x77 Load immediate
+00003DAD: E0F2 LDI R31,0x02 Load immediate
+00003DAE: 8300 STD Z+0,R16 Store indirect with displacement
+00003DAF: 8301 STD Z+1,R16 Store indirect with displacement
+00003DB0: 8302 STD Z+2,R16 Store indirect with displacement
+00003DB1: 8303 STD Z+3,R16 Store indirect with displacement
130: unsigned char *p = chainCipherBlock;
+00003DB2: 019E MOVW R18,R28 Copy register pair
131: unsigned char BOOTFLASH *q = initialVector;
+00003DB3: E000 LDI R16,0x00 Load immediate
+00003DB4: E711 LDI R17,0x71 Load immediate
132: unsigned char n = 16;
+00003DB5: E140 LDI R20,0x10 Load immediate
136: *p++ = *q++;
+00003DB6: 01F8 MOVW R30,R16 Copy register pair
+00003DB7: 9155 LPM R21,Z+ Load program memory and postincrement
+00003DB8: 018F MOVW R16,R30 Copy register pair
+00003DB9: 01F9 MOVW R30,R18 Copy register pair
+00003DBA: 9351 ST Z+,R21 Store indirect and postincrement
+00003DBB: 019F MOVW R18,R30 Copy register pair
138: while (--n);
+00003DBC: 954A DEC R20 Decrement
+00003DBD: F7C1 BRNE PC-0x07 Branch if not equal
141: aesInit( tempbuf ); // Init AES algorithm.
+00003DBE: E900 LDI R16,0x90 Load immediate
+00003DBF: 2E40 MOV R4,R16 Copy register
+00003DC0: E002 LDI R16,0x02 Load immediate
+00003DC1: 2E50 MOV R5,R16 Copy register
+00003DC2: 0182 MOVW R16,R4 Copy register pair
+00003DC3: 940E3B7D CALL 0x00003B7D Call subroutine
148: WDTCR |= (1<<WDTOE) | (1<<WDE) | (1<<WDP0) | (1<<WDP2);
+00003DC5: B501 IN R16,0x21 In from I/O location
+00003DC6: 610D ORI R16,0x1D Logical OR with immediate
+00003DC7: BD01 OUT 0x21,R16 Out to I/O location
160: if (repeat) cnt = previous_frame_address;
+00003DC8: 9100028F LDS R16,0x028F Load direct from data space
+00003DCA: 2300 TST R16 Test for Zero or Minus
+00003DCB: F051 BREQ PC+0x0B Branch if equal
160: if (repeat) cnt = previous_frame_address;
+00003DCC: E8EB LDI R30,0x8B Load immediate
+00003DCD: E0F2 LDI R31,0x02 Load immediate
+00003DCE: D0BB RCALL PC+0x00BC Relative call subroutine
+00003DCF: E7E7 LDI R30,0x77 Load immediate
+00003DD0: E0F2 LDI R31,0x02 Load immediate
+00003DD1: D0BD RCALL PC+0x00BE Relative call subroutine
+00003DD2: C003 RJMP PC+0x0004 Relative jump
335: repeat = 0;
+00003DD3: E000 LDI R16,0x00 Load immediate
+00003DD4: 9300028F STS 0x028F,R16 Store direct to data space
162: previous_frame_address = cnt;
+00003DD6: E7E7 LDI R30,0x77 Load immediate
+00003DD7: E0F2 LDI R31,0x02 Load immediate
+00003DD8: D0B1 RCALL PC+0x00B2 Relative call subroutine
+00003DD9: E8EB LDI R30,0x8B Load immediate
+00003DDA: E0F2 LDI R31,0x02 Load immediate
+00003DDB: D0B3 RCALL PC+0x00B4 Relative call subroutine
163: __watchdog_reset();
+00003DDC: 95A8 WDR Watchdog reset
164: frameSize = ((frameindex_t)ConvHDToByte(busReceiveByte(repeat, flash),busReceiveByte(0,flash)) << 8) |
165: ConvHDToByte(busReceiveByte(0,flash),busReceiveByte(0,flash));
+00003DDD: D0BA RCALL PC+0x00BB Relative call subroutine
+00003DDE: 9100028F LDS R16,0x028F Load direct from data space
+00003DE0: 940E3EBE CALL 0x00003EBE Call subroutine
+00003DE2: D0A5 RCALL PC+0x00A6 Relative call subroutine
+00003DE3: D0B4 RCALL PC+0x00B5 Relative call subroutine
+00003DE4: D0B0 RCALL PC+0x00B1 Relative call subroutine
+00003DE5: D0A2 RCALL PC+0x00A3 Relative call subroutine
+00003DE6: 2FA0 MOV R26,R16 Copy register
170: unsigned char *p = rxBuffer;
+00003DE7: 0132 MOVW R6,R4 Copy register pair
171: n = frameSize;
+00003DE8: 2FB0 MOV R27,R16 Copy register
173: crc = 0;
+00003DE9: E080 LDI R24,0x00 Load immediate
+00003DEA: E090 LDI R25,0x00 Load immediate


Вот собственно, мне кажется что далее этого места и не нужно.
Видно. что данная ф-я нигде не сохраняет R25? но с успехом его использует...
Что это?
На "Сам дурак" не обижусь... ...если объясните почему...
Спасибо...

Сообщение отредактировал IgorKossak - Feb 12 2013, 21:31
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SSerge
сообщение Feb 12 2013, 11:06
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Разгадка проста.
Параметр в Вашу функцию передаётся в регистре R16 и в нём-же возвращается результат.
Команда MOV R16,R25 перед вызовом копирует из R25 в R16.
В функции первым делом R24 сохраняется в стек(ST -Y,R24), затем R16 копируется в R24 и дальше используется чтобы ещё раз скопировать его в R16 и вызвать функцию loader(). Перед выходом прежнее содержимое R24 восстанавливается из стека(LD R24,Y+).


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Sergio66
сообщение Feb 12 2013, 12:54
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(SSerge @ Feb 12 2013, 15:06) *
Разгадка проста.
Параметр в Вашу функцию передаётся в регистре R16 и в нём-же возвращается результат.
Команда MOV R16,R25 перед вызовом копирует из R25 в R16.
В функции первым делом R24 сохраняется в стек(ST -Y,R24), затем R16 копируется в R24 и дальше используется чтобы ещё раз скопировать его в R16 и вызвать функцию loader(). Перед выходом прежнее содержимое R24 восстанавливается из стека(LD R24,Y+).


1. Команда MOV R16,R25 перед вызовом копирует из R25 в R16. Это не сохранение контекста, а передача параметра. R25 остается со своим содержимым, которое, кстати говоря, есть управляющая переменная цикла while.
2. Насколько мне известно, любая функция, если она затрагивает какие то регистры, должна их сначала сохранять в стеке, а затем, восстанавливать...
3. Вы предложили не разгадку, а описание того, что я итак вижу...
Я хочу понимать, что я не так сделал, что функция меняет значение переменной, определенной на внешнем по отношению к ней уровне.. На мой взгляд, это нонсенс. Скажу больше. Эта программа работала нормально, пока был цикл
flash = 2; (размещена в R25)
while (flash) {
...
flash--;
}

как только я поменял цикл на
do {
...
flash--;
} while (flash)
началась вот такая абракадабра...
Насколько я понимаю, что то работает не так... или компилятор с оптимизатором, или моя голова...
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01468 секунд с 7
ELECTRONIX ©2004-2016