Jak dokładnie przechodzimy od zestawów binarnych / heksadecymalnych do zestawów instrukcji asemblacyjnych?

13

Starałem się ostatnio trochę nauczyć programowania Embedded / Assembly, a także próbowałem nauczyć się najniższego poziomu (bramek i tym podobnych).

Jedną rzeczą mnie jednak zastanawia ... jest to, w jaki sposób „otrzymujemy” zestawy instrukcji. Rozumiem nieco, jak działają bramki / TTL i takie, ale nie widzę, jak się z tego dostać do mov, add, clr itp ...?

To chyba głupie pytanie ... ale myślę o pierwszych mikroprocesorach / kontrolerach i myślę ... jak dokładnie zaprojektowali zestaw instrukcji i sprawili, że działał?

edycja: Myślę, że dla Clarity, udaję, że mówię o pierwszym mikroprocesorze, jak przeszli od Binary do faktycznego utworzenia zestawu instrukcji?


źródło
2
Każda instrukcja ma wartość, kompilator konwertuje kod na te instrukcje w oparciu o strukturę kodu.
Ramhound,
1
Nie jestem pewien, czy doskonale rozumiem twoje pytanie, ale myślę, że możesz znaleźć odpowiedź tutaj , tutaj lub tutaj .
e-MEE,
3
jak przeszli z Binary do faktycznego tworzenia zestawu instrukcji? W rzeczywistości „nie” nie - przynajmniej na odwrót. Projektanci procesorów określają operacje, które wykona procesor, następnie tworzą z nich zestaw instrukcji, a następnie odwzorowują instrukcje (mnemoniki) na kody operacyjne (binarny kod maszynowy). @ Scott Whitlock podał dobrą odpowiedź poniżej, chciałem tylko odpowiedzieć na ostatnią część twojego pytania, ponieważ moje przypuszczenie, przynajmniej z mojego doświadczenia, jest odwrócone.
Radian
1
Ta naprawdę miła książka: www1.idc.ac.il/tecs wyjaśniła mi wszystko, większość rozdziałów jest dostępna bezpłatnie online. Tworzysz własny układ (w prostym języku deskryptorów sprzętowych) z nand gates, następnie asemblera, a następnie kompilatora, a następnie piszesz system operacyjny w języku, który stworzyłeś! Niesamowite rzeczy i jako ktoś bez dyplomu naukowego był to dla mnie czas dobrze spędzony!
bplus

Odpowiedzi:

18

Sercem procesora jest ALU . Jest odpowiedzialny za przyjęcie instrukcji (np. MOV), która jest tylko pewną z góry określoną liczbą cyfr binarnych, a także pobranie 0, 1 lub 2 operandów i wykonanie na nich odpowiedniej operacji. Najprostszą instrukcją może być NOP (brak operacji), która zasadniczo nic nie robi. Inną typową operacją jest DODAJ (dodaje dwie wartości).

ALU odczytuje i zapisuje dane zi do „rejestrów”. Są to małe lokalizacje pamięci wewnątrz procesora. Część instrukcji (2 do 3 bitów dla każdego wejścia w zależności od liczby posiadanych rejestrów) wskazuje, z którego rejestru należy czytać. W CPU poza jednostką ALU znajdują się jednostki, które obsługują ładowanie wymaganych danych (i instrukcji) z pamięci do rejestrów i zapisywanie wyników z rejestrów z powrotem do pamięci. Miejsce zapisu wyniku zostanie również zakodowane w kolejnych 2 lub 3 bitach.

Wybór „kodów operacyjnych”, który jest liczbą binarną reprezentującą operację, nie jest arbitralny. Dobrze dobrane kody zmniejszają złożoność ALU. Każdy bit lub grupa bitów ma tendencję do włączania i wyłączania niektórych bramek logicznych w ALU. Na przykład instrukcja ADD musiałaby umożliwić etapowi wyjściowemu wybranie wyniku wewnętrznej logiki dodawania. Podobnie instrukcja MUL wybrałaby wynik logiki mnożenia. W zależności od projektu całkiem prawdopodobne jest, że zarówno obwód sumujący, jak i mnożący faktycznie wykonują swoją operację na operandach wejściowych, a zmienia się tylko wybór wyjścia (co zostaje zapisane w bitach wyjściowych ALU).

Scott Whitlock
źródło
1
Chyba o co pytam, jak wybierają? A jak oni właściwie to przypisują?
1
@Sauron: Ponownie przeczytaj trzeci akapit i spróbuj zrozumieć binarne układy arytmetyczne i cyfrowe. Mogę reprezentować zestaw instrukcji zawierający 256 instrukcji 8-bitową linią w obwodzie cyfrowym. Oznacza to, że potrzebuję 8 portów IO na moich urządzeniach sprzętowych, aby przenieść każdy możliwy stan (2 stany na linię ^ 8 linii = 256 możliwych stanów). Jednostka przetwarzająca może następnie zdecydować, co zrobić z tym cyfrowym sygnałem wejściowym. Obwód cyfrowy oznacza, że ​​masz dwa stany sprzętowe: Hi i Lo, napięcie lub brak napięcia. Stąd pochodzi plik binarny. Reprezentacja binarna jest najbliższa metalu.
Falcon
3
@Sauron - wyszukaj Cyfrowe multipleksery, aby zobaczyć, w jaki sposób obwód cyfrowy może wybrać jedną z kilku wartości. Jeśli masz 8-bitową magistralę, potrzebujesz tylko 8 cyfrowych binarnych multiplekserów równolegle.
Scott Whitlock,
1
@ Falcon Ok ... Myślę, że to ma większy sens. Ciągle zapominam, że ostatecznie wszystko sprowadza się do sygnałów binarnych ... a nawet instrukcja taka jak „mov” jest nadal reprezentowana jako binarna.
1
@Sauron - Przeszukaj procesor, pomoże ci zrozumieć, jakie są kody operacyjne i jak działają. Dlaczego wybrane kody operacyjne są nieistotne, nawet pytanie „dlaczego” nie ma większego sensu. Zrozumienie sposobu ich wyboru może pomóc ci lepiej zrozumieć procesor i jego strukturę.
Ramhound,
9

