Hallo,
wenn ich unter avr-gcc (-O2) auf die Bytes in einem uint16_t (oder
breiter) zugreifen möchte, um diese beispielsweise an eine (8-Bit) IO
Adresse auszugeben, wird unnötiger Code generiert (siehe Beispiel).
Beispiel C (disassembly) (zugegeben, nicht besonders sinnvoll):
1 | uint16_t cnt=0;
|
2 | 64: 20 e0 ldi r18, 0x00 ; 0
|
3 | 66: 30 e0 ldi r19, 0x00 ; 0
|
4 | for(;;){
|
5 | PORTB=cnt>>0;//unteres Byte von cnt an PORTB
|
6 | 68: 28 bb out 0x18, r18 ; 24
|
7 | PORTB=cnt>>8;//zweites Byte von cnt an PORTB
|
8 | 6a: 83 2f mov r24, r19 ;bedingt notwendig
|
9 | 6c: 99 27 eor r25, r25 ;unnoetig
|
10 | 6e: 88 bb out 0x18, r24 ; 24
|
11 | cnt++;
|
12 | 70: 2f 5f subi r18, 0xFF ; 255
|
13 | 72: 3f 4f sbci r19, 0xFF ; 255
|
14 | 74: f9 cf rjmp .-14 ; 0x68
|
15 | }
|
im Anhang das gleiche Beispiel nochmal für uint32.
Wie kann ich dem Compiler beibiegen, bei Zuweisungen von
(variable>>(n*8))-Konstrukten direkt auf die Register zuzugreifen, in
denen die Werte liegen? Z.B. könnte an Adresse 0x6e einfacher stehen out
0x18,r19 und die Befehle an Adressen 0x6a-0x6d wären unnötig. Und so
weiter. Kann man das sicher mit C-Syntax erschlagen oder muss man da auf
Assembler zurückgreifen?
Grüße, Sebastian