Hallo, ich habe an einem Projekt mit einem Arduino Uno (also ATmega328p) gearbeitet, bei dem das Timing sehr wichtig ist, und wollte wissen, in welche Anweisungen der Compiler meinen Code konvertiert. Und da drin habe ich eine, uint8_t
die ich bei jeder Iteration mit ein Bit nach rechts verschiebe, data >>= 1
und es scheint, dass der Compiler dies in 5 Anweisungen übersetzt hat ( data
ist in r24
):
mov r18, r24
ldi r19, 0x00
asr r19
ror r18
mov r24, r18
Wenn ich mir aber die Dokumentation zum Befehlssatz ansehe, sehe ich eine Anweisung, die genau dies tut: lsr r24
Übersehe ich etwas oder warum verwendet der Compiler dies nicht auch? Die Register r18
und r19
werden nirgendwo anders verwendet.
Ich benutze ein Ardunio, aber wenn ich richtig bin, benutzt es nur den normalen avr-gcc
Compiler. Dies ist der Code (getrimmt), der die Sequenz generiert:
ISR(PCINT0_vect) {
uint8_t data = 0;
for (uint8_t i = 8; i > 0; --i) {
// asm volatile ("lsr %0": "+w" (data));
data >>= 1;
if (PINB & (1 << PB0))
data |= 0x80;
}
host_data = data;
}
Soweit ich sehen kann, verwendet die Ardunino-IDE den vom System bereitgestellten AVR-gcc-Compiler, der Version 6.2.0-1.fc24 ist. Beide werden über die Paketverwaltung installiert und sollten daher auf dem neuesten Stand sein.
avr-objdump
für die Elf-Datei verwendet. Was scheint nicht zu entsprechen?
data >>= 1;