Przyjmę twoje pytanie dosłownie i omówię głównie mikroprocesory, a nie ogólnie komputery.

Wszystkie komputery mają jakiś kod maszynowy. Instrukcja składa się z kodu operacyjnego i jednego lub większej liczby operandów. Na przykład instrukcja ADD dla Intel 4004 (pierwszy mikroprocesor) została zakodowana jako 1000RRRR, gdzie 1000 to kod operacji dla ADD, a RRRR reprezentuje numer rejestru 0-15 (0000-1111 w systemie binarnym).

Wszystkie pozostałe instrukcje, które odnoszą się do jednego z 16 rejestrów 4-bitowych (takich jak INC, ISZ, LD, SUB, XCHG) również używają niskich 4-bitów do kodowania numeru rejestru oraz różnych kodowań górnych 4-bitów w celu określenia kod operacyjny. Na przykład ADD, SUB, LD i XCHG używają kodów 1000, 1001, 1010 i 1011 (wszystkie w postaci binarnej) w połączeniu z polem rejestru. Dzięki temu możesz zobaczyć, jak wzorzec służy do uproszczenia logiki.

Pierwsze programy komputerowe zostały napisane ręcznie, ręcznie kodując jedynki i zera, aby stworzyć program w języku maszynowym. Zostało to następnie zaprogramowane w ROM (pamięć tylko do odczytu). Teraz programy są na ogół zapisywane w elektrycznie kasowalnej pamięci Flash, w przypadku mikrokontrolerów, lub zabraknie pamięci RAM, jeśli mikroprocesory. (Ten ostatni nadal potrzebuje pamięci do odczytu).

Język maszynowy staje się naprawdę nudny, dlatego opracowano programy asemblera, które przyjmują mnemoniczny język asemblera i tłumaczą go, zwykle jedną linię kodu asemblera na instrukcję, na kod maszynowy. Więc zamiast 10000001 napisałby ADD R1.

Ale pierwszy asembler musiał zostać napisany w kodzie maszynowym. Następnie można go przepisać we własnym kodzie asemblera, a wersja w języku maszynowym zostanie użyta do złożenia go po raz pierwszy. Następnie program może się sam złożyć (nazywa się to ładowaniem).

Ponieważ pierwszy mikroprocesor został opracowany na długo po pojawieniu się komputerów mainframe i minikomputerów, a 4004 i tak nie nadawał się do uruchomienia asemblera, Intel prawdopodobnie napisał cross-asembler, który działał na jednym z jego dużych komputerów, i przetłumaczył kod asemblera dla 4004 w obraz binarny, który można zaprogramować w pamięci ROM.

tcrosley
źródło
4

Komputer na bardzo niskim poziomie może być reprezentowany przez ścieżkę danych i kontrolę . Przeglądając je razem, możesz dużo czytać, ponieważ ma to fundamentalne znaczenie w architekturze / projektowaniu cyfrowym.

Zrobię co w mojej mocy, aby podsumować:

Jak wspomniano tutaj, w sercu mamy ALU - co należy wiedzieć o ALU (i innych częściach procesora), to że można go konfigurować dla różnych operacji. Mówiąc dokładniej, mamy możliwość rekonfiguracji ścieżki danych , czyli w jaki sposób są pobierane parametry, jakie operacje należy wykonać i gdzie są później przechowywane. Wyobraź sobie, że potrafisz manipulować tymi trzema rzeczami - to nasza kontrola .

Jak to osiągamy? Jak już wspomniano, możemy skorzystać z logiki cyfrowej niskiego poziomu i stworzyć multipleksery dla różnych ścieżek. Multipleksery są kontrolowane za pomocą zestawu bitów wejściowych - skąd te bity są pobierane? Zakodowane z samych instrukcji. Na wynos: instrukcje takie jak mov, add itp. Są tylko zestawem bitów, które informują CPU, jak skonfigurować jego ścieżkę danych dla określonej operacji. To, co czytasz (mov, dodaj), to czytelna dla człowieka forma (język asemblera), a nasz program definiuje procedurę ścieżek danych i operacji.

Przepraszam, jeśli jest to nadmierne uproszczenie bardziej złożonych procesów dla tych, którzy są bardziej kompetentni w tej dziedzinie. Do Twojej wiadomości, wymiana stosów w inżynierii elektrycznej byłaby doskonałym miejscem do zadawania tego pytania, ponieważ dotyczy logiki na bardzo niskim poziomie.

Jon
źródło
3

jeśli rozumiem twoje pytanie, nie rozumiem, w jaki sposób bin / hex lub montaż są powiązane.

Zakładam, że najważniejsze jest pytanie, w jaki sposób mogę dostać się z podstawowych bramek ORAZ, LUB NIE, do instrukcji takich jak ruch, ładowanie, przechowywanie, dodawanie itp.

Mam swój własny zestaw instrukcji do nauczania, który stworzyłem od zera, i zawiera on niektóre szczegóły, jak powiedzieć, że dodawanie i odejmowanie działa od podstawowych bram i takich rzeczy http://github.com/dwelch67/lsasim .

Poszukaj książki o kodzie (coś coś) od Petzolda. Może zacząć od podstaw, ale powoli prowadzi cię od niczego, co ma związek z komputerami i elektroniką, do binarnych, szesnastkowych i do podstawowych bram itp.

Zastanawiasz się, jak dziś zbudujesz jeden od zera, czy jak to zrobili w ciągu dnia? Dzisiaj zaczniesz od definicji zestawu instrukcji. po prostu usiądź i napisz to, myślisz o rodzajach instrukcji, jakie musisz mieć ładunki, przechowuje, przenosi i alu rzeczy, a następnie ile rejestrów, jak duże rejestry, to po części wpływa na rozmiar instrukcji, myślisz o wielkości instrukcji ...

