Witam! Definiuje sobie funkcje: unsigned char funkcja();
Z tego co mi wiadomo uchar miesci sie w jednym bajcie, logiczne jest wiec, ze wartosc zwracana przez funkcje zwracana jest w jakims rejestrze. Kompiluje sobie program, patrze w disassemblerze jak to wyglada i o dziwo wartosc funkcji zwracana jest w dwoch bajtach! Dlaczego tak jest? Pozdrawiam, T.M.F.
Gcc po prostu tak ma i już, jeśli bardzo ci to przeszkadza i nie potrzebujesz w programie zmiennych całkowitych dłuższych niż 16-bitów to dodaj opcję -mint8 przy kompilacji źródeł.
Troche przeszkadza, bo wydluza kod. Kompiluje sobie na ATMega8 i pamieci nie mam za wiele, a mam pare funkcji zwracajacych wartosc typu bool (zdefiniowana jako uchar, bo nie moge jakos znalezc pliku naglowkowego definiujacego bool, true i false). Dzieki za wskazowke z tym -mint8, sprawdze i potestuje. Jak wtedy zachowuja sie typy long itd. ?
int - 8-bitów, long 16-bitów. Lepiej jednak używać definicji (u)int8/16_t wtedy długości zmiennych nie zmieniają się (oczywiście (u)int32_t przestaje być rozpoznawane).
Szczególną grupą procesorów są DSP, w których wszystko nie robi się tak aby było wygodnie pisać programy (patrz np. ARM), ale w celu maksymalizacji wydajności. Na przykład w texasowych procesorach TMS320VC54xx magistrala pamięci jest 16-bitowa. Prawie wszystkie rejestry są 16-bitowe (poza dwoma akumulatorami). Pamięć SRAM w środku procesora jest 16-bitowa. I na zewnątrz też musi być. Procesor nie ma fizycznej możliwości zaadresowania oktetu. W tych DSPkach bajt po prostu ma 16 bitów (nie mylić z oktetem, który jest zawsze 8-bitowy). Tablica 8 wartości [unsigned] char zajmuje 8 słów 16b. Nie muszę chyba tłumaczyć, jak upierdliwe jest przenoszenie kodu w języku C z normalnego procesora (np. AVR czy ARM) na DSP. Z drugiej strony, jeżeli od razu się pisze na texasa to można się przyzwyczaić.
Istnieje, patrz np. kompilatory C dla DSP'ków. Na texasach minimalną adresowaną jednostką jest słowo 16b i bajt zajmuje tam 16 bitów. Tyle samo co słowo typu [unsigned] int. Kompilator jednak dba o to, aby wartość zmiennej typu unsigned char mieściła się w zwyczajowo przyjętym zakresie (0-255) i przed każdym zapisem do pamięci robi operację "AND" ze stałą 0xff. W przypadku typu ze znakiem (char) dodatkowo rozszerza bit znaku. Dlatego też operacje na wartościach typu [unsigned] char dają znacznie dłuższy kod wynikowy niż gdyby odbywały się na [unsigned] int.
BTW: Całkiem ciekawe jest przeprowadzanie operacji na wartościach
32-bitowych. Dwa akumulatory istniejące w TMS320VC5416 mają po 32 bity każdy, ale asembler pozwala w gruncie rzeczy na niewiele natywnych operacji na takich porcjach danych. Dane leżące w pamięci muszą być wyrównane do adresu parzystego (adresowanie dotyczy zawsze słów
16-bitowych) co wydaje się oczywiste. Ale DSP pobierając wartość 32b spod adresu nieparzystego nie wykrzaczy się (nie ma wyjątków itp) tylko zamieni połówki słowa pobieranego. :-) Na szczęście kompilator C zwykle na to zwraca uwagę alokując odpowiednio zmienne w RAMie i na stosie. Trzeba tylko uważać z rzutowaniem.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.