Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Rejestry 32 bitowe - gdzie mieszczą się liczby zajmujące więcej niż 4 bajty

Ostatnio zmodyfikowano 2017-07-14 18:48
Autor Wiadomość
latajacaryba
Temat założony przez niniejszego użytkownika
Rejestry 32 bitowe - gdzie mieszczą się liczby zajmujące więcej niż 4 bajty
» 2017-07-14 01:58:02
Witam. Ze strony o rejestrach procesora, dowiedziałem się trochę o rejestrach [[a href = "http://parzych.net/2010/06/assembler-pigulka-najwazniejsze-komendy-rejestry-przyklady/" name = "źródło"]]. Jednak co mnie zastanawia:

jeśli mamy zmienne np. long, które zajmują 8 bajtów, to jak są one przechowywane w rejestrze (przechowywane żeby wykonać na nich jakąś operacje), skoro rejestry w systemie x86 mają "pojemność" 4 bajtów?
To samo tyczy się long double dla rejestrów o pojemności 8 bajtów w systemie 64 bitowym.
P-163256
Monika90
» 2017-07-14 10:36:06
A czy trzeba trzymać całą liczbę w rejestrze by wykonać na niej operację? Nawet ośmiobitowy procesor może wykonywać 64-bitowe operacje arytmetyczne, kawałek po kawałku.

A jeśli chodzi o long double, to x86 ma 80-bitowe rejestry dla liczb zmiennoprzecinkowych.
P-163258
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-07-14 14:15:54
Dziękuję za odpowiedź :)

PS. przypomniała mi się jeszcze jedna rzecz, wiem, że jedno pytanie na temat, ale będzie krótko:
Jeśli mamy system, w którym słowo ma 4 bajty, i utworzymy sobie w programie zmienną, np. bool to będzie ona zajmować 4 bajty, mimo, że zmienna bool to 1 bajt? Bo rozumiem, że nie można operować na konkretnych bajtach słowa, tylko na całym słowie?
P-163275
pekfos
» 2017-07-14 15:25:28
A co to jest słowo w tym pytaniu? Rejestr? W x86 można się odwołać bezpośrednio do najmłodszych 16 bitów rejestru 32-bitowego, jak i do dwóch najmłodszych oktetów (EAX, AX, AH, AL), więc zmienna bool w rejestrze może zajmować "1 bajt".
P-163282
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-07-14 16:34:07
Chodzilo mi o to słowo maszynowe
P-163287
pekfos
» 2017-07-14 16:48:46
Chyba nie trafiam z odpowiedzią, skoro odpowiadasz na pytania retoryczne.. Same "słowo" tu nic nie mówi w kontekście, ile faktycznie pamięci zajmuje zmienna. bool jako zmienna na stosie, czy pole w strukturze, podlega wyrównaniu, więc może być zużyte więcej pamięci, niż potrzeba. Podobnie w dynamicznej alokacji, może być zaalokowane więcej miejsca niż potrzeba na samego boola, bo może implementacja potrzebuje sobie jakieś informacje zapisać. Do tego stronnicowanie pamięci też jest czynnikiem.
C/C++
void f()
{
    bool a, b;
}
W takim kodzie, na x86, obie zmienne mogą zajmować razem albo 4, albo 8 bajtów. To zależy, czy kompilator umieścił je na osobnych słowach stosu. Zmiana wskaźnika stosu o inną wartość niż wielokrotność długości słowa stosu, to wyjątek procesora. Gdyby to była tablica bool a[2], to to już by musiało być na 4 bajtach, wliczając wyrównanie. O paru sprawach tego typu pisałem tu: Zapis binarny.
P-163289
Elaine
» 2017-07-14 17:28:35
W x86 można się odwołać bezpośrednio do najmłodszych 16 bitów rejestru 32-bitowego, jak i do dwóch najmłodszych oktetów (EAX, AX, AH, AL), więc zmienna bool w rejestrze może zajmować "1 bajt".
W praktyce zajmuje całe 4 lub 8 bajtów rejestru, bo pozostałych części rejestru nie warto wtedy alokować dla innych zmiennych, bo na wielu procesorach dostęp do jednej części rejestru po zmianie innej części rejestru wymaga dodatkowego µopu składającego w całość wszystkie 32 lub 64 bity.

W takim kodzie, na x86, obie zmienne mogą zajmować razem albo 4, albo 8 bajtów.
A w praktyce najprawdopodobniej dwa, plus padding do 16 bajtów zgodnie z ABI, ale to się nie liczy, bo istnieje zawsze i kompilator może tam włożyć inne zmienne. Może nawet zajmować zero, jeśli istnieje tylko w rejestrze, albo zostanie zaalokowana w shadow space lub czerwonej strefie (które również istnieją zawsze z wymogów ABI, więc się nie liczą).

Zmiana wskaźnika stosu o inną wartość niż wielokrotność długości słowa stosu, to wyjątek procesora.
Na x86? Nie, wskaźnik stosu może sobie być nawet i nieparzysty, i nikomu nie będzie to za bardzo przeszkadzać, prznajmniej dopóki ktoś nie spróbuje zrobić movaps, movapd lub movdqa ze stosu lub na stos — domyślnie stos jest wyrównany do 16 bajtów według praktycznie każdego ABI, więc kompilator może założyć, że użycie tych instrukcji jest bezpieczne.



Jeśli mamy system, w którym słowo ma 4 bajty, i utworzymy sobie w programie zmienną, np. bool to będzie ona zajmować 4 bajty, mimo, że zmienna bool to 1 bajt? Bo rozumiem, że nie można operować na konkretnych bajtach słowa, tylko na całym słowie?
W pamięci będzie zajmowała jeden bajt, bo nie ma sensu, by zajmowała więcej (chyba że ABI jest bardzo dziwne). Gdy zostanie załadowana do rejestru, to wtedy zostanie rozszerzona do rozmiaru rejestru.

Jeśli architektura nie dopuszcza dostępu do jednostek mniejszych niż 32 bity, to wtedy oczywiście taka zmienna będzie zajmować 32 bity — ale ponieważ bajt jest najmniejszą adresowalną jednostką pamięci, to takie architektury mają wtedy 32-bitowe bajty (uprzedzając pytanie, tak, takie architektury istnieją).
P-163290
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-07-14 18:48:25
W takim razie to wszystko, dziękuję za odpowiedzi.
P-163297
« 1 »
  Strona 1 z 1