Pozwól, że przestanę i zapytam, jak piszesz program? Zaczynasz od pustego ekranu w edytorze tekstu? Masz pojęcie o zadaniu, które próbujesz rozwiązać, potrzebnych zmiennych, funkcjach, języku programowania itp. Każda osoba jest inna, ale do pewnego stopnia robisz to trochę (powiedz, definiowanie i pisanie funkcji), trochę tego (tworzenie plików nagłówkowych z definicjami wielokrotnego użytku, wyliczeniami, strukturami i innymi), i trochę innych rzeczy (po prostu kod, wypełnij funkcje zmiennymi i kodem). I krążysz wokół różnych zadań, w końcu czujesz, że masz równowagę między wielkością kodu, szybkością, czytelnością, jakością, funkcjonalnością itp. Nie inaczej w projektowaniu sprzętu. projektanci sprzętu również używają języków programowania (vhdl, verilog) i przechodzą ten sam proces,

Podobnie jak wymyślenie programu, który równoważy pragnienia, wydajność, rozmiar, funkcje itp. Być może masz narzucone pewne reguły projektowe, które chcesz lub które twój szef zmusił itp. Podobnie jak w przypadku projektowania oprogramowania długo po wstępny projekt do wdrożenia może się okazać, że masz duże błędy i musisz wrócić do wstępnego projektu i zmienić zestaw instrukcji, duże lub małe zmiany. Może zajść tak daleko, aby mieć kompilator i symulowany procesor, aby znaleźć naprawdę potrzebne kilka konkretnych instrukcji, które znacznie poprawiają jakość skompilowanego kodu, wydajność itp.

Więc wymyśliłeś zestaw instrukcji od zera, wykorzystałeś pewne doświadczenie w projektowaniu sprzętu, aby pogrupować podobne instrukcje z podobnymi wzorami bitowymi, aby można je było łatwiej dekodować, nie tylko do programowania w języku sprzętowym, ale oszczędza energię i bramki dobry towar. W dzisiejszych czasach stworzyłbyś coś w rodzaju symulatora, rozumiem, że ARM był najpierw symulatorem oprogramowania, a później projekty sprzętu przyszły, nie wiem, czy to prawda, ale trzymanie się tej historii. Zależy to od zespołu, niektóre zespoły mogą być tylko ludźmi sprzętowymi i chcą po prostu zająć się programowaniem w hdl, niektórzy tacy jak ja mogą chcieć zrobić trochę obu. Obecnie dostępne są dobre symulatory języka sprzętowego, więc nie musisz budować żadnego sprzętu, który skompilujesz i symulujesz, i wykonujesz większość debugowania za pomocą programu / pakietu do symulacji sprzętu. zespół programistów może opracowywać asemblery i kompilatory dla zestawu instrukcji oraz korzystać z symulowanych programów pamięci RAM i ROM do symulowanego procesora i sprawdzać go. przeprowadziliśmy symulację pełnego rozruchu systemu Linux na procesorze, nad którym pracowałem niedawno, zajęło to wiele godzin, ale zadziałało (znalazłem błąd logiki w ten sposób).

Więc teraz o to, o co naprawdę myślę, że pytasz. Jak przejść z podstawowych bramek do procesora z zestawem instrukcji. Cóż, podstawowe bramki ORAZ, LUB, NIE, są naprawdę analogowe, nie mają pojęcia czasu, nie można natychmiast zmienić napięcia na wejściach, a gdy zmieniasz to napięcie, wyjścia zaczynają się zmieniać. bramki są zbudowane z tranzystorów, a tranzystory są wzmacniaczami, pomnóż je przez pewną liczbę i pozwól, aby tyle prądu przepływało po drugiej stronie. kiedy używamy ich jako bramek logicznych, w rzeczywistości je nadmiernie nasycamy, napięcie wejściowe jest tak wysokie lub niskie, że tranzystor może napędzać tylko maksymalne napięcie lub brak napięcia (prądu). w zasadzie tranzystor zamienia się w przełącznik. Krótko mówiąc, nie ma pojęcia czasu. Aby mieć zestaw instrukcji, musimy wykonać instrukcje, aby wykonać sekwencję przez program, musimy mieć pojęcie, że teraz jesteśmy przy tej instrukcji, i w następnym przedziale czasowym będziemy pracować nad tą instrukcją. Podobnie jak w grze polegającej na zamianie wzmacniacza w przełącznik, grasz w podobne gry za pomocą podstawowych bramek logicznych z zegarem. zegary pochodzą z magicznych kryształów w puszce (nie warto tu wchodzić), które wytwarzają napięcia, które włączają się i wyłączają w ustalonym tempie. użyj tego napięcia w równaniach logicznych i możesz zacząć porządkować sekwencje. zegary pochodzą z magicznych kryształów w puszce (nie warto tu wchodzić), które wytwarzają napięcia, które włączają się i wyłączają w ustalonym tempie. użyj tego napięcia w równaniach logicznych i możesz zacząć porządkować sekwencje. zegary pochodzą z magicznych kryształów w puszce (nie warto tu wchodzić), które wytwarzają napięcia, które włączają się i wyłączają w ustalonym tempie. użyj tego napięcia w równaniach logicznych i możesz zacząć porządkować sekwencje.

bardzo, bardzo krótko pomyśl o tej tabeli prawdy:

0 0 0
0 1 1
1 0 1
1 1 0

binarnie:

0 + 0 = 1
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10 (2 decimal)

koncentrując się tylko na lsbit, jednym bitowym dodatku, powyższa tabela prawdy opisuje jeden bitowy dodatek. Opisuje także bramę XOR. Jedno wejście jest prawdziwe lub drugie, ale nie jedno i drugie.

Aby uzyskać więcej niż jeden bit, musisz spojrzeć na bity przeniesienia, przeniesienia i przeniesienia, i potrzebujesz trzech bitów sumatora, dwóch operandów i przeniesienia z dwoma wyjściami, przeniesienia i bitu wynikowego. Po dodaniu sumatora z trzema wejściami i dwoma wyjściami można kaskadować tak szeroki, jak chcesz. Ale nadal jest to analogiczne, bramy zmieniają się natychmiast.

