Arduino循环增加时钟周期,为什么?
简单的故事是:
在这种情况下,示例2和3是相同的(通常编译器优化代码并删除无用的指令)。这些例子只有两个说明:
PORTB |= 0b00010000;PORTB &= 0b11101111;结论对于这些示例,代码只更改端口值
例如,1您有5个指令(每次每次1次,每次迭代4次):
int I=0(每1次)I<4PORTB |= 0b00010000;PORTB &= 0b11101111;i++此示例的代码更改端口值并处理索引
为了理解为什么要学习编译器做什么和处理器是如何工作的。下面是示例的汇编代码
示例1
代码语言:javascript复制PORTB:
.zero 4
loop():
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 0
.L3:
cmp DWORD PTR [rbp-4], 3
jg .L4
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
add DWORD PTR [rbp-4], 1
jmp .L3
.L4:
nop
pop rbp
ret示例2
代码语言:javascript复制PORTB:
.zero 4
loop():
push rbp
mov rbp, rsp
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
nop
pop rbp
ret示例3
代码语言:javascript复制PORTB:
.zero 4
loop():
push rbp
mov rbp, rsp
.L2:
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
or eax, 16
mov DWORD PTR PORTB[rip], eax
mov eax, DWORD PTR PORTB[rip]
and eax, 239
mov DWORD PTR PORTB[rip], eax
jmp .L2