Глюк оптимизатора в ИАР МСП v3.30 Перекомпилировал маленький терминал на LCD c v.3.21 на v.3.30 и перестало работать перекодирование win1251->"русская кодировка LCD".
См. код, после ======= как можно обойти этот глюк.
*** помечены нужные места
Использую максимальную оптимизацию по скорости с выключеной "Code motion". С другими видами оптимизации (по скорости, по объему) ошибка остается при уровнях оптимизации High, Medium.
\ In segment CODE, align 2 178 int putchar( int c ) \ putchar: 179 { \ 000000 0A12 PUSH.W R10 \ 000002 0B12 PUSH.W R11 \ 000004 0812 PUSH.W R8 \ 000006 0A4C MOV.W R12, R10 180 static const char perecod[] = // перекодировка русских букв из таблицы win1251 в таблицу, применяемую в ЖКИ 181 { 'A' , 0xa0, 'B' , 0xa1, 0xe0, 'E' , 0xa3, 0xa4, 0xa5, 0xa6, 'K' , 0xa7, 'M' , 'H' , 'O' , 0xa8, // 0xc0..0xcf 182 'P' , 'C' , 'T' , 0xa9, 0xaa, 'X' , 0xe1, 0xab, 0xac, 0xe2, 0xad, 0xae, 'b' , 0xaf, 0xb0, 0xb1, // 0xd0..0xdf 183 'a' , 0xb2, 0xb3, 0xb4, 0xe3, 'e' , 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 'o' , 0xbe, // 0xe0..0xef 184 'p' , 'c' , 0xbf, 'y' , 0xe4, 'x' , 0xe5, 0xc0, 0xc1, 0xe6, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 // 0xf0..0xff 185 }; 186 static const char n_line[] = { LCD_ONE, LCD_TWO, LCD_THREE, LCD_FOUR, LCD_ONE }; 187 static int lcd_pos; 188 static int previos; 189 int c_old = c; \ 000008 0B4C MOV.W R12, R11 190 // int a = c - 'А'; // пришлось ввести переменную и вынести ее расчет сюда, ато "крутой" оптимизатор от v3.30 заоптимизировывает... 191 // 192 // if ( c ) 193 // { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251 194 // c = perecod[a]; // русские буквы в кодировке win1251 195 // else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd 196 // c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0 197 198 if ( c ) \ 00000A 0C93 CMP.W #0x0, R12 \ 00000C D924 JEQ ??putchar_2 199 { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251 \ 00000E 3C90C000 CMP.W #0xc0, R12 \ 000012 0238 JL ??putchar_3 200 c = perecod[c - 'А']; // русские буквы в кодировке win1251 \ 000014 7AF3 AND.B #0xff, R10 // *** ЭТО НЕ ПРАВИЛЬНО \ 000016 053C JMP ??putchar_4 201 else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd \ ??putchar_3: \ 000018 3C908000 CMP.W #0x80, R12 \ 00001C 0238 JL ??putchar_4 202 c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0 \ 00001E 3A504000 ADD.W #0x40, R10 203 204 205 switch ( c ) \ ??putchar_4: ================================================================================================================================== 178 int putchar( int c ) \ putchar: 179 { \ 000000 0A12 PUSH.W R10 \ 000002 0B12 PUSH.W R11 \ 000004 0812 PUSH.W R8 \ 000006 0A4C MOV.W R12, R10 180 static const char perecod[] = // перекодировка русских букв из таблицы win1251 в таблицу, применяемую в ЖКИ 181 { 'A' , 0xa0, 'B' , 0xa1, 0xe0, 'E' , 0xa3, 0xa4, 0xa5, 0xa6, 'K' , 0xa7, 'M' , 'H' , 'O' , 0xa8, // 0xc0..0xcf 182 'P' , 'C' , 'T' , 0xa9, 0xaa, 'X' , 0xe1, 0xab, 0xac, 0xe2, 0xad, 0xae, 'b' , 0xaf, 0xb0, 0xb1, // 0xd0..0xdf 183 'a' , 0xb2, 0xb3, 0xb4, 0xe3, 'e' , 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 'o' , 0xbe, // 0xe0..0xef 184 'p' , 'c' , 0xbf, 'y' , 0xe4, 'x' , 0xe5, 0xc0, 0xc1, 0xe6, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 // 0xf0..0xff 185 }; 186 static const char n_line[] = { LCD_ONE, LCD_TWO, LCD_THREE, LCD_FOUR, LCD_ONE }; 187 static int lcd_pos; 188 static int previos; 189 int c_old = c; \ 000008 0B4C MOV.W R12, R11 190 int a = c - 'А'; // *** пришлось ввести переменную и вынести ее расчет сюда, ато "крутой" оптимизатор от v3.30 заоптимизировывает... \ 00000A 0F4C MOV.W R12, R15 \ 00000C 3F5040FF ADD.W #0xff40, R15 191 192 if ( c ) \ 000010 0C93 CMP.W #0x0, R12 \ 000012 DA24 JEQ ??putchar_2 193 { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251 \ 000014 3C90C000 CMP.W #0xc0, R12 \ 000018 0338 JL ??putchar_3 194 c = perecod[a]; // русские буквы в кодировке win1251 \ 00001A 5A4F.... MOV.B ??perecod(R15), R10 // *** ТАК ПРАВИЛЬНО! \ 00001E 053C JMP ??putchar_4 195 else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd \ ??putchar_3: \ 000020 3C908000 CMP.W #0x80, R12 \ 000024 0238 JL ??putchar_4 196 c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0 \ 000026 3A504000 ADD.W #0x40, R10 197 198
-
- Ответ: На електронихе штиль, спрошу и здесь - 330А или 330В? Может уже пофиксили? - ig_z(21.06.2005 19:01, )