Jak zmieniasz ten analogowy adder w instrukcję ADD, czy masz logikę, która patrzy na instrukcję, która siedzi jako dane wejściowe do tych bram, które ustawiłeś. niektóre bity w instrukcji mówią, to jest instrukcja dodawania, niektóre bity mówią, że jeden operand jest taki i taki rejestr, może rejestr 7, inne bity mogą powiedzieć, że drugi operand to rejestr 4. i w zależności od architektury może mieć inny rejestr zdefiniowany w instrukcji, która mówi o umieszczeniu wyniku w rejestrze 2. Teraz logika to widzi, ponieważ potrzebuję, aby zawartość rejestru 7 była kierowana do jednego wejścia sumatora alu, a rejestracja danych wejścia 4 kierowana do sumatora, a ty trasujesz wyjście sumatora do zarejestrowania 2. Ponieważ zegar jest częścią tej logiki, istnieje okres od początku okresu zegarowego do początku następnego okresu zegarowego, w którym wszystkie sygnały analogowe uspokajają się i rozwiązują równanie logiczne, do którego są podłączone. Podobnie jak po włączeniu przełącznika światła, zmieniasz stan świateł z powiedz na wyłączony. to światło potrzebuje czasu, aby się rozgrzało i zasadniczo ustabilizowało. Tutaj niewiele się różni.

Istnieje pewna logika, która mówi, że jeśli ten okres zegara jest fazą wykonania instrukcji AND, to w następnym okresie zegara zapiszę wynik w rejestrze wyjściowym. jednocześnie zamierzam pobrać następną instrukcję itp. Więc dla współczesnych procesorów, gdzie wykonanie alu jest często tylko jednym okresem zegara, ponieważ logika analogowa może tak szybko rozwiązać równania logiczne. Starsze procesory, które trzeba było policzyć do pewnej liczby, pozostawić sumator podłączony, poczekać na x liczby cykli zegara na logikę sumatora do rozwiązania, a następnie próbkować wynik z wyjścia, podać alu różne wejścia, poczekać x liczbę cykli zegara na to rozwiązać, powtarzaj na zawsze lub do momentu zaniku zasilania.

Co rozumiem przez równania logiczne? po prostu, jeśli chcesz, możesz pomyśleć o tym w kategoriach bramek AND, OR, NOT. Dla każdego bitu wejściowego do obwodu sumatora alu istnieje równanie, prawdopodobnie bardzo długie równanie, które obejmuje zegar, który obejmuje przerzutniki (pojedyncze / pojedyncze bity pamięci), które zawierają bieżącą instrukcję (oraz równania, które zasilają każdy z nich bity pamięci) i ciągle. Weź jedną funkcję oprogramowania, którą napisałeś, w języku, w którym ją napisałeś, zakładając, że jest to funkcja, która pobiera dane wejściowe, wykonuje zadanie, a następnie kończy i zwraca wynik. Pomyśl o wszystkich możliwych kombinacjach danych wejściowych i o różnych ścieżkach wykonania dzięki tej funkcji. Być może napisałeś go w jakimś języku wysokiego poziomu, ale prawdopodobnie mógłbyś nawet w tym języku przepisać go, aby był bardziej prymitywny i bardziej prymitywny, używając wielu zagnieżdżonych struktur if-then-else. i może zejdź niżej do języka asemblera. Podobnie jak w przypadku równań, o których mówię, programista sprzętowy nie programuje w tych równaniach o długim uzwojeniu, tak jak prawdopodobnie nie programuje się w drzewach o długich uzwojeniach, jeśli-to-inaczej, w języku asemblera, gdy wybrany język programowania oszczędza tak wiele. Podobnie jak kompilator, którego używasz, zamienia mały kod źródłowy w zespół z długim nawinięciem z dużą ilością „jeśli-to-innych”, istnieje kompilator, który pobiera sprzętowy kod języka programowania i przekształca go w równania logiczne.

Wracając do pierwszego procesora (który dziś rozważymy jako mikrokontroler, ale wtedy był to procesor). Zrobiłeś wszystkie powyższe na papierze i nie używałeś sprzętowych języków programowania, tak naprawdę napisałeś równania logiczne, ale jeszcze ostrożniej wybrałeś wzory bitów dla instrukcji, aby liczba bramek i drutów do łączenia tych bram była tak prosta jak praktyczne. Na papierze ręcznie trzeba było stworzyć długą listę okablowanych bramek logicznych, a następnie narysować rzeczywiste elementy na wysadzonej wersji silikonowej maski. nawet dzisiaj układy scalone są wykonywane przy użyciu procesu podobnego do fotograficznego lub procesu podobnego do sitodruku w kategoriach laika, więc weźmiesz te niebieskie wydruki, jeśli chcesz, i zmniejszysz je, a następnie zastosujesz na warstwach krzemowych.

tutaj znowu w dniu, w którym wszyscy mieli lepsze podejście do asemblera i nie tylko moglibyście skończyć z programowaniem asemblera, ale nie musieliście mieć edytora tekstu ani asemblera, którym musielibyście napisać swoje pierwsze programy ręcznie, a potem używając podręcznika, ręcznie przekonwertowałem to na kod maszynowy, jedynki i zera. Na niektórych komputerach może być konieczne załadowanie pamięci RAM, zmieniając przełączniki, obracając bity adresu, obracając bity danych, aż będą zgodne z liczbami na papierze, przesuwaj bit zegara w górę, a następnie w dół i załadowałeś jedno miejsce pamięci jeden bajt instrukcji jednego z programów, powtórz kilkaset razy i mam nadzieję, że nie popełnisz błędów.

W ten sam sposób, w jaki pierwszy powiedzmy, że kompilator C został prawdopodobnie napisany w jakimś innym języku, potem stał się sam hostingiem, ponieważ został ponownie napisany w C i skompilowany przez pierwszy kompilator C, a następnie sam. Następnie kompilatory C zostały wykorzystane do wynalezienia innych języków programowania, które następnie stały się samosterowalne. Wynaleźliśmy systemy operacyjne i edytory tekstu, które się na nich opierały, i cała czarna magia pozostała dla kilku osób za zasłoną w kącie do zrobienia ...

