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