|
发现更为奇怪的结果了: 看下面的修改的代码
while (1) {
if ((--x)&&(--x ==0)) {
x = SPEED1S;
y = 1;
if(GPIOA->IDR & 1) y *= 0x10000;
GPIOA->BSRR = y;
}
}
;;;75 while (1) {
;;;76 if ((--x)&&(--x ==0)) {
;;;77 x = SPEED1S;
;;;81 y = 1;
;;;82 if(GPIOA->IDR & 1) y *= 0x10000;
000072 490b LDR r1,|L1.160|
000074 4625 MOV r5,r4 ;54
000076 f44f3280 MOV r2,#0x10000
00007a e000 B |L1.126|
|L1.124|
00007c e7fe B |L1.124|
|L1.126|
00007e 1e64 SUBS r4,r4,#1 ;76
000080 d0fd BEQ |L1.126|
000082 1e64 SUBS r4,r4,#1 ;76
000084 d1fb BNE |L1.126|
000086 f8d13808 LDR r3,[r1,#0x808]
00008a 462c MOV r4,r5 ;77
00008c 2001 MOVS r0,#1 ;81
00008e 07db LSLS r3,r3,#31
000090 d000 BEQ |L1.148|
000092 4610 MOV r0,r2
|L1.148|
;;;83 GPIOA->BSRR = y;
000094 f8c10810 STR r0,[r1,#0x810]
000098 e7f1 B |L1.126|
;;;84 }
;;;85 }
分析: 从上面的编译结果, 可以看到, 变量 x 仍被分配给寄存器 R4,
在标号 |L1.126| 后面四条指令, 就执行了两次减1 后判断的循环任务.
这两个分支, 一个不需要跳转, 另一个需要跳转. 接下来看测试的结果.
下面是每次 Systick 中断中读取到的 x(R4) 的值.
0x0075c35e,0x004e86c6,0x00274a2e,0x00000d96
差值 ,0x00273c98,0x00273c98,0x00273c98
也就是说, 1 秒钟, 执行了 0x273c98 * 4 = 0x9CF260 个循环.
对, 仍然是 0x9CF260 , 写这里的时候, 我反复过 n 次了.
有人要说了, 1/8 秒不是要乘以 8 嘛, 但是一次循环里执行了两次减1.
据此推算, 这四条指令的循环一次需要 7 个周期,
难道说减法指令和分支不跳转不需要时间, 光那条分支后跳转指令需要 7 个周期? |
|