Na przykład, jeśli komputer 10111100
zapisał jeden konkretny bajt pamięci RAM, w jaki sposób komputer może interpretować ten bajt jako liczbę całkowitą, znak ASCII lub coś innego? Czy dane typu są przechowywane w sąsiednim bajcie? (Nie sądzę, aby tak się stało, ponieważ spowodowałoby to użycie podwójnej ilości miejsca na jeden bajt.)
Podejrzewam, że być może komputer nawet nie zna rodzaju danych, które zna tylko program, który go używa. Domyślam się, że ponieważ RAM jest R AM i dlatego nie jest odczytywany sekwencyjnie, konkretny program po prostu mówi CPU, aby pobrać informacje z określonego adresu, a program określa, jak je traktować. Wydaje się, że pasuje to do programowania rzeczy, takich jak potrzeba rzutowania czcionek.
Czy jestem na dobrej drodze?
źródło
Odpowiedzi:
Twoje podejrzenie jest słuszne. Procesor nie dba o semantykę danych. Czasami jednak robi to różnicę. Na przykład niektóre operacje arytmetyczne dają różne wyniki, gdy argumenty są semantycznie podpisane lub niepodpisane. W takim przypadku musisz powiedzieć procesorowi, którą interpretację zamierzałeś.
Programiści muszą ustalić, jakie są jej dane. Procesor wykonuje tylko rozkazy, błogo nieświadomy ich znaczenia lub celów.
źródło
mov al, 42
jest rodzajem wysokiego poziomu - oczywiste jest, że istnieje tylko jedna możliwa instrukcja, którą można wywołać, ale wciąż jest nieco abstrakcyjna. Jednak użyciemov.8 al, 42
jawnie czyni to boleśnie oczywistym :)Jak już inni odpowiedzieli, dzisiejsze popularne procesory nie wiedzą, co zawiera dana pozycja pamięci; oprogramowanie decyduje.
Istnieją jednak inne możliwości. Maszyny Lisp na przykład zastosowały oznakowaną architekturę, która przechowywała typ każdej pozycji pamięci; w ten sposób sam sprzęt może wykonywać niektóre zadania w językach wysokiego poziomu.
I nawet teraz myślę, że możesz rozważyć bit NX w architekturze Intel, AMD, ARM i innych, aby zastosować tę samą zasadę: rozróżnij na poziomie sprzętowym, czy dana strefa pamięci zawiera dane lub instrukcje.
Ponadto, dla kompletności, w architekturach Harvarda (jak niektóre mikrokontrolery) dane i instrukcje są fizycznie oddzielone, więc CPU ma pewne pojęcie o tym, co czyta.
W tym pytaniu Quora znajduje się komentarz na temat działania oznaczonej pamięci, jej wpływu na wydajność i upadku, i wiele więcej.
źródło
Tak. Program pobiera bajt z pamięci i może interpretować go w dowolny sposób.
źródło
Brak adnotacji typu.
Pamięć RAM przechowuje czyste dane, a następnie program określa, co robić.
Z rejestrami procesora jest nieco trudniej, jeśli masz rejestry danego typu (np. FPU), mówisz, co jest w środku.
Operacje na rejestrach zmiennoprzecinkowych jawnie wykorzystują dane wpisane. Ty lub twój kompilator powiecie, co i kiedy należy tam umieścić, abyście nie mieli takiej swobody.
Komputer nie przyjmuje żadnych założeń dotyczących bazowych danych w pamięci RAM, aw rejestrach z jednym wyjątkiem - rejestry typowane w CPU są znanego typu, zoptymalizowane pod kątem radzenia sobie z tym. Ma to tylko pokazać, że istnieją miejsca, w których dane mają być typu oczekiwanego, ale nic nie stoi na przeszkodzie, aby rzutować ciągi na zmiennoprzecinkowe i pomnożyć je.
W językach programowania określasz typ, a w językach wyższego poziomu dane są ogólne, a kompilator / interpreter / VM koduje to, co jest w środku z narzutem.
Na przykład w C Twój typ wskaźnika mówi, co zrobić z danymi i jak uzyskać do nich dostęp.
Oczywiście możesz odczytać ciąg znaków (znaków) i traktować je jako wartości zmiennoprzecinkowe, liczby całkowite i mieszać je.
źródło
CPU nie dba o to, wykonuje kod asemblera, który po prostu przenosi dane, przesuwa je, dodaje lub pomnaża ...
Typy danych to koncepcja języka wyższego poziomu: w C lub C ++ musisz określić Typy dla każdego manipulowanego elementu danych; kompilator C / C ++ dba o przekształcenie tych danych w odpowiednie polecenia do przetworzenia przez CPU (kompilatory zapisują kod asemblera)
W niektórych językach nawet wyższego poziomu można wywnioskować typy: na przykład w Pythonie lub JavaScript nie trzeba określać typów danych, ale dane mają typ i nie można dodać ciągu z liczbą całkowitą, ale można dodać liczba zmiennoprzecinkowa z liczbą całkowitą: „kompilator” (który w przypadku Javascript jest kompilatorem JIT (Just in Time). Javascript jest często nazywany językiem „interpretowanym”, ponieważ w przeszłości przeglądarki interpretują kod JavaScript, ale obecnie silniki JavaScript są kompilatorami.
Kod, zawsze kończy się kompilacja do kodu maszynowego, ale oczywiście format kodu maszynowego zależy od komputera, na który celujesz (64-bitowy kod x86 nie będzie działał na maszynie 32-bitowej x86 lub procesorze ARM)
Tak więc w uruchomionym interpretowanym kodzie jest zaangażowanych wiele warstw.
Java i C # są innymi interesującymi, ponieważ kod Java lub C # jest technicznie „kompilowany” do pliku binarnego Java (kod bajtowy), ale sam ten kod jest następnie interpretowany przez środowisko wykonawcze Java, które jest specyficzne dla sprzętu bazowego (należy zainstalować środowisko JRE ukierunkowane na odpowiednią maszynę do uruchamiania plików binarnych Java (Jars))
źródło
Typy danych nie są funkcją sprzętową. Procesor zna kilka (cóż, dużo) różnych poleceń. Są to tak zwane zestaw instrukcji procesora.
Jednym z najbardziej znanych jest zestaw instrukcji x86 . Jeśli szukasz „pomnóż” na tej stronie, otrzymasz 50 wyników.
MULPD
iMULSD
do mnożeniaFIMUL
liczb podwójnych, do mnożenia liczb całkowitych ...Te polecenia działają na rejestrach. Rejestry to gniazda pamięci, które mogą zawierać stałą liczbę bitów (często 32 lub 64, w zależności od architektury używanej przez procesor), bez względu na to, co te bity reprezentują. Stąd instrukcja CPU interpretuje wartości rejestrów w inny sposób, ale same wartości nie mają typów.
Przykład podany na PyCon 2017 przez Stuarta Williamsa :
źródło
Dokładnie. Ale pamięć RAM nie jest odczytywana „sekwencyjnie” i oznacza pamięć o dostępie bezpośrednim, co jest dokładnie odwrotne.
Poza tym wiedząc, co bajt jest , nie wiem nawet, czy jest to bajt lub fragment większej pozycji jak liczbę zmiennoprzecinkową.
Chciałbym dodać do innych odpowiedzi, podając kilka konkretnych przykładów.
Zastanów się
01000001
. Program może kopiować je z jednego miejsca do drugiego jako część dużej paczki danych bez względu na jego znaczenie. Ale skopiowanie go na adres używany przez bufor wideo w trybie tekstowym spowoduje, że literaA
będzie wyświetlana w pewnej pozycji na ekranie. Dokładnie taka sama akcja, gdy karta jest w trybie graficznym CGA, wyświetli czerwony i niebieski piksel.W rejestrze może to być liczba 65 jako liczba całkowita. Wykonywanie arytmetyki w celu ustawienia bitu 32 może oznaczać wszystko bez kontekstu, ale może w szczególności polegać na zmianie litery na małe litery.
Procesor 8086 (nadal) ma specjalne instrukcje o nazwie DAA ※, które są używane, gdy rejestr zawiera 2 cyfry dziesiętne, więc jeśli właśnie użyłeś tej instrukcji, interpretujesz ją jako dwie cyfry
41
.Programy ulegają awarii, ponieważ słowo pamięci jest odczytywane, myśląc, że jest wskaźnikiem, gdy zapisano tam coś innego.
Za pomocą debugera, sprawdzającego pamięć, mapa służy do kierowania interpretacją wyświetlacza. Bez tej informacji o symbolu debuger niskiego poziomu pozwala określić: pokaż ten adres jako 16-bitowe słowa, pokaż ten adres jako długi zmiennoprzecinkowy, jako ciągi znaków ... cokolwiek. Zastanawianie się nad zrzutem pakietu sieciowego lub nieznanym formatem pliku stanowi wyzwanie.
Jest to główne źródło mocy i elastyczności we współczesnej architekturze komputerowej: komórka pamięci może oznaczać cokolwiek , dane lub instrukcje, domyślnie tylko w tym, co „znaczy” dla programu przez to, co robi z wartością i jak wpływa na kolejne operacje. znaczenie jest głębsze niż szerokość całkowita: czy te znaki ... znaki w ascii lub ebcdic? Tworzysz słowa w języku angielskim lub w kodach produktów SQU? Adres do wysłania lub adres zwrotny, z którego pochodzi? Interpretacja najniższy poziom (bity logiczne; całkowitą podobny, podpisane lub niepodpisane; pływak; BCD; pointer) jest kontekstowa na poziomie instrukcji ustawiony, ale widać, że to wszystko kontekst w pewnym poziom: doadres jest taki, jaki jest, ponieważ znajduje się na kopercie. Jest kontekstowy z zasadami listonosza, a nie CPU. Kontekst jest jednym wielkim kontinuum, z bitami na jednym końcu.
※ Przypis: Instrukcja DAA jest zakodowana jako bajt
00100111
. Tak więc ten bajt jest wspomnianą wcześniej instrukcją, jeśli jest czytany w strumieniu instrukcji, a cyfry,27
jeśli są interpretowane jako cyfry bcd, a 0x27 = 39 jako liczba całkowita, która jest liczbą 9 w ASCII, i częścią tablicy przerwań (połowa INT 13 2-bajtowy adres, używany w procedurach serwisowych BIOS).źródło
Jedynym sposobem, w jaki komputer wie, że miejscem w pamięci jest instrukcja, jest to, że rejestr specjalnego przeznaczenia zwany wskaźnikiem instrukcji wskazuje na nią w tym lub innym miejscu. Jeśli wskaźnik instrukcji wskazuje na słowo pamięci, jest ono ładowane jako instrukcja. Poza tym komputer nie ma możliwości poznania różnicy między programami a innymi typami danych.
źródło