Dziękuję wszystkim za odzew :-)
Metody opisywane przez Kolegów męczyłem już wcześniej (poza przesiadką na C++), ale nie przynoszą one spodziewanego rezultatu. Może sprecyzuję o co mi chodzi. Sprawa jest czysto "akademicka" i wynika z mojego pewnego rodzaju "zboczenia" w dążeniu do absurdalnej optymalizacji kodu wynikowego ;-) Jest tak. Funkcja zdefiniowana tradycyjnie:
void ProgressBar(char x, char y, char w, char h, char value) { .... }
przy wywołaniu: ProgressBar(0, 90, 128, 5, y);
otrzymujemy w kodzie wynikowym: 37e2: 0b 2d mov r16, r11 37e4: 25 e0 ldi r18, 0x05 ; 5 37e6: 40 e8 ldi r20, 0x80 ; 128 37e8: 6a e5 ldi r22, 0x5A ; 90 37ea: 80 e0 ldi r24, 0x00 ; 0 37ec: 0e 94 b4 17 call 0x2f68 ; 0x2f68 <ProgressBar>
I to co mnie "wkurza", to czemu łachudra przekazuje parametry w rejestrach r16, r18, r20, r22, r24 niejako promując typ char do int ? Jakby nie mógł po kolei r16..r20. Oczywiście w tym przypadku nie ma to większego znaczenia, ale przy większej ilości parametrów przekazywanych do funkcji i/lub większej ilości zmiennych lokalnych funkcji, zaczyna się kombinacja ze stosem lub z dolnymi rejestrami. Kompilator w pewnym sensie "szatkuje" sobie obszar rejestrów doprowadzając do sytuacji, że w pewnym momencie brakuje np czterech kolejnych rejestrów do zapamiętania lokalnej zmiennej typu long choć pojedynczych wolnych rejestrów jest wystarczająca ilość.
Przekazując do funkcji zmienną typu long lub wspomniany wcześniej typ tRect wszystko jest cacy w kolejnych rejestrach r20..r23.
Tak jak wspomniałem dyskusja jest czysto akademicka w stylu: "czemu kompilator robi to akurat tak, choć w assemblerze wygodniej byłoby inaczej ?" ;-)
Chyba, że w kompilatorze jest jakaś przełącznik, coby przy przekazywaniu parametrów char nie był "przekształcany" w int. Pamiętam, że starsze wersje przy poleceniu switch(zmienna_typu_char) wykonywały niepotrzebne dwubajtowe porównania na typie int.
Pozdrawiam Grzegorz