Zasadniczo każdy nowoczesny komputer jest maszyną do popychania. Zwykle przesuwa bity w grupach danych, zwanych bajtami, słowami, dwordami lub qwordami.
Bajt składa się z 8 bitów, słowa 2 bajtów (lub 16 bitów), dworda 2 słowa (lub 32 bity) i qword 2 dwordów (lub 64 bitów). To nie jedyny sposób na ułożenie bitów. Występuje również manipulacja 128-bitowa i 256-bitowa, często w instrukcjach SIMD.
Instrukcje montażu działają na rejestrach, a adresy pamięci zwykle działają w jednej z powyższych postaci.
ALU (arytmetyczne jednostki logiczne) działają na takich pakietach bitów, jakby reprezentowały liczby całkowite (zwykle format dopełnienia Twoa), a FPU tak, jakby to były wartości zmiennoprzecinkowe (zwykle w stylu IEEE 754 float
i double
). Inne części będą działać tak, jakby były połączonymi danymi o określonym formacie, znakach, wpisach w tabeli, instrukcjach procesora lub adresach.
Na typowym komputerze 64-bitowym pakiety 8 bajtów (64 bity) to adresy. Wyświetlamy te adresy w sposób konwencjonalny, jak w formacie szesnastkowym (jak 0xabcd1234cdef5678
), ale jest to prosty sposób na odczytanie przez użytkowników wzorów bitowych. Każdy bajt (8 bitów) jest zapisywany jako dwa znaki szesnastkowe (równoważnie każdy znak szesnastkowy - od 0 do F - reprezentuje 4 bity).
To, co się właściwie dzieje (na pewnym poziomie), to fakt, że są bity, zwykle przechowywane w rejestrze lub przechowywane w sąsiednich lokalizacjach w banku pamięci, a my po prostu próbujemy je opisać innemu człowiekowi.
Podążanie za wskaźnikiem polega na zwróceniu się do kontrolera pamięci o podanie danych w tym miejscu. Zwykle pytasz kontroler pamięci o określoną liczbę bajtów w określonej lokalizacji (cóż, domyślnie zakres lokalizacji, zwykle sąsiadujących), i jest on dostarczany za pośrednictwem różnych mechanizmów, do których nie mogę się dostać.
Kod zwykle określa miejsce docelowe pobierania danych - rejestr, inny adres pamięci itp. - i zwykle złym pomysłem jest ładowanie danych zmiennoprzecinkowych do rejestru oczekującego liczby całkowitej lub odwrotnie.
Typ danych w C / C ++ jest czymś, co kompilator śledzi i zmienia generowany kod. Zwykle w danych nie ma nic nieodłącznego, co sprawia, że faktycznie są one dowolnego typu. Po prostu kolekcja bitów (ułożonych w bajty), które są manipulowane przez kod w sposób całkowity (lub zmiennoprzecinkowy lub adresowy).
Istnieją wyjątki od tego. Istnieją architektury, w których pewne rzeczy są innym rodzajem bitów. Najczęstszym przykładem są chronione strony wykonania - podczas gdy instrukcje informujące CPU, co mają robić, są bitami, w czasie wykonywania strony (pamięci) zawierające kod do wykonania są specjalnie oznaczone, nie można ich modyfikować i nie można wykonywać stron, które nie są oznaczone jako strony wykonania.
Istnieją również dane tylko do odczytu (czasami przechowywane w pamięci ROM, których fizycznie nie można zapisać!), Problemy z wyrównaniem (niektóre procesory nie mogą załadować double
pamięci z pamięci, chyba że są one dostosowane w określony sposób, lub instrukcje SIMD, które wymagają pewnego wyrównania) i mnóstwo inne dziwactwa architektury.
Nawet powyższy poziom szczegółowości jest kłamstwem. Komputery nie „naprawdę” przepychają się wokół bitów, naprawdę przepychają się wokół napięć i prądów. Te napięcia i prądy czasami nie robią tego, co „powinny” robić na poziomie abstrakcji bitów. Chipy są zaprojektowane do wykrywania większości takich błędów i ich korygowania bez konieczności abstrakcyjnego rozpoznawania wyższego poziomu.
Nawet to kłamstwo.
Każdy poziom abstrakcji ukrywa poniższy poziom i pozwala myśleć o rozwiązywaniu problemów bez konieczności pamiętania diagramów Feynmana w celu wydrukowania "Hello World"
.
Zatem na wystarczającym poziomie uczciwości komputery wypychają bity, a te bity mają znaczenie dzięki sposobowi ich użycia.