tak, bardzo rozwiewany, to jest wielkie pytanie wymagające lat nauki i doświadczenia, aby naprawdę zrozumieć. spójrz na mój lsasim, nie twierdzę, że jestem ekspertem w czymkolwiek, ale jest to zestaw instrukcji, istnieje zarówno symulator, który wykonuje instrukcję napisaną w C, jak i inna implementacja procesora zaimplementowana w sprzętowym języku programowania, który może być symulowane przy użyciu różnych narzędzi. Plus prymitywny asembler i niektóre inne narzędzia i tym podobne. Być może, analizując niektóre z nich, w szczególności kod języka programowania sprzętowego, może wypełnić lukę w stosunku do tego, o co, jak sądzę, pytasz. Jeśli nie zmniejszyłem tej luki lub wykonałem długą uzwojenie stycznej, daj mi znać, że chętnie usunę tę odpowiedź (zakładając, że nie jestem w stanie spotykać się z wieloma programistami).

old_timer
źródło
To naprawdę nie odpowiada na pytanie autora, przynajmniej nie dodaje niczego do dyskusji, której nie zaakceptowała zaakceptowana odpowiedź. Twoja matematyka binarna nie jest w 100% poprawna. 1 + 1 wynosi 0 z przepełnieniem 1. W zależności od wielkości rejestru będzie to 2 lub 0.
Ramhound
@dwelch DAMN! Jestem twoim fanem serc, jeśli nic mniej. +1
AceofSpades
2

Procesory działają na zerach i jedynkach. Wszystkie instrukcje miały sekwencje bitów, które je definiowały. Thsi był kodem maszynowym. Tak trudno ludziom czytać i pisać. W pierwszym kroku zgrupowaliśmy zera i jedynki w 4-bitowych sekwencjach i użyliśmy od 0 do F, aby je przedstawić. Zmniejszyło to liczbę, które musieliśmy zapamiętać, ale nadal nie było łatwo zapamiętać kod szesnastkowy instrukcji.

Zaczęliśmy więc używać asemblera, który miał „słowa” takie jak MOV i ADD. Asembler zastąpiłby instrukcje prawidłowym zestawem 0 'i 1' konwertując "listing" zestawu na kod maszynowy.

W końcu opracowaliśmy języki „wyższego poziomu”, w których „instrukcje” mogą reprezentować całe sekwencje kodu maszynowego.

Jim C.
źródło
Do twojej wiadomości, ósemkowa była używana jako binarny skrót przed szesnastkowym.
ocodo
Slomojo ma rację, liczba ósemkowa, podstawa 8 wykorzystała 3 bity, została użyta wraz z hexem, podstawa 16 użyto 4 bity. Oktal miał tę zaletę, że wszyscy wiedzieli, co oznaczają liczby od 0 do 7. Ludzie, którzy nie używali Hex, byli często mistyfikowani przez „cyfry” od A do F.
Jim C
0

Ostatnio natknąłem się na to pytanie i mniej więcej rok temu, kiedy zacząłem podróżować tą ścieżką; Uważam, że jest to bardzo dobra strona z materiałami źródłowymi i referencyjnymi w odniesieniu do moich własnych pytań pokrewnych.


Część 1: Wstęp

Trochę o sobie:

W połowie lat 80., kiedy jeszcze byłem w szkole podstawowej, rozbierałem śmieciowe zestawy stereo, magnetowid i inne urządzenia elektroniczne, które były od lat 50. do 80. i patrzyły na płytki drukowane i zawsze chciałem wiedzieć, jak to zrobiły praca ... W jaki sposób faktycznie uzyskali sygnał transmisji, wyprodukowali audio, wideo, zrobili to i tamto itd. Mogłem rozpoznać poszczególne części tu i tam, takie jak rezystor, kondensator, dioda i tranzystor, ale nie wiedzieć, co zrobili lub jak funkcjonowali w tak młodym wieku.

Przez lata zawsze byłem wyjątkowy w matematyce, fizyce i chemii. Zrozumiałem matematykę w dużym stopniu i potrafiłem nawet czytać proste lub podstawowe układy z moich gimnazjów i liceów, które przyszły później, ale nigdy nie udało mi się dowiedzieć o bramkach logicznych i o tym, jak zostały zbudowane ... uczyć się algebry Boolean w liceum z mojej klasy logiki, prawdopodobieństwa i statystyki z wyróżnieniem. Wszystkie moje zajęcia z matematyki i przedmiotów ścisłych były zajęciami z wyróżnieniem. Nie wziąłem rachunku do drugiego semestru na uniwersytecie. Testowałem z College Algebra i wziąłem Trygonometrię jako kurs odświeżający. Mój najwyższy poziom matematyki w klasie to Rachunek II jednej zmiennej.

Gram w gry wideo od około 3 lub 4 lat. Jako dziecko miałem Atari, NES, Sega Genesis i PS1. W miarę jak dorastałem i do moich późnych nastolatków i wczesnych lat 20-tych, nabyłem PS2 i SNES z preferowanymi wybranymi tytułami. Nie uwzględnia to również gier komputerowych, które sięgają nawet Dooma!

Zawsze byłem zagorzałym graczem konsolowym i PC, a to nie obejmuje gier typu pinball i zręcznościowych.

Pierwszy komputer dostałem, gdy miałem około 12 lat na Boże Narodzenie na początku lat 90-tych. Dni DOS 6.0 i Windows 3.11 lub OS / 2. Od tego czasu zawsze znałem rodzinę systemów operacyjnych „Windows”, a wszystkie systemy, które miałem, to architektura Intel. Miałem ograniczone doświadczenie z Apple lub Mac ze szkoły lub college'u, ale nigdy nie miałem przywileju pracy na systemach Linux. Mam Cygwina i próbowałem swoich sił w nauce bash, ale jestem tak przyzwyczajony do Dos lub składni Command Prompt.

