|
|
https://www.keil.com/update/relnotes/AddOn_C251V560_13.htm
Keil C251 版本 5.60.13,发布于…发布日期:2026 年 2 月 4 日 - 这只是 C251 编译器工具链的某个更新版本而已。
- [C251 编译器]
- 已更正:C251 V5.60 版本生成的代码比之前版本要庞大。例如:void memSet(void near *dest, unsigned char val, unsigned short len) { unsigned char near *p = dest; if (len == 0) return; do { *p++ = val; len--; } while (len != 0);}000000 7D12 MOV WR2,WR4 <----- needs to be saved because of the next MOV000002 7C5B MOV R5,R11 <----- this is useless, R11 could be used directly --+000004 7D03 MOV WR0,WR6 <----- also useless, WR6 could be used directly -----+000006 4D11 ORL WR2,WR2 <----- WR4 could be checked directly here then |000008 6809 JE ?C0002 | ?C0003: |00000A 7A0950 MOV @WR0,R5 <------ here ----------------------------------------+00000D 0B04 INC WR0,#01H00000F 1B14 DEC WR2,#01H000011 78F7 JNE ?C0003 ?C0002:000013 22 RET
- 已更正:在创建更大规模的代码时,就像之前描述的那样,可能会出现这样一个情况:在将变量赋值给寄存器时,编译器可能会覆盖掉那些被无谓使用的寄存器。例如:static uint16_t rxD;static uint8_t rxC;static uint8_t *prxD;static uint16_t rxDAvail;static uint8_t count = 0;static uint16_t buf1Sz;static uint8_t *buf1;static uint8_t buf2Sz;static uint8_t *buf2;void bug(uint8_t c) { if (rxD == 0) { rxC = c; prxD = NULL; rxDAvail = 0; if (rxC == 0x13U) { count++; prxD = buf2; rxDAvail = buf2Sz; } else { prxD = buf1; rxDAvail = buf1Sz; } }000000 7C5B MOV R5,R11 <----- this is useless, R11 could be used directly --+000002 7E370000 R MOV WR6,rxC |000006 4D33 ORL WR6,WR6 |000008 784B JNE ?C0001 |00000A 7A530000 R MOV rxC,R5 <------ here ----------------------------------------+00000E 6D22 XRL WR4,WR4 <----- because of useless and not tracked assignment this overwrites R5000010 7A270000 R MOV prxD,WR4 |000014 7A270000 R MOV rxDAvail,WR4 |000018 A5BD1319 CJNE R5,#013H,?C0002 <------ and here ------------------------------------+00001C 7EB30000 R MOV R11,count000020 04 INC A000021 7AB30000 R MOV count,R11000025 7E270000 R MOV WR4,buf2000029 7A270000 R MOV prxD,WR400002D 7E530000 R MOV R5,buf2Sz000031 0A25 MOVZ WR4,R5000033 800C SJMP ?C0008 ?C0002:000035 7E270000 R MOV WR4,buf1000039 7A270000 R MOV prxD,WR400003D 7E270000 R MOV WR4,buf1Sz ?C0008:000041 7A270000 R MOV rxDAvail,WR4
- 已更正:在某些情况下,WR10 中的 R11 部分会被覆盖。例如:static uint8_t demo(uint8_t arg1, uint8_t arg2) { uint16_t wResult = 0xFFFF; wResult = arg1 + 1; wResult = wResult >> arg2; return wResult & 0xFF;};---- Variable 'arg2' assigned to Register 'R7' ----;---- Variable 'arg1' assigned to Register 'R11' ----000000 0A5B MOVZ WR10,R11 ; A=R11000002 0B54 INC WR10,#01H;---- Variable 'wResult' assigned to Register 'WR10' ----000004 7CB7 MOV R11,R7 <----- this overwrites part of WR10000006 7D35 MOV WR6,WR10000008 6005 JZ ?C0004.....
- 已更正:NOCASE 不应影响字符串字面量,因为这样可能会导致变量名称的混淆。
- 已更正:在类型定义中,reentrant 属性被忽略了,没有产生任何提示。例如:
C code exampletypedef void (footype) (void) reentrant;footype foo;void foo(void) reentrant; - 已更正:二维数组的第二个维度的大小计算有误。例如:
C code examplevoid bug(void) { unsigned char array[3][5]; array[0][0] = 0; printf("sizeof(*array) = %d, should be %d\n", (int)sizeof(*array), (int)sizeof(array[0]));}The size of a pointer to the array was calculated instead of the size of the second dimension. - 已更正:在某些情况下,当使用 goto 语句创建嵌套循环时,某些指令会被优化掉。例如:
C code exampleint bug(void) { int i; int j = 2; int n = 0; goto lFirst;lNext: --j; if (j == 0) goto lDone; ++n; // <--- this is optimized out !!lFirst: i = 2; while (i > 0) { --i; if (i == 1) // always true goto lNext; }lDone: return n;}The instruction flow was not correctly built by the compiler. The back edge to lNext was ignored.For that reason '++n' was optimized away. - 已更正:由于进行了无符号 char 类型的强制类型转换,整数提升操作被忽略了。实际上,在移位操作之前应该先进行整数提升操作。例如:
C code exampleint bug(int x) { return ((unsigned char)x)<<9;} - 已修复:在某些情况下,编译器出现了崩溃现象。因此,一些优化措施被取消了,而崩溃问题也得到了解决。现在,这些优化措施又重新被启用了,不过对于某些特殊的 CPU 来说,崩溃现象仍然会发生。
- [L251 链接器/定位器]
- 已更正:L251 SEGSIZE 指令改变了段的大小,但并未改变其后面的段的大小。
- 已更正:链接器显示“L48:忽略递归调用”,但在某些情况下并未进行任何递归操作。
|
1
喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
-
+2
楼主威武~
|