Automaticke pretypovani u AVR-GCC
Tomáš Halabala
tomas.halabala@iol.cz
Úterý Červenec 21 15:05:12 CEST 2009
Ahoj,
dokaze mi nekdo z pritomnych vysvetlit, proc GCC pretypovava 8-bitový
výraz v podmínce if na U16 bez ohledu na cast? Jak docilim toho, aby se
testovala nenulovost puvodni 8-bitove promenne bez rozsireni na 16-bitu?
Uvedu priklad:
typedef unsigned char U8;
static U8 Status;
void fce(void)
{
if (3 & Status) { ...
..
}
Vysledek:
170a: 80 91 11 01 lds r24, 0x0111 // Status->r24
170e: 90 e0 ldi r25, 0x00 ; 0
1710: 83 70 andi r24, 0x03 ; 3
1712: 90 70 andi r25, 0x00 ; 0
1714: 89 2b or r24, r25
1716: 69 f1 breq .+90
Bez ohledu na formu zapisu podminky. Stejny vysledek vynikne i pri:
if ((U8)((U8)(3) & (U8)(Status)) { ..
K pretypovani naopak nedojde, jestlize je vysledny vyraz jeste porovnan
s jinou konstantou, napr takto:
if (3 == (3 & Status)) { ..
Vysledek vypada takto:
170a: 80 91 11 01 lds r24, 0x0111
170e: 83 70 andi r24, 0x03 ; 3
1710: 83 30 cpi r24, 0x03 ; 3
1712: 69 f5 brne .+90 ;
Na druhou stranu v jinem miste programu, kde je situace uplne stejna,
pouze s jinou promennou Var2, ktera se v tom okamziku nachazi v registru
r22, protoze byla predana jako parametr funkce takto:
void fce2( const U8 Var1, const U8 Var2 )
{
if (3 == (3 & Var2)) { ...
...
k pretypovani opet dojde a test probehne nasledovne:
1238: c6 2f mov r28, r22 // uschovani pro dalsi pouziti
123a: d0 e0 ldi r29, 0x00 ; 0
123c: ce 01 movw r24, r28
123e: 83 70 andi r24, 0x03 ; 3
1240: 90 70 andi r25, 0x00 ; 0
1242: 03 97 sbiw r24, 0x03 ; 3
1244: 31 f4 brne .+12 ;
K pretypovani nedojde pokud je konstanta rovna nejake mocnine dvou. To
je spravne, provede se test daneho bitu, ale proc v jinem pripade k
pretypovani dojde?
Je toto chovani normalni a je to vlastnost, ktera se neda ovlivnit nebo
to lze ovlivnit, ale ja nevim jak? Uz me nebavi psat kazdou kravinu v asm.
Tomas
Další informace o konferenci Hw-list