|
发表于 2024-12-28 16:39:03
|
显示全部楼层
本帖最后由 mmxx2015 于 2024-12-28 16:40 编辑
是超过32767后16位数据比较变成32数据比较,单次循环运行用时变长导致的,因为不带修饰的整数默认是有符号整数,16位有符号数最大只能表示32767,32768就需要扩展为32数表示。
循环比较<=32767时的编译结果:
- ; for(i=0;i<32767;i++); //延时
- ; SOURCE LINE # 27
- MOV i?040,#00H
- MOV i?040+01H,#00H
- ?C0006:
- CLR C
- MOV A,i?040+01H
- SUBB A,#0FFH
- MOV A,i?040
- SUBB A,#07FH
- JNC ?C0005
- ?C0008:
- INC i?040+01H
- MOV A,i?040+01H
- JNZ ?C0018
- INC i?040
- ?C0018:
- SJMP ?C0006
- ?C0007:
- ; //for(i=0;i<32768;i++); //延时
- ; //for(i=0;i<32768U;i++); //延时
- ; }
- ; SOURCE LINE # 30
- ?C0005:
复制代码 循环比较>=32768时的编译结果:
- ; for(i=0;i<32768;i++); //延时
- ; SOURCE LINE # 28
- MOV i?040,#00H
- MOV i?040+01H,#00H
- ?C0006:
- MOV R6,i?040
- MOV R7,i?040+01H
- CLR A
- MOV R4,A
- MOV R5,A
- MOV R3,#00H
- MOV R2,#080H
- MOV R1,#00H
- MOV R0,#00H
- SETB C
- LCALL ?C?SLCMP
- JC ?C0005
- ?C0008:
- INC i?040+01H
- MOV A,i?040+01H
- JNZ ?C0018
- INC i?040
- ?C0018:
- SJMP ?C0006
- ?C0007:
- ; //for(i=0;i<32768U;i++); //延时
- ; }
- ; SOURCE LINE # 30
- ?C0005:
复制代码 C?SLCMP执行的指令:
- C?SLCMP:
- C:0x00C3 EB MOV A,R3
- C:0x00C4 9F SUBB A,R7
- C:0x00C5 F5F0 MOV B(0xF0),A
- C:0x00C7 EA MOV A,R2
- C:0x00C8 9E SUBB A,R6
- C:0x00C9 42F0 ORL B(0xF0),A
- C:0x00CB E9 MOV A,R1
- C:0x00CC 9D SUBB A,R5
- C:0x00CD 42F0 ORL B(0xF0),A
- C:0x00CF EC MOV A,R4
- C:0x00D0 6480 XRL A,#P0(0x80)
- C:0x00D2 C8 XCH A,R0
- C:0x00D3 6480 XRL A,#P0(0x80)
- C:0x00D5 98 SUBB A,R0
- C:0x00D6 45F0 ORL A,B(0xF0)
- C:0x00D8 22 RET
复制代码
这就好比跑1000米,一圈200米只需跑5圈就够了,如果换个操场,一圈变成500米,如果还跑5圈,用时就长很多了。
解决办法:
(1)在立即数后面加U后缀指明这是无符号整数;
(2)改成递减计数,如:
- i=32768; //延时
- while(--i);
复制代码 不过,无论哪种修改方法都不推荐,因为一直占用CPU时间,推荐用定时器定时。
|
打赏
-
查看全部打赏
|