Czyli np char zajmuje 1bajt ale i tak w rejestrze
będzie 4/8 bajtów?
1 bajt zajmuje 1 bajt. Są rejestry o różnych wielkościach, ale np. w x86_64 jak wrzucisz bajt do rejestru al, i potem chcesz wrzucić int64_t do rejestru rax to ten wcześniejszy bajt zostanie nadpisany bo rejestr al wchodzi w skład rejestru rax.
Z tego co wiem w pamięci fizycznej (RAM) przechowywane są bajty danych
i do każdego z nich odwołujemy się za pomocą adresu. Załóżmy że deklaruję zmienna
int(4bajty). Co za to odpowiada, że do tej zmiennej mogę się odwołać za pomocą
jednego adresu? Procesor na podstawie typu zmiennej "wie" ile kolejnych bajtów pobrać z pamięci?
Procesor tylko wykonuje rozkazy. O tym jaki rozkaz ma być decyduje kompilator. I jak kompilator widzi, że ma pobrać zmienną typu int czyli (załóżmy) cztero-bajtową to tworzy rozkaz, który pobiera zmienną cztero-bajtową. Adres jest jeden ponieważ procesor pobiera cztery bajty, które są obok siebie. Czyli jak ma pobrać cztery bajty z adresu np. 0x40 to pobiera bajty 0x40, 0x41, 0x42 i 0x43 (nie zawsze jest taka kolejność, zależy jaka jest forma zapisu na danej architekturze (big endian, little endian itp. jakbyś chciał poczytać)).
Dlaczego zmienna może mieć rozmiar większy niż 8 bajtów np long double?
Przecież dzisiejsze procesory są 64 bitowe a więc rejestry są 64 bitowe, jak
takie zmienne są przetwarzane,jak się zmieszczą w tych rejestrach?
Jakie mechanizmy za to odpowiadają?
Istnieje tak zwany koprocesor, jest on odpowiedzialny za operacje na liczbach zmiennoprzecinowych. Na x86 jego rejestry mają 80 bitów
W standardzie jest, §3.9.1 ¶8
There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation.
Czyli w skrócie, double ma przynajmniej taką precyzję jak float, a long double ma przynajmniej taką jak double. Nigdzie nie ma napisane co ile ma bitów. Na x86 z reguły float ma 32 bity, double 64, a long double 80, właśnie dzięki tym rejestrom koprocesora.
Niektóre kompilatory dają long double 128 bitów, ale jest to zależne od implementacji. Nie są one wtedy trzymane całe w rejestrach. Jakie mechanizmy za to dokładnie odpowiadają nie wiem (: