Gast
#39354
Hallo! Ich habe mal ne Frage zur Optimierung von AVR-GCC 3.3 20021209: Es geht dabei um eine Funktion zur Ansteuerung eines LCDs. Dabei wurde immer nur ein Befehl umgeschrieben, die Funktion blieb aber gleich und trotzdem gab's große Codeunterschiede. Der Code der Funktion(am besten optimiert): #define DB_SHIFT=2 void lcd_send(unsigned char data, unsigned char ormask) { unsigned char tmp; //////////////////// tmp=data&0xF0; // Um diese vier // tmp>>=4-DB_SHIFT; // Zeilen geht es // LCD_PORT=tmp | ormask; //////////////////// lcd_enable(); LCD_PORT=((data & 0x0F)<<DB_SHIFT) | ormask; lcd_enable(); lcd_wait_20us(10); } und das zugehörige Assemblerlisting: 216 0050 0F93 push r16 217 0052 1F93 push r17 219 0054 082F mov r16,r24 220 0056 162F mov r17,r22 41:lcd.c **** unsigned char tmp; 42:lcd.c **** tmp=data&0xF0; 224 0058 807F andi r24,lo8(-16) 43:lcd.c **** tmp>>=4-DB_SHIFT; 227 005a 8695 lsr r24 228 005c 8695 lsr r24 44:lcd.c **** LCD_PORT=tmp | ormask; 231 005e 862B or r24,r22 232 0060 85BB out 53-0x20,r24 Besser hätte ich es auch nicht machen gekonnt. Aber wenn ich den Befehl verkürze: tmp=(data&0xF0)>>(4-DB_SHIFT); Bekomm ich aber einen um 8Byte großeren Code: 216 0050 FF92 push r15 217 0052 0F93 push r16 218 0054 1F93 push r17 220 0056 F62E mov r15,r22 41:lcd.c **** unsigned char tmp; 42:lcd.c **** tmp=(data&0xF0)>>(4-DB_SHIFT); 224 0058 082F mov r16,r24 225 005a 1127 clr r17 226 005c C801 movw r24,r16 227 005e 9695 lsr r25 228 0060 8795 ror r24 229 0062 9695 lsr r25 230 0064 8795 ror r24 231 0066 8C73 andi r24,lo8(60) 43:lcd.c **** LCD_PORT=tmp | ormask; 234 0068 862B or r24,r22 235 006a 85BB out 53-0x20,r24 Genausoschlimm ist folgender Befehl: LCD_PORT=((data>>4)<<DB_SHIFT) | ormask; 216 0050 0F93 push r16 217 0052 1F93 push r17 219 0054 082F mov r16,r24 220 0056 162F mov r17,r22 46:lcd.c **** LCD_PORT=((data>>4)<<DB_SHIFT) | ormask; 223 0058 8295 swap r24 224 005a 8F70 andi r24,0x0f 225 005c 9927 clr r25 226 005e 880F lsl r24 227 0060 991F rol r25 228 0062 880F lsl r24 229 0064 991F rol r25 230 0066 862B or r24,r22 231 0068 85BB out 53-0x20,r24 47:lcd.c **** lcd_enable(); 234 006a 0E94 0000 call lcd_enable 48:lcd.c **** LCD_PORT=((data & 0x0F)<<DB_SHIFT) | ormask; 237 006e 802F mov r24,r16 238 0070 9927 clr r25 Was mir hier besonders negativ auffällt ist die Tatsache das immer wieder(225,227,229) mir r25 gearbeitet wird, dieses Register aber in 238 gelöscht wird ohne das der darin stehende Wert jemals benutzt worden wäre. Kann mir vielleicht mal jemand erklären an welche Regeln ich mich halten muss, damit der Compiler effektiven Code produziert.