Przeważnie piszemy program w języku wysokiego poziomu. Podczas nauki natknąłem się na język asemblera. Asembler konwertuje język asemblera na język maszynowy, a kompilator robi to samo z językiem wysokiego poziomu. Odkryłem, że język asemblera zawiera instrukcje takie jak move r1 r3, move 5 itp. I raczej trudno się go uczyć. Dlaczego więc stworzono język asemblera? Czy to ten, który pojawił się na pierwszym miejscu jeszcze przed językiem wysokiego poziomu? Dlaczego studiuję na temat asemblerów w mojej klasie inżynierii komputerowej?
programming-languages
education
history
Nithin Jose
źródło
źródło
Odpowiedzi:
„Więc dlaczego stworzono język asemblera?”
Język asemblera został stworzony jako dokładny skrót do kodowania na poziomie maszyny, abyś nie musiał zliczać zer i jedynek przez cały dzień. Działa tak samo jak kod poziomu maszynowego: z instrukcjami i operandami.
„Który był pierwszy?”
Wikipedia ma dobry artykuł na temat historii języków programowania
„Dlaczego studiuję na temat asemblerów w mojej klasie inżynierii komputerowej?”
źródło
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:
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:
Te wartości odpowiadają:
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):
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:
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:
To brzmi jak nasz dodatek z góry, zakładając, że
x
jest w rejestrze 1,y
jest w rejestrze 2 iz
powinien skończyć w rejestrze 3. Ale co z tą linią?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:
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.)
źródło
Tak, asembler był jednym z pierwszych języków programowania, w których jako tekst wprowadzano tekst, w przeciwieństwie do lutowania drutów, używania płytek wtykowych i / lub przełączania przełączników. Każdy język asemblera został stworzony tylko dla jednego procesora lub rodziny procesorów, ponieważ instrukcje odwzorowane bezpośrednio na kody operacyjne uruchamiane przez procesor.
Jeśli musisz zaprogramować sterowniki urządzeń lub napisać kompilatory, zrozumienie działania procesora jest nieocenione, jeśli nie jest wymagane. Najlepszym sposobem na zrozumienie tego jest napisanie kodu w asemblerze.
Jeśli spojrzysz na sposób, w jaki kompilator pisze kod, często spotyka się opcje wywoływania konwencji, których znajomości asemblera prawdopodobnie nie można zrozumieć.
Jeśli musisz rozwiązać błąd, a jedyne, co masz, to zrzut pamięci , to zdecydowanie musisz znać asembler, aby zrozumieć wynik, którym jest kod asemblera i jeśli masz szczęście, możesz go uzupełnić o instrukcje wyższego poziomu w języku wysokiego poziomu.
źródło
Pozwól mi dodać jeden mniej praktyczny aspekt. To (prawdopodobnie) nie jest powód historyczny, ale powód dla ciebie dzisiaj.
Zgromadzenie (w porównaniu do języków wysokiego poziomu) jest nagie . Nic nie ukrywa (odbywa się to w oprogramowaniu) i jest prosty w tym sensie, że ma stosunkowo niewielki, stały zestaw operacji.
Może to być pomocne przy dokładnej analizie algorytmu. Semantyka i przepływ kontrolny są tak proste, że zliczanie wszystkich operacji (lub oczekiwanej liczby) można wykonać poprzez oznaczenie wykresu przepływu kontroli zliczaniem przejść (prawdopodobieństw). Knuth robi to w swoich książkach TAoCP z wielkim skutkiem, demonstrując jedne z najbardziej rygorystycznych analiz algorytmów.
Anegdota: mój kolega nauczył się czytać Java Bytecode właśnie w tym celu.
źródło
Tutaj są odpowiedzi:
Kiedy potrzebujemy języka asemblera? na Programmers.SE
Dlaczego język asemblera jest nadal potrzebny, jeśli mamy języki wysokiego poziomu oferujące zaawansowane narzędzia? na Stackoverflow
Dlaczego warto uczyć się języka asemblera? autor: Gary L. Burt
Wszystkie te odpowiedzi wskazują na:
źródło
Asembler = kod maszynowy
Niektóre osoby wciąż zastanawiają się nad tym, w jaki sposób język asemblera różni się od kodów numerycznych rozumianych przez CPU.
To (choć prawda) całkowicie mija się z celem.
Jeśli chodzi o tłumaczenie, język asemblera i numeryczny (binarny, szesnastkowy, cokolwiek) to jedno i to samo.
Grokuj lub upuść.
Jeśli grokujesz zespół, wiesz, jak działa rzeczywisty komputer.
montaż Grokking obejmuje:
multiscalar
znaczyJeśli masz problem z montażem, masz prawie pełny obraz działania procesora podłączonego do klawiatury.
Musisz wykorzystać tę wiedzę, tak jak chirurg mózgu używa skalpela.
Nie potrzebuję żadnych śmierdzących abstrakcji
O ile nie zepsujesz zestawu (a tym samym procesora na stole operacyjnym), nigdy nie uwolnisz się od szponów abstrakcji maszyny RAM (lub niech Bóg nie zabroni maszynie Turinga horroru ).
Zespół L33t Hax0r 5k1llz
pomaga również zrozumieć, w jaki sposób 133thax0r udaje się pokonać schematy ochrony. (P: dlaczego ASLR nie działa ? Ponieważ
mov rax,fs:[28h]
go psuje ).0,1%
Nie liczy się znajomość montażu, ale znajomość maszyny, nad którą pracujesz.
Jeśli chcesz poznać maszynę, musisz ją zrozumieć, a to oznacza mówienie językiem maszyny.
Jeśli tego nie zrobisz, utkniesz z abstrakcją.
To nauka i to dobrze, ale to nigdy nie jest pełny obraz.
To tak, jakby nauczyć się mówić po khosie.
Jeśli nie dążysz do poziomu guru, najlepiej trzymaj się tego, co wiesz, te kliknięcia skomplikują ci życie .
Bo to zabawne.
źródło
Do tej pory nauczyłem się RPG II za pomocą IBM System 32, a później APL na 370. Chodziło mi o rozmiar i szybkość. Moja mantra była mniejsza i szybsza. Asembler jest najbardziej kompaktowym i najszybszym językiem na rynku. Wykonałbym programy testowe zarówno w C, jak i asemblerze. Tam, gdzie programy C wymagałyby setek Kb, równoważny program asemblacji często byłby mniejszy niż 5 Kb. Badając dane wyjściowe kompilatora C, znajdowałem kod, który sprawdzałby, a parametry ponownie sprawdzały, czy możliwe są błędy warunkowe, które często były rzadkie, egzotyczne i zupełnie niepotrzebne, a wszystko to trwało długo, ale największy nadmiar pamięci przepuszczał absolutnie wszystko do i ze stosu.
W dzisiejszym środowisku programistycznym pisanie kodu zapewnia dodatkowy poziom bezpieczeństwa i ochrony. Możliwość odczytywania informacji bezpośrednio z urządzenia, które nie jest dostępne dla języków wysokiego poziomu, umożliwia szyfrowanie za pomocą asemblera w taki sposób, że program może być używany tylko na tym konkretnym komputerze. Na przykład szyfrowanie klucza użytkownika za pomocą adresu MAC interfejsu sieciowego, a następnie parkowanie tego klucza na określonym niezarejestrowanym sektorze dysku twardego, a następnie oznaczenie sektora jako zły, aby inne pliki nie mogły go zastąpić. Oczywiście tracisz sektor, ale co to jest? 2048 lub 4096 bajtów z miliardów lub trylionów?
źródło