Na początku lat 90-tych dostałem kopię PC-World i wpisałem fragmenty kodu w QBasic, których nie znałem zbyt dobrze i starałem się, aby te programy działały. Jedynym, który odniósł sukces, był program zmieniający naciśnięcia klawiszy w głównym rzędzie klawiszy na różne dźwięki dzwonka. Nie mam na myśli dzwonków na telefonie komórkowym, mam na myśli ciągłą częstotliwość tak długo, jak długo przytrzymujesz klawisz.

Zawsze moją pasją było nie tylko chcieć wiedzieć, jak działają urządzenia elektroniczne w cyrkulacji na poziomie cyfrowym i logicznym, aby nauczyć się programować komputer, ale zawsze chciałem zrobić własne wideo Gry. Już na początku lat 90. chciałem tworzyć gry Frogger i Tetris ...


Stało się to moją wiodącą motywacją i chęcią zmierzenia się z jednym z najtrudniejszych rodzajów programowania lub rozwoju oprogramowania w dziedzinie informatyki, czyli 3D Game Engine Design. Istnieją inne dziedziny informatyki, które są równie trudne, jednak każdy wyrafinowany silnik gry zazwyczaj lub zwykle obejmuje prawie wszystkie z nich, ponieważ poszczególne komponenty lub silniki podrzędne wymagają ich technik i / lub właściwości.

Miałem trochę doświadczenia w programowaniu od czasów liceum, ale było to ograniczone do okropnego Visual Basic. Zacząłem podnosić i uczyć się C / C ++ w latach 2002 - 2003, dopiero kilka lat po ukończeniu liceum w 1999 roku. Do dziś nie mam żadnego doświadczenia na studiach informatycznych ani inżynierii komputerowej, ale poprzez poświęcenie i determinacja, nauczyłem się prawie każdej koncepcji związanej z komputerami, sprzętem, programowaniem, algorytmami itp. i nadal uczę się tak dużo, jak tylko mogę ...

W pierwszych dniach nauki C / C ++ miałem dostęp do Internetu, ale internet był w początkowej fazie, strony takie jak Amazon, Youtube, Facebook itp. Jeszcze nie istniały, wciąż były dni 56 tys. modemów telefonicznych, które podnoszą linię telefoniczną, jeśli nie masz drugiej linii dedykowanej. Renderowanie obrazu na ekranie zajęłoby kilka minut, nie mówiąc już o ciągłym odtwarzaniu wideo.

Więc jeśli chodzi o badania i naukę programowania w C ++, zasoby były ograniczone i większość z nich miała format tekstowy. Próbując poradzić sobie z projektami od wczesnych dni samouczków internetowych, wiele z tych projektów nie było w pełni ukończonych, pisarze byli profesjonalistami lub studentami i przyjęli wiele założeń, że czytelnik jest już zaznajomiony z wieloma potrzebnymi pojęciami, takimi jak kompilacja , łączenie i debugowanie oraz integracja biblioteki.

Dla kogoś, kto nie wie nic o tych tematach, jest zagubiony, ponieważ nie wie, co poszło źle, ani jak to naprawić i jak sprawić, aby działał poprawnie. W tych dniach zajęło mi wiele godzin prób i błędów przy bardzo ograniczonych zasobach. Prośba o pomoc, taką jak możemy teraz w tej witrynie lub szukanie szczegółowych wyjaśnień, które można znaleźć na stronie preferencji, nie była dostępna! Jeśli osobiście nikogo nie znałeś, nie było tylu, do których mógłbyś zwrócić się o pomoc!

Z biegiem czasu poprawiłem swoją wiedzę tu i tam, a ostatecznie Internet poprawił się do DSL, a teraz Internet High Speed, strony internetowe stały się bardziej interaktywne, filmy zaczęły się wyświetlać, jakość filmów poprawiła się z czasem, strony takie gdy Youtube zaczął się pojawiać, a sprawy stały się trochę łatwiejsze po stronie badawczej. Coraz więcej samouczków stało się łatwo dostępnych, niektóre były dobre i przydatne tam, gdzie inni uczyli złych praktyk ...

Spędziłem też dużo czasu na poszukiwaniu i nabywaniu niezbędnych narzędzi do rozwoju. Musiałem nauczyć się składni języka, kompilatora i procesu kompilacji, łączenia, budowania i debugowania. Następnie musiałem dowiedzieć się o różnych dostępnych bibliotekach i interfejsach API oraz o tym, jak skonfigurować moje projekty lub rozwiązania, aby połączyć wszystkie te zależności.

Przez lata obserwowałem rozwój, ewolucję i adaptację języka C ++ w miarę upływu czasu. Na początku pozostawał prawie taki sam przez wiele lat, ale w ciągu ostatnich 10 lat zmienił się dramatycznie w tym krótkim okresie od jego powstania.

Wspominam o tym wszystkim, ponieważ C ++ jest jednym z najtrudniejszych języków do opanowania ze względu na jego wszechstronność, moc, bogaty zestaw funkcji i możliwość strzelania sobie w stopę! I nawet ze wszystkimi zastrzeżeniami, jest to jeden z najpotężniejszych i preferowanych języków, który jest używany w wiodącej branży jako standard dla tego rodzaju rozwoju, ponieważ gdy jest wykonany poprawnie, jest szybki, zwięzły, niezawodny i wykorzystuje najmniejszy odcisk stopy.

Od tego czasu jestem samoukiem w C / C ++ od wielu lat z zamiarem skupienia się na programowaniu grafiki 3D i projektowaniu silnika gry. Włożyłem od 100 do 1000 godzin poszukiwań, badań i wiele więcej w czytanie, uczenie się i stosowanie tej wiedzy do projektowania użytecznych działających produktów i aplikacji. Zawsze miałem ochotę i chęć dowiedzieć się więcej, aby poprawić swoje umiejętności i umiejętności rzemieślnicze.


