Dlaczego potrzebujemy języka asemblera?
Cóż, w rzeczywistości jest tylko jeden język, który kiedykolwiek będziemy potrzebować , nazywany „językiem maszynowym” lub „kodem maszynowym”. To wygląda tak:
0010000100100011
To jedyny język, w którym komputer może mówić bezpośrednio. Jest to język, w którym mówi procesor (a technicznie różne typy procesorów mówią w różnych wersjach). Jest też do bani patrzeć i próbować zrozumieć.
Na szczęście każda sekcja pliku binarnego odpowiada konkretnemu znaczeniu. Jest podzielony na kilka sekcji:
0010|0001|0010|0011
operation type source register other source destination register
0010 0001 0010 0011
Te wartości odpowiadają:
operation type 0010 = addition
source register 0001 = register 1
other source 0010 = register 2
destination register 0011 = register 3
Tak więc ta operacja spowodowałaby dodanie liczb do rejestrów 1 i 2 i umieszczenie tej wartości w rejestrze 3. Jeśli dosłownie umieścisz te wartości w CPU i powiesz „idź”, dodasz dwie liczby. Operacja „odejmij” może być tutaj 0011 lub coś, zamiast 0010 tutaj. Jakakolwiek wartość sprawi, że procesor odejmie.
Tak więc program mógłby wyglądać tak (nie próbuj tego zrozumieć, ponieważ stworzyłem tę konkretną wersję kodu maszynowego, aby wyjaśnić różne rzeczy):
instruction 1: 0010000100100011
instruction 2: 0011000110100100
instruction 3: 0101001100010111
instruction 4: 0010001001100000
Czy to jest do kitu? Zdecydowanie. Ale potrzebujemy go do procesora . Cóż, jeśli każdy kod maszynowy odpowiada konkretnej akcji, stwórzmy po prostu „angielski” skrót, a następnie, gdy zrozumiemy, co robi program, zamień go na prawdziwy binarny kod maszynowy i przekaż procesorowi do uruchomienia.
Nasza oryginalna instrukcja z góry mogłaby wyglądać następująco:
(meaning) operation type source register other source destination register
(machine code) 0010 0001 0010 0011
("English") add r1 r2 r3
Pamiętaj, że ta angielska wersja ma dokładne odwzorowanie na kod maszynowy . Więc kiedy piszemy wiersz tego „angielskiego”, tak naprawdę piszemy bardziej przyjazny i zrozumiały kod maszynowy.
To jest język asemblera. Właśnie dlatego istnieje i dlaczego został pierwotnie stworzony.
Aby zrozumieć, dlaczego potrzebujemy go teraz, przeczytaj powyższe odpowiedzi, ale kluczem do zrozumienia tego jest to: Języki wysokiego poziomu nie mają jednej reprezentacji to kod maszynowy. Np. W C, Python lub cokolwiek innego:
z = x + y
To brzmi jak nasz dodatek z góry, zakładając, że x
jest w rejestrze 1, y
jest w rejestrze 2 i z
powinien skończyć w rejestrze 3. Ale co z tą linią?
z = x * 2 + (y / 6) * p + q - r
Spróbuj przedstawić tę linię w 16 bitach pliku binarnego i powiedzieć procesorowi „iść”. Nie możesz Kod maszynowy nie ma instrukcji pojedynczej operacji do dodawania, odejmowania i czegokolwiek innego z 4 lub 5 zmiennymi jednocześnie. Najpierw należy go przekonwertować na sekwencję kodu maszynowego. To właśnie robisz, gdy „kompilujesz” lub „interpretujesz” język wysokiego poziomu.
Cóż, mamy do tego programy, więc po co nam teraz montaż? Powiedzmy, że twój program działa wolniej niż się spodziewasz i chcesz wiedzieć, dlaczego. Patrząc na „wynik” języka maszynowego tego wiersza, może on wyglądać następująco:
1010010010001001
0010001000010000
0110010000100100
0010001011000010
0010100001000001
0100010100000001
0010010101000100
0010101010100000
0000100111000010
Tylko po to, żeby zrobić jedną linię Pythona. Więc naprawdę chcesz to debugować?!?!?! NO . Zamiast tego poprosisz swojego kompilatora o podanie danych wyjściowych w formie, którą możesz łatwo zrozumieć, czyli w asemblerze w wersji odpowiadającej dokładnie temu kodowi maszynowemu. Następnie możesz dowiedzieć się, czy twój kompilator robi coś głupiego i spróbować to naprawić.
(Dodatkowa uwaga na radzie @ Raphaela: Możesz faktycznie konstruować procesory, które działają z rzeczami innymi niż kody binarne, takie jak kody trójskładnikowe (baza 3) lub kody dziesiętne, a nawet ASCII. Jednak ze względów praktycznych naprawdę utknęliśmy na systemie binarnym.)