[an error occurred while processing this directive]
[an error occurred while processing this directive]
|
При использовании кода типа этого:
typedef struct
{
unsigned char size;
unsigned long id;
unsigned char data[8];
}MyStruct_t;
#define _ARRAY_SIZE 4
MyStruct_t bank1 str1[_ARRAY_SIZE];
MyStruct_t bank2 str2[_ARRAY_SIZE];
void main(void)
{
unsigned char i;
for(i = 0; i < _ARRAY_SIZE; i++)
{
str1[i] = str2[i];
}
for(;;);
}
Генерируется следующая последовательность:
23 psect text0
24 07C2 _main
25 ; _i assigned to ?a_main+0
26 0000 _main$i set ?a_main
27 ;TEST.C: 16: unsigned char i;
28 07C2 1283 bcf 3,5
29 07C3 1303 bcf 3,6
30 07C4 01A0 clrf ?a_main
31 07C5 l3
32 ;TEST.C: 19: {
33 ;TEST.C: 20: str1[i] = str2[i];
34 07C5 300D movlw 13
35 07C6 00F2 movwf btemp+1
36 07C7 0820 movf ?a_main,w
37 07C8 120A 118A 27B6 fcall lbmul
38 07CB 3E10 addlw _str2^(0+256)
39 07CC 0084 movwf 4
40 07CD 1783 bsf 3,7
41 07CE 300D movlw 13
42 07CF 00F2 movwf btemp+1
43 07D0 0820 movf ?a_main,w
44 07D1 120A 118A 27B6 fcall lbmul
45 07D4 3EA0 addlw _str1
46 07D5 00F1 movwf btemp
47 07D6 1783 bsf 3,7
48 07D7 0871 movf btemp,w
49 07D8 300D movlw 13
50 07D9 120A 118A 27E4 fcall structbank
+ 120A 118A
51 ;TEST.C: 21: }
52 07DE 0AA0 incf ?a_main
53 07DF 3004 movlw 4
54 07E0 0220 subwf ?a_main,w
55 07E1 1C03 btfss 3,0
56 07E2 2FC5 goto l3
57 07E3 l6
58 ;TEST.C: 23: for(;;);
59 07E3 2FE3 goto l6
Как видно, для копирования сложных структур, используется функция structbank.
В нашем примере структуры размещены в разных банках. Если структуры размещены в одном банке - используется
structcopy.
Проблема заключается в том, что ни structbank, ни structcopy не восстанавливают исходный банк регистров по окончании
своей работы.
В приведённом примере локальная переменная i, назначенная компилятором на ?a_main, модифицируется не в нулевом банке,
а в первом. То есть происходит порча данных структуры str1. В данном примере это не приводит к фатальным
последствиям, так как никакой дальнейшей работы с данными не производится. Но в реальной жизни этот баг привёл к
потере некоторого времени на его локализацию.
Окончательно убедиться в наличии описываемой ошибки можно, проанализировав исходные тексты функций structbank и
structcopy, расположенных в файлах structbk.as и struct.as соответственно.
Данный пример был проверен на версиях компилятора 7.87 PL2 и 8.00 PL2. Результат одинаковый.
Work Around:
Не использовать конструкцию str1[i] = str2[i] для копирования структур.
Использовать для этой цели memcpy(&str1, &str2, sizeof(str1)).
E-mail: info@telesys.ru