To był pierwszy etap, potem zacząłem czytać i pracować początkowo z DirectX 9.c, co zrobiłem w C / C ++, a nawet w C #. Potem przeszedłem na DirectX 10 i Legacy OpenGL 1.0. Z ich pochodził DirectX 11 i OpenGL 3.x - 4.x, a teraz nawet spróbowałem swoich sił w Vulkan.

Zbudowałem odnoszące sukcesy silniki gier, wykorzystując różne samouczki online, zarówno w formacie tekstowym, jak i wideo. Powiedziałem już, że mam silne doświadczenie matematyczne, ale było to ograniczone do rachunku I i II. Musiałem nauczyć się rachunku wektorowego, o którym miałem wiedzę z mojej klasy fizyki opartej na rachunku, ale jeśli chodzi o algebrę liniową z transformacjami afinicznymi i geometrią analityczną, musiałem się uczyć samodzielnie, gdy pewne równania, funkcje, metody, algorytmy i potrzebne były koncepcje. Potem musiałem nauczyć się tłumaczyć je na wydajny, czytelny, niezawodny, wielokrotnego użytku kod, który był ogólny i wolny od błędów, jak to możliwe, wprowadzając setki do tysięcy godzin debugowania.

To była cudowna podróż, która nauczyła się tematów i algorytmów obejmujących zarządzanie pamięcią, liczenie referencji, tworzenie instancji, rekurencję i wiele innych, które są używane w wielu, jeśli nie we wszystkich elementach silnika gry, gdzie są one ogromne. Mógłbym wymienić je wszystkie tutaj, ale byłoby to wystarczające informacje, aby wypełnić 3 lub 4 pola odpowiedzi warte napisania. Dołączę jednak listę ogólnych tematów, a nie ich podtematy.

Oto tematy lub lista tematów składająca się z w pełni funkcjonalnego silnika gry, który obejmuje wszystkie różne techniki renderowania, konfigurowanie potoków renderowania i cieniowania, techniki cieniowania i oświetlenia za pomocą shaderów, przetwarzania wstępnego i końcowego, buforów ramek, buforów tylnych , ładowanie obrazu, ładowanie i analizowanie modelu i dźwięku, tworzenie prymitywnych kształtów z właściwościami koloru, tekstury i normalnych współrzędnych z ręcznym mapowaniem tekstur, transformacjami obiektów, typami kamer, hierarchiami wykresów scen, klasami menedżerów dla tekstur, audio, czcionek i shaderów oraz zarządzanie pamięcią, system rejestrowania z obsługą wyjątków, wielowątkowe i równoległe techniki programowania, tworzenie sieci, silnik fizyki, wykrywanie kolizji, generator cząstek, animacja, sztuczna inteligencja, generowanie terenu, skrzynki na niebo i kopuły nieba, renderowanie wody,listowie i więcej ..., GUI z teksturowaną czcionką do renderowania tekstu, nakładki HUD, inwentaryzacje, generowanie map i makr, system stanów i automaty stanów, a na koniec napisanie parsera do stworzenia własnego języka skryptowego do automatyzacji wielu z tych obiektów możliwość zmiany wartości danych w silniku bez konieczności ponownej kompilacji poprzez załadowanie plików danych w celu zapełnienia obiektów danych i struktur w odpowiednich kontenerach podczas uruchamiania aplikacji.i na koniec napisanie parsera w celu stworzenia własnego języka skryptowego w celu automatyzacji wielu z tych obiektów, aby mieć możliwość zmiany wartości danych w silniku bez konieczności ponownej kompilacji poprzez ładowanie plików danych w celu zapełnienia obiektów danych i struktur w ich odpowiednich kontenerach przy uruchomieniu aplikacji.i na koniec napisanie parsera w celu stworzenia własnego języka skryptowego w celu automatyzacji wielu z tych obiektów, aby mieć możliwość zmiany wartości danych w silniku bez konieczności ponownej kompilacji poprzez ładowanie plików danych w celu zapełnienia obiektów danych i struktur w ich odpowiednich kontenerach przy uruchomieniu aplikacji.


Przez te wszystkie lata intrygowało mnie to, że chcę uczyć się języka asemblera, od ich chciałem dowiedzieć się o kompilatorach, asemblerach i prostych systemach operacyjnych, mam na myśli ich wewnętrzne funkcjonowanie, sposób ich budowy i projektowania.

Czas mijał, a potem zrobiłem krok i zacząłem się uczyć emulacji sprzętu. Skoncentrowałem się szczególnie na NES, ale ogólnie chciałem nauczyć się emulacji sprzętowej procesorów. Doprowadziło mnie to do zapoznania się z zestawem instrukcji, w którym znałem już tę koncepcję i czym ona była, ponieważ do pewnego stopnia znałem rodzinę x86 Intela do pewnego stopnia, ale teraz musiałem nauczyć się zestawu instrukcji 6502.

Jednak nurkując w to, skończyłem robić więcej badań i zacząłem uczyć się o architekturze zestawu instrukcji z perspektywy inżynierii. To pozwoliło mi dowiedzieć się, jak procesor jest zbudowany z bramek logicznych i jak bramki logiczne są zbudowane z tranzystorów wraz z innymi różnymi komponentami elektrycznymi. Skończyło się na tym, że dowiedziałem się o tym z dwóch perspektyw: od góry do dołu i od dołu do góry. Obie metody były bardzo skuteczne i myślę, że uczenie się od obu pomaga zbudować ten most lub lukę, w której oprogramowanie przebija sprzęt.

Odtąd musiałem odświeżyć moją algebrę boolowską i ostatecznie skończyłem uczyć się o K-Mapach, Tabelach Implikacji, Maszynach Stanowych zarówno Mealy, jak i Moore'a oraz różnych innych rzeczach, które wiążą Logikę Binarną i Arytmetykę z Bramkami Logicznymi Fizycznymi i Układami Scalonymi. I to prowadzi mnie do niechęci do przeszłości, w której zacząłem pracować z Logisimem i zacząłem uczyć się HDL, VHDL, Verilog itp.

Nauczyłem się tego wszystkiego w wolnym czasie, kiedy mogłem przez ostatnie 15 - 18 lat.


Oto niektóre strony i linki, które prowadziły mnie przez lata. Wiele z nich jest aktualnych, ponieważ wiele witryn, z których pierwotnie się nauczyłem, już nie istnieje, straciłem ich linki i nie pamiętam, lub wyszukiwarki pchnęły je z tyłu ich list wyszukiwania ...

  • Języki - C ++

  • Samouczki grafiki 3D i strony z zasobami

  • Serie i kanały Youtube obejmują powyższe tematy, a także sprzęt komputerowy i inżynierię elektryczną. Jest ich zbyt wiele, by wymienić, więc wymienię kilka z nich, które uważam za najbardziej przydatne i zaradne. Nie podam linków, ale możesz wyszukać te kanały na youtube.

    • 3Blue1Brown - Advanced Mathematics
    • Bisqwit - Zaawansowane programowanie w C / C ++ (projekty aplikacji) - Emulator sprzętu NES
    • Jason Turner - Zaawansowane nowoczesne techniki programowania w C ++
    • javidx9 - Zaawansowane programowanie w C / C ++ (projekty aplikacji) - Emulator sprzętu NES / Some Assembly
    • MIT OpenCourse - College College in Mathematics and Computer Science
    • Bilkent Online Courses - Kursy dla studentów informatyki i inżynierii komputerowej (procesory MIPS)
    • The Cherno - Zaawansowane tematy programowania C / C ++ i aplikacje - Rozwój silnika gry
    • Ben Eater - Inżynieria sprzętu - Praktyczne zastosowanie za pomocą paneli
    • Neso Academy - Inżynieria sprzętu - Teoria i koncepcje
    • Socratica - programowanie w języku Python
    • Mówiąc najprościej - Inżynieria sprzętu - Teoria i koncepcje
    • Bitwise - Advanced C / C ++ Projektowanie asemblera za pomocą emulacji sprzętowej
    • Bo Qian - C ++ Tematy w strukturach danych i algorytmach.
    • LineByLine - Programowanie Vulkan
    • Joshua Shucker - Programowanie wulkaniczne
    • www.MarekKnows.com - C ++, 3D Math and Engine Engine Development

I nie biorą one pod uwagę niektórych książek, które mam na te tematy.

-Uwaga- Proszę nie głosować w tej sprawie, ponieważ jest to tylko wiadomość dla czytelnika z moim własnym doświadczeniem i jest pozbawiona jakichkolwiek prób odpowiedzi lub odniesienia do pierwotnego pytania. W ciągu następnych kilku dni, kiedy będę miał czas; Dodam odpowiedź uzupełniającą, aby wyrazić swoje przemyślenia na temat pytania PO, podając przydatne linki jako odniesienie i zestaw zasobów, a także zaktualizuję tę odpowiedź, aby uwzględnić tutaj linki i zmodyfikować tę notatkę. Jest późno i obecnie nie mam czasu na poprawianie i edytowanie tego, co już napisałem. Zrobię to, kiedy będę mógł ”.

Francis Cugler
źródło
Właśnie zaktualizowałem tę odpowiedź lub post. Chciałem dodać drugą część, która faktycznie odpowie na pytanie, ale nie mam wystarczającej liczby punktów reputacji, aby to zrobić. Zdobycie potrzebnych punktów reputacji zajmie mi trochę czasu, zanim dodam drugą odpowiedź. Ten post nie jest faktyczną odpowiedzią, ale wykorzystam go jako odniesienie i przejrzę tabelę do uzasadnienia mojej prawdziwej odpowiedzi. Konieczne jest posiadanie niektórych z wyżej wymienionych zasobów, aby wypełnić lukę między oprogramowaniem a sprzętem.
Francis Cugler,
-2

U jego podstawa procesor jest zwykle tylko maszyną stanu. Musisz więc zrozumieć, w jaki sposób bramki logiczne, przerzutniki lub rejestry łączą się z tworzeniem maszyn stanu.

Maszyna stanów pobiera dane wejściowe i bieżący stan, przepuszcza je przez logikę logiczną (i potencjalnie arytmetyczną), a następnie dostarcza dane wyjściowe i następny stan. Jednym z wejść może być rejestr instrukcji. Jedno z wyjść może być włączeniem i wyborem źródła do ponownego załadowania rejestru instrukcji, może również zwiększyć lub załadować inny rejestr działający jako licznik programu. Dzięki temu oraz pewnej pamięci adresowalnej możesz sekwencjonować instrukcje.

Gdy masz już możliwość sekwencjonowania instrukcji, możesz użyć logiki, aby zdekodować te bity instrukcji oraz aktualny stan do innej wiązki bitów sterujących. Niektóre z tych bitów kontrolnych mogą działać jako dane wejściowe do sterowania grupą logiki, która może wykonywać logikę arytmetyczną i logiczną dla całego słowa, nazywając to ALU. Inne bity mogą ładować różne elementy lub wybierać dane wejściowe dla ALU. Inne bity mogą powiedzieć, gdzie przechowywać wyniki ALU. Lub załaduj rejestry adresujące. Lub napisz do pamięci lub innych wyjść. Itp.

Częścią projektowania zestawu instrukcji jest po prostu ustalenie, które kombinacje bitów po zdekodowaniu kontrolują wszystkie rejestry i sekwencjonowanie maszyny stanów. Dokonano tego i (ponownie) zoptymalizowano tysiące różnych sposobów.

Istnieją co najmniej 3 poziomy podręczników uniwersyteckich na ten nietrywialny temat.

hotpaw2
źródło
2
To nie wyjaśnia, w jaki sposób operacja MOV jest uwzględniana w wartości binarnej. Nie wspominając o tym, że operacja MOV jest wartością, jest to słowo kluczowe, którego używamy, więc nie musimy zapamiętywać 16 do 32 bitowej wartości binarnej.
Ramhound,