Ich habe den folgenden Code in meinem Mikrocontroller-Programm:
int analogValue = ADCH; // ADC Data Register
//
// Simple analog comparator.
// If analogValue lower than threshold then toggle output high,
// Otherwise toggle it low.
//
if ( analogValue > 128 ) {
PORTB = 0; // Port B Data Register
} else {
PORTB = _BS( outputPin ); // Port B Data Register
}
Woher:
Als ich mir den resultierenden Assembler-Code ansah, bemerkte ich, dass er einen 16-Bit-Vergleich durchführt (Zeile 40-44), wo genau genommen nur 8 Bit ausreichend gewesen wären:
40: 90 e0 ldi r25, 0x00 ; 0
42: 81 38 cpi r24, 0x81 ; 129
44: 91 05 cpc r25, r1
46: 14 f0 brlt .+4 ; 0x4c <__SREG__+0xd>
48: 18 ba out 0x18, r1 ; PORTB
4a: f5 cf rjmp .-22 ; 0x36 <__CCP__+0x2>
4c: 28 bb out 0x18, r18 ; PORTB
4e: f3 cf rjmp .-26 ; 0x36 <__CCP__+0x2>
Mir ist klar, dass ich analogValue als int deklariert habe , was auf AVR tatsächlich 16 Bit ist, aber ...
Wie kann ich den Compiler anweisen, den 8-Bit-Vergleich zu verwenden? Die Arduino IDE erlaubt mir die Verwendung von byte , avr-gcc jedoch standardmäßig nicht.
Auf dieser Seite finden Sie das vollständige Programm und den daraus resultierenden zerlegten Code.
EDIT1:
Ändern int
in char
ändert den Assemblycode in:
14: 11 24 eor r1, r1 ; r1 = 0
3e: 18 ba out 0x18, r1 ; PORTB
Den Test grundsätzlich komplett überspringen.
EDIT2: (Thnx: Wouter van Ooijen)
Ändern int
in unsigned char
ändert den Assemblycode in:
3c: 85 b1 in r24, 0x05 ; ADCH
3e: ...
40: 87 fd sbrc r24, 7 ; compare < 128 (well optimized)
42: 02 c0 rjmp .+4 ; 0x48 <__SREG__+0x9>
44: 18 ba out 0x18, r1 ; 24
46: f7 cf rjmp .-18 ; 0x36 <__CCP__+0x2>
48: 98 bb out 0x18, r25 ; 24
4a: f5 cf rjmp .-22 ; 0x36 <__CCP__+0x2>
Ich denke tatsächlich, dass eine bessere Praxis, die diese architektonische Mehrdeutigkeit vermeidet, darin besteht, <stdint.h>
deklarative Typen einzuschließen und dann zu verwenden, wie:
usw...
Die mehr oder weniger Standarddefinition eines Bytes in C ist „unsigned char“.
unsigned
Teil hat den Job gemacht, char
kompiliert von alleine ohne Warnungen.
Jippie
_t
her?Vicatcu
Toby Jaffey
Jon L
Superkatze
int
16 Bit beispielsweise verhalten sichuint32_t flag;
die Anweisungenflag &= ~0x00004000;
undflag &= ~0x00010000;
wie erwartet, aberflag &= ~0x00008000;
etwas anders.