W jaki sposób nauka montażu pomaga w programowaniu? [Zamknięte]


132

Programuję w językach wyższego poziomu (Python, C #, VBA, VB.NET) od około 10 lat i zupełnie nie rozumiem, co się dzieje „pod maską”.

Zastanawiam się, jakie są korzyści z nauki asemblera i jak pomoże mi to jako programista? Czy możesz podać mi zasób, który pokaże mi dokładnie związek między tym, co piszę w kodzie wyższego poziomu, a tym, co dzieje się w asemblerze?


2
Jeśli naprawdę chcesz wiedzieć, co kryje się pod twoim kodem, zapoznaj się z instrukcją procesora Intel (tylko część wprowadzająca): download.intel.com/products/processor/manual/325462.pdf . Może jest to trochę głębsze, niż chciałeś, ale uważam to za przydatne.
superM

4
Jeśli chcesz wiedzieć, co dzieje się pod maską konkretnie w .Net, możesz dowiedzieć się więcej o CIL. Pod pewnymi względami jest podobny do montażu, ale o wiele wyższy poziom. Z tego powodu łatwiej to zrozumieć niż sam montaż.
sick

6
Jeśli nauczysz się asemblera, możesz uniknąć myślenia, że ​​optymalizujesz forpętlę, deklarując zmienne poza nią. przykład
StriplingWarrior

7
O mój Boże. Właśnie mi przypomniałeś o klasie języka asemblera, którą wziąłem na studia około rok temu. To niesamowite, że niezwykle proste rzeczy, które bierzemy za pewnik, są tłumaczone na setki, a nawet tysiące mniejszych i bardziej niższych operacji. Komputery to niezwykłe maszyny.
Radu Murzea,

14
Nauka asemblera da ci głęboką i trwałą miłość do koncepcji języka programowania, która ochroni cię przed NIGDY koniecznością pisania złożonego kodu w asemblerze.
Shadur

Odpowiedzi:


188

Ponieważ zrozumiesz, jak to naprawdę działa.

  • Zrozumiesz, że wywołania funkcji nie są bezpłatne i dlaczego stos wywołań może się przepełnić (np. W funkcjach rekurencyjnych). Zrozumiesz, w jaki sposób argumenty są przekazywane do parametrów funkcji i jak można to zrobić (kopiowanie pamięci, wskazywanie na pamięć).
  • Zrozumiesz, że pamięć nie jest za darmo i jak cenne jest automatyczne zarządzanie pamięcią. Pamięć nie jest czymś, co „po prostu masz”, w rzeczywistości trzeba nią zarządzać, dbać o nią i, co najważniejsze, nie zapominać (ponieważ musisz ją uwolnić samodzielnie).
  • Zrozumiesz, jak działa kontrola na najbardziej podstawowym poziomie.
  • Z pewnością docenisz konstrukcje w językach programowania wyższego poziomu.

Sprowadza się to do tego, że wszystkie rzeczy, które piszemy w języku C # lub Python, muszą zostać przetłumaczone na sekwencję podstawowych działań, które komputer może wykonać. Łatwo jest myśleć o komputerze w kategoriach klas, ogólnych i listowych, ale istnieją one tylko w naszych językach programowania wysokiego poziomu.

Możemy myśleć o konstrukcjach językowych, które wyglądają naprawdę ładnie, ale nie przekładają się zbyt dobrze na niskopoziomowy sposób robienia rzeczy. Wiedząc, jak to naprawdę działa, lepiej zrozumiesz, dlaczego rzeczy działają tak, jak działają.


12
+1 za „Sam bardziej docenisz konstrukcje w językach programowania wyższego poziomu”. Świetna odpowiedź.
DevSolo,

42
Tyle że po kilku tygodniach asmowania zaczniesz myśleć o C jako o języku programowania wysokiego poziomu. Chyba że rozmawiasz z deweloperami urządzeń wbudowanych niskiego poziomu, mówiąc, że na głos spowoduje, że większość ludzi pomyśli, że jesteś trochę szalony.
Dan Neely

19
@ Dan: To zabawne, jak te warunki zmieniają się w czasie. 20 lat temu, kiedy zaczynałem programować, poprosiłbyś kogoś, żeby powiedział: „Oczywiście C to język wysokiego poziomu!” To powinno być oczywiste; zapewnia znormalizowany model dostępu do sterty i pamięci. A to poważna abstrakcja od sprzętu; w języku niskiego poziomu musisz sam śledzić wszystkie adresy pamięci, a jeśli robisz coś naprawdę wymyślnego, piszesz własny alokator sterty! Muszę się więc zastanawiać, jakie są kryteria, które sprawiają, że dziś coś jest na wysokim lub niskim poziomie?
Mason Wheeler,

9
Wysoki poziom / niski poziom nie jest binarny. Wszechstronny programista, który w swojej karierze pisał zarówno asembler, jak i Python, mógłby uznać C lub C ++ za język średniego poziomu.
Russell Borogove

6
Są to ważne rzeczy do zrozumienia, ale można je łatwo omówić na poziomie abstrakcyjnym: np. W kursie wprowadzającym na temat komputerów na poziomie instrukcji maszynowych. Nie jestem programistą asemblera, ale dobrze je rozumiem, jeśli sam tak mówię. W niektórych odpowiedziach SO widzę dyskusję o pamięci podręcznej instrukcji i potokach, a te rzeczywiście powodują, że kręci mi się w głowie; ale tego poziomu podinstrukcji brakuje (jak dotąd) w odpowiedziach. Jaka jest więc korzyść z nauki programowania asemblera, a nie z kursu podstawowego?
Alexis

33

Zapewni to lepsze zrozumienie tego, co „dzieje się pod maską” oraz w jaki sposób działają wskaźniki oraz znaczenie zmiennych rejestru i architektury (przydzielanie i zarządzanie pamięcią, przekazywanie parametrów (według wartości / przez odniesienie) itp.).

Na szybki rzut oka z C, jak to jest?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

skompiluj gcc -S so.ci spójrz na dane wyjściowe zestawu w so.s:

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

2
+1: Dobra wskazówka! Możesz się wiele nauczyć, patrząc na to, co robi kompilator C.
Giorgio

8
... Czy SOS było zamierzone? (wezwanie pomocy itp.)
Izkata,

1
@Izkata ha ha .. dobra, nawet tego nie zauważyłem. Mam standardowy so.cplik do pytań o przepełnienie stosu (jak mam so.py, so.awkitp.), Aby szybko przetestować. So.S .. :)
Levon,

9
Jeśli się kompilujesz gcc -O -c -g -Wa,-ahl=so.s so.c, możesz zobaczyć dane wyjściowe zestawu dla każdej linii kodu C. To sprawia, że ​​trochę łatwiej jest zrozumieć, co się dzieje.
Mackie Messer,

1
Tak, wyjście jest długie. Możesz wyszukać 5:so.ckod w wierszu 5 so.c.
Mackie Messer,

30

Myślę, że odpowiedź, której szukasz, znajduje się tutaj: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language

Cytat z artykułu:

Chociaż to prawda, prawdopodobnie nie znajdziesz się przy pisaniu aplikacji następnego klienta w asemblerze, wciąż możesz wiele zyskać na nauce montażu. Obecnie język asemblera jest używany przede wszystkim do bezpośredniej manipulacji sprzętem, dostępu do specjalistycznych instrukcji procesora lub rozwiązywania krytycznych problemów z wydajnością. Typowe zastosowania to sterowniki urządzeń, systemy wbudowane niskiego poziomu i systemy czasu rzeczywistego.

Faktem jest, że im bardziej złożone stają się języki wysokiego poziomu, i im więcej ADT (abstrakcyjnych typów danych) jest zapisywanych, tym więcej nakładów na obsługę tych opcji. W przypadku .NET może być rozdęty MSIL. Wyobraź sobie, że znasz MSIL. Tutaj lśni język asemblera.

Język asemblera jest tak blisko procesora, jak to tylko możliwe, jako programista, więc dobrze zaprojektowany algorytm płonie - montaż doskonale nadaje się do optymalizacji prędkości. Wszystko zależy od wydajności i wydajności. Język asemblera daje Ci pełną kontrolę nad zasobami systemu. Podobnie jak linia montażowa, piszesz kod, aby wypychać pojedyncze wartości do rejestrów, zajmować się adresami pamięci bezpośrednio w celu pobierania wartości lub wskaźników.

Pisanie w asemblerze oznacza dokładne zrozumienie, w jaki sposób procesor i pamięć współpracują ze sobą, aby „sprawić, że coś się stanie”. Ostrzegam, język asemblera jest tajemniczy, a rozmiar kodu źródłowego aplikacji jest znacznie większy niż w języku wysokiego poziomu. Ale nie miejcie złudzeń, jeśli jesteście gotowi poświęcić czas i wysiłek na opanowanie zgromadzenia, wyzdrowiejecie i będziecie wyróżniać się na polu.

Dodatkowo polecam tę książkę, ponieważ ma ona uproszczoną wersję architektury komputera: Wprowadzenie do systemów obliczeniowych: od Bits and Gates do C i Beyond, 2 / e Yale N. Patt, University of Texas w Austin Sanjay J. Patel, Uniwersytet illinois w Urbana-Champaign


7
Opisuje to, do czego służy ASM, i wspomina, że ​​HLL są wzdęte, ale jedyną konkretną korzyścią uczenia się ASM jest pisanie superszybkiego kodu. Tak, ale nawet jeśli nauczysz się ASM, jakie jest prawdopodobieństwo, że włączysz go do aplikacji? Zakładając, że piszesz aplikacje biznesowe, a nie kontrolery sprzętowe lub sterowniki urządzeń.

+1 @notkilroy, dziękuję za link, a zwłaszcza zalecenie dotyczące książki
Anthony

2
@Jon, naprawdę nie rozumiem, dlaczego byś to zrobił, jeśli tworzysz oprogramowanie biznesowe. To jedno, jeśli jesteś DBA, piszesz kompilator lub masz ograniczone miejsce w pamięci, ale nie sądzę, aby wiele osób dotykało go często. Optymalizacją zajmuje się głównie kompilator, który jest największym powodem pisania w asemblerze. Czasami pomaga to w śledzeniu wycieków pamięci.
Brynne,

Ponieważ specjalizuję się w tworzeniu aplikacji biznesowych, polegam przede wszystkim na narzędziach programistycznych opartych na SQL, które używają 4GL. Pozwalają mi szybko prototypować aplikację i dostosowywać ją do systemu produkcyjnego. Rzadko muszę pisać wywoływane funkcje cfunc. Czas na dostawę i czas na modyfikację są ważnymi czynnikami w moim świecie!
Frank R.

2
Całkiem się nie zgadzam. Zautomatyzowany optymalizator często może pokonać programistę w tworzeniu szybkiego montażu.
DeadMG,

22

Moim skromnym zdaniem niewiele to pomaga.

Bardzo dobrze znałem montaż x86. Pomogło mi to trochę, gdy na moich kursach pojawił się montaż, pojawił się raz podczas wywiadu i pomógł mi udowodnić, że kompilator (Metrowerks) generuje zły kod. To fascynujące, jak naprawdę działa komputer, i czuję się bogatszy intelektualnie, że się go nauczyłem. W tym czasie gra była bardzo przyjemna.

Jednak dzisiejsze kompilatory lepiej generują asemblowanie niż prawie każdy na prawie dowolnym fragmencie kodu. O ile nie piszesz kompilatora lub nie sprawdzasz, czy kompilator działa prawidłowo, prawdopodobnie marnujesz czas, ucząc się go.

Przyznaję, że wiele pytań, które programiści C ++ wciąż z powodzeniem zadają, jest udzielanych przez znajomość asemblera. Na przykład: czy powinienem używać zmiennych stosu lub sterty? powinienem przekazać według wartości lub stałej referencji? Jednak prawie we wszystkich przypadkach uważam, że tych wyborów należy dokonywać w oparciu o czytelność kodu, a nie oszczędność czasu obliczeniowego. (Np. Używaj zmiennych stosu, ilekroć chcesz ograniczyć zmienną do zakresu.)

Moja skromna sugestia polega na skoncentrowaniu się na umiejętnościach, które naprawdę mają znaczenie: projektowaniu oprogramowania, analizie algorytmów i rozwiązywaniu problemów. Z doświadczeniem w tworzeniu dużych projektów poprawi się Twoja intuicja, co znacznie zwiększy twoją wartość niż znajomość montażu (moim zdaniem).


2
Nie zgadzam się Jeśli masz rozległą wiedzę na temat określonego algorytmu i dobrą znajomość sprzętu, zwykle można utworzyć kod asemblacji, który jest lepiej zoptymalizowany niż to, co może stworzyć kompilator, ponieważ musi on być bezpieczny. Zrozumienie, w jaki sposób Twój kod jest przetłumaczony na asembler, pomaga również podczas optymalizacji.
Leo

Optymalizacja nie jest powodem do nauki. W tym aspekcie zgadzam się z Neilem G. Neil G nie ma jednak sensu; Nie docenia, w jaki sposób jego podstawowa znajomość prawdziwej maszyny informuje o tym, jak używa języka wysokiego poziomu.
Warren P,

Z mojego doświadczenia wynika, że ​​algorytm jest wykonywany szybko przez jego implementację, pomiar rzeczy, znajdowanie sposobów optymalizacji, implementację lepszego sposobu itp. Itd. Itd. Problem z montażem polega na tym, że jego wdrożenie zajmuje wiele lat, więc nie będziesz mieć możliwość powtórnego udoskonalenia.
gnasher729

Obecnie jest bardzo mało przypadków kodowania w asemblerze, ale wiedza o tym, jak to działa, jest po prostu bezcenna i bardzo pomoże tym, którzy chcą wiedzieć, jak to wszystko działa. Na przykład trudno mi śledzić różne rzeczy, gdy nie wiem, dlaczego tak się dzieje.
Winger Sendon,

21

Powinieneś znać jeden poziom „głębiej” w systemie, nad którym pracujesz. Przeskakiwanie za daleko za jednym razem nie jest złe, ale może nie być tak pomocne, jak by się chciało.

Programista w języku wysokiego poziomu powinien nauczyć się języka niższego poziomu (C to doskonała opcja). Nie musisz iść do samego montażu, aby poznać to, co dzieje się pod przykryciem, gdy mówisz komputerowi, aby utworzył instancję obiektu, utworzył tablicę skrótów lub zestaw - ale powinieneś być w stanie kodować im.

Dla programisty Java, nauczenie się trochę C pomogłoby ci w zarządzaniu pamięcią, przekazywaniu argumentów. Napisanie części obszernej biblioteki Java w C pomogłoby zrozumieć, kiedy użyć jakiej implementacji Seta (chcesz skrótu? Lub drzewa?). Postępowanie z char * w środowisku wątkowym pomoże zrozumieć, dlaczego String jest niezmienny.

Przeniesiony na wyższy poziom ... Programista AC powinien znać się na montażu, a typy montażu (często spotykane w sklepach z systemami wbudowanymi) prawdopodobnie dobrze sobie radzą ze zrozumieniem rzeczy na poziomie bramek. Ci, którzy pracują z bramami, powinni znać fizykę kwantową. A ci fizycy kwantowi, cóż, wciąż próbują dowiedzieć się, jaka jest następna abstrakcja.


1
Jeden poziom głębiej jest w porządku. Zwykle wybieram parę, ale zakładanie, że znajomość asemblera x86 jest warta inwestycji w porównaniu do studiowania MSIL dla programisty C #, wymaga zbyt wiele. Jako ktoś, kto studiował fizykę montażu i ciała stałego w uni, nie sądzę, że znajomość fizyki projektowania bram pomogła mi w ogóle, oprócz ukończenia studiów w dziedzinie elektroniki.
Muhammad Alkarouri,

@MuhammadAlkarouri Myślałem o zrozumieniu upływu prądu, długości przebiegów, oporu i wpływu ciepła na system. Zrozumienie leżącego u podstaw „dlaczego” pomaga w podejmowaniu decyzji w większym stopniu niż zasady minimalnego oddzielania śladów i tolerancji operacyjnych.

5

Ponieważ nie wspomniałeś o C lub C ++ w językach, które znasz. Poleciłbym MOCNIE nauczenie się ich, zanim nawet pomyśli o montażu. C lub C ++ poda wszystkie podstawowe pojęcia, które są całkowicie przejrzyste w językach zarządzanych, a większość pojęć wymienionych na tej stronie zrozumiesz w jednym z najważniejszych języków, których możesz używać w projektach w świecie rzeczywistym. To prawdziwa wartość dodana do twoich umiejętności programowania. Należy pamiętać, że asembler jest używany w bardzo specyficznych obszarach i nie jest tak przydatny jak C lub C ++.

Chciałbym nawet powiedzieć, że nie powinieneś nurkować na zgromadzeniu, zanim zrozumiesz, jak działają języki niezarządzane. To prawie obowiązkowa lektura.

Powinieneś nauczyć się montażu, jeśli chcesz zejść jeszcze niżej. Chcesz wiedzieć, jak dokładnie tworzona jest każda konstrukcja języka. Ma charakter informacyjny, ale ma złożoność na zupełnie innym poziomie.


5

Jeśli znasz dobrze język, powinieneś mieć przynajmniej podstawową wiedzę na temat technologii o jeden poziom abstrakcji niższą.

Dlaczego? Gdy coś pójdzie nie tak, znajomość podstawowych mechanizmów znacznie ułatwia debugowanie dziwnych problemów i naturalnie pisanie bardziej wydajnego kodu

Używając Pythona (/ CPython) jako przykładu, jeśli zaczniesz mieć dziwne awarie lub niską wydajność, wiedza na temat debugowania kodu C może być bardzo przydatna, podobnie jak wiedza na temat jego metody zarządzania pamięcią. Pomoże to również wiedzieć, kiedy / czy napisać coś jako rozszerzenie C i tak dalej ...

Aby odpowiedzieć na twoje pytanie w tym przypadku, znajomość asemblera naprawdę nie pomogłaby doświadczonemu deweloperowi Pythona (to zbyt wiele kroków w dół od abstrakcji - cokolwiek zrobione w Pythonie skutkowałoby wieloma wieloma instrukcjami asemblacji)

.. ale jeśli masz doświadczenie z C, to znajomość „następnego poziomu w dół” (montaż) byłaby rzeczywiście przydatna.

Podobnie, jeśli używasz CoffeScript, to (bardzo) przydatna jest znajomość Javascript. Jeśli korzystasz z Clojure, przydatna jest znajomość Java / JVM.

Ten pomysł działa również poza językami programowania - jeśli używasz asemblera, dobrym pomysłem jest zapoznanie się z funkcjonowaniem podstawowego sprzętu. Jeśli jesteś projektantem stron internetowych, dobrze jest wiedzieć, jak jest wdrażana aplikacja internetowa. Jeśli jesteś mechanikiem samochodowym, dobrze jest mieć wiedzę na temat fizyki


3

Napisz mały program c i zdemontuj wyjście. To wszystko. Należy jednak być przygotowanym na większy lub mniejszy stopień kodu „sprzątania”, który zostanie dodany na korzyść systemu operacyjnego.

Montaż pomaga zrozumieć, co dzieje się pod maską, ponieważ dotyczy bezpośrednio pamięci, rejestrów procesorów i tym podobnych.

Jeśli naprawdę chcesz przejść od zera, bez komplikacji systemu operacyjnego komplikujących rzeczy, spróbuj zaprogramować Arduino w języku asemblera.


3

Nie ma ostatecznej odpowiedzi, ponieważ programiści nie są tego samego typu. Czy musisz wiedzieć, co czai się pod spodem? Jeśli tak, naucz się tego. chcesz po prostu nauczyć się tego z ciekawości? Jeśli tak, naucz się tego. Jeśli nie przyniesie ci to praktycznych korzyści, po co się tym przejmować? Czy do prowadzenia samochodu potrzebny jest poziom wiedzy mechanika? Czy mechanik potrzebuje wiedzy inżyniera, aby pracować tylko w samochodzie? To poważna analogia. Mechanik może być bardzo dobrym, produktywnym mechanikiem bez nurkowania, aby uzyskać głęboką wiedzę o pojazdach, które utrzymuje. To samo dotyczy muzyki. Czy naprawdę chcesz pogłębić złożoność melodii, harmonii i rytmu, aby być dobrym piosenkarzem lub graczem? Nie. Niektórzy wyjątkowo utalentowani muzycy nie potrafią czytać partytury, nie mówiąc już o różnicy między trybami Doriana i Lidiana. Jeśli chcesz, w porządku, ale nie, nie musisz. Jeśli jesteś programistą, montaż nie ma praktycznego zastosowania, o którym mogę myśleć. Jeśli jesteś w systemach wbudowanych lub czymś naprawdę specjalnym, może to być konieczne, ale gdyby tak było, wiedziałbyś o tym.

Oto, jak Joel przyjmuje wartość uczenia się języka wyższego poziomu: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html


2

Właściwie to, co prawdopodobnie byłoby dla ciebie najlepsze, byłaby klasa, która (o ile wiem) nigdzie nie istnieje: byłaby to klasa, która łączy krótki przegląd języka maszyn / asemblerów i koncepcji adresowania pamięci z przewodnikiem po budowie kompilatora , generowanie kodu i środowiska wykonawcze.

Problem polega na tym, że w języku wysokiego poziomu, z dala od sprzętu, takim jak C # lub Python, tak naprawdę nie doceniasz faktu, że każdy wykonywany ruch zamienia się w setki, jeśli nie tysiące instrukcji maszynowych, i nie mają tendencję do zrozumienia, w jaki sposób kilka wierszy języka wysokiego poziomu może powodować dostęp i modyfikację ogromnej ilości pamięci. Nie chodzi o to, że musisz dokładnie wiedzieć, co się dzieje „pod przykrywkami”, ale musisz docenić zakres tego, co się dzieje, i ogólną koncepcję rodzajów rzeczy, które się zdarzają.


1

Moja odpowiedź na to pytanie ewoluowała stosunkowo niedawno. Istniejące odpowiedzi obejmują to, co powiedziałbym w przeszłości. W rzeczywistości jest to nadal objęte najważniejszą odpowiedzią - punkt „doceniaj konstrukty w programowaniu wyższego poziomu”, ale myślę, że jest to szczególny przypadek, o którym warto wspomnieć ...

Według tego posta na blogu Jeffa Atwooda , który odnosi się do badania, zrozumienie przypisania jest kluczową kwestią w zrozumieniu programowania. Programiści uczący się albo rozumieją, że notacja po prostu reprezentuje kroki, które podąża komputer, i uzasadniają te kroki, albo stają się wiecznie zdezorientowani przez wprowadzające w błąd analogie do równań matematycznych itp.

Cóż, jeśli rozumiesz następujące elementy z asemblera 6502 ...

LDA variable
CLC
ADC #1
STA variable

To naprawdę tylko kroki. Kiedy nauczysz się tłumaczyć to na instrukcję przypisania ...

variable = variable + 1;

Nie potrzebujesz wprowadzającej w błąd analogii do równania matematycznego - masz już prawidłowy model mentalny, aby go odwzorować.

EDYCJA - oczywiście jeśli wyjaśnienie, które otrzymujesz, LDA variablejest w gruncie rzeczy ACCUMULATOR = variable, dokładnie to, co otrzymujesz z niektórych samouczków i odniesień, kończysz tam, gdzie zacząłeś i wcale nie jest to pomocne.

Nauczyłem się asemblera 6502 jako mojego drugiego języka, z których pierwszym był Commodore Basic, i tak naprawdę niewiele się wtedy nauczyłem - częściowo dlatego, że tak mało było do nauczenia, ale także dlatego, że asembler wydawał się wtedy o wiele bardziej interesujący . Częściowo razy, częściowo dlatego, że miałem 14 lat geek.

Nie polecam robić tego, co zrobiłem, ale zastanawiam się, czy przestudiowanie kilku bardzo prostych przykładów w bardzo prostym języku asemblera może być wartościowym wstępem do nauki języków wyższego poziomu.


0

O ile nie jesteś pisarzem kompilatora lub nie potrzebujesz czegoś wysoce zoptymalizowanego (takiego jak algorytm przetwarzania danych), nauka kodowania asemblera nie zapewni żadnych korzyści.

Pisanie i obsługa kodu napisanego w asemblerze jest bardzo trudna, dlatego nawet jeśli znasz język asemblera bardzo dobrze, nie powinieneś go używać, chyba że istnieją inne sposoby.

Artykuł „ Optymalizacja pod kątem SSE: studium przypadku ” pokazuje, co można zrobić, jeśli pójdziesz na montaż. Autorowi udało się zoptymalizować algorytm ze 100 cykli / wektor do 17 cykli / wektor.


1
Autor nie użył żadnych instrukcji wektorowych ani wewnętrznych w wersji C ++. Nie potrzebujesz asemblera do pisania kodu SSE.
gnasher729

@ gnasher729 Tak, nie potrzebujesz. Ale w przypadku montażu program może działać znacznie szybciej. W końcu człowiek może być mądrzejszy niż kompilator (w rzadkich przypadkach).
BЈовић

0

Pisanie w asemblerze nie dałoby magicznego wzrostu prędkości, ponieważ z powodu ilości szczegółów (alokacja rejestru itp.) Prawdopodobnie napiszesz najbardziej trywialny algorytm, jaki kiedykolwiek powstał.

Dodatkowo dzięki nowoczesnym (czytanym - zaprojektowanym po 70-80) procesorom montaż nie zapewni wystarczającej liczby szczegółów, aby wiedzieć, co się dzieje (to znaczy - na większości procesorów). Nowoczesne PU (CPU i GPU) są dość złożone, jeśli chodzi o instrukcje planowania. Znajomość podstaw montażu (lub pseudo-montażu) pozwoli zrozumieć książki / kursy architektury komputerowej, które dostarczyłyby dalszej wiedzy (pamięci podręczne, wykonywanie poza kolejnością, MMU itp.). Zwykle nie trzeba znać złożonego ISA, aby je zrozumieć (MIPS 5 jest dość popularnym IIRC).

Po co rozumieć procesor? Może dać ci znacznie więcej zrozumienia, co się dzieje. Powiedzmy, że piszesz mnożenie macierzy w naiwny sposób:

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Może być „wystarczająco dobry” dla twojego celu (jeśli jest to macierz 4x4, i tak może być skompilowana do instrukcji wektorowych). Istnieją jednak dość ważne programy podczas kompilacji ogromnych tablic - jak je zoptymalizować? Jeśli napiszesz kod w asemblerze, możesz mieć kilka procent ulepszeń (chyba że zrobiłbyś to tak, jak robi większość ludzi - także w naiwny sposób, wykorzystując niewykorzystane rejestry, stale ładując / przechowując w pamięci i w efekcie mając wolniejszy program niż w języku HL) .

Jednak możesz odwrócić linie i magicznie zyskać wydajność (dlaczego? Zostawiam to jako „pracę domową”) - IIRC w zależności od różnych czynników dla dużych matryc może być nawet 10x.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

To powiedziawszy - pracują nad tym, aby kompilatory były w stanie to zrobić ( grafit dla gcc i Polly dla czegokolwiek używającego LLVM). Są nawet w stanie je przekształcić (przepraszam - piszę blokowanie z pamięci):

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

Podsumowując - znajomość podstaw złożenia pozwala na zagłębienie się w różne „szczegóły” z projektu procesora, które pozwoliłyby pisać szybsze programy. Warto znać różnice między architekturami RISC / CISC lub VLIW / vector Processor / SIMD / ... Nie chciałbym jednak zaczynać od x86, ponieważ są one dość skomplikowane (być może również ARM) - wiedza na temat rejestru itp. Jest wystarczająca do uruchomienia IMHO.


Interesujące jest to, że podałeś kilka próbek kodu, ale żaden z nich nie jest w języku asemblera.
Robert Harvey

-1

Zwykle jest to BARDZO ważne dla celów debugowania. Co robisz, gdy system pęka w środku instrukcji i błąd nie ma sensu? Z językami .NET nie ma większego problemu, o ile używasz tylko bezpiecznego kodu - system prawie zawsze ochroni cię przed tym, co dzieje się pod maską.


-2

Krótko mówiąc, myślę, że odpowiedź brzmi, ponieważ możesz zrobić więcej, jeśli nauczysz się montażu. Nauka montażu zapewnia dostęp do dziedzin programowania urządzeń wbudowanych, penetracji i obchodzenia zabezpieczeń, inżynierii wstecznej i programowania systemu, w których bardzo trudno jest pracować, jeśli nie znasz asemblera.

Jeśli chodzi o naukę poprawiania wydajności programu, jest to wątpliwe w programowaniu aplikacji. Przez większość czasu jest tak wiele rzeczy, na których należy się skupić, zanim osiągniesz ten poziom optymalizacji, takich jak optymalizacja dostępu do we / wy zarówno na dysku, jak i w sieci, optymalizacja sposobu tworzenia GUI, wybór odpowiednich algorytmów, maksymalizacja wszystkich rdzeni , działając na najlepszym sprzęcie, jaki można kupić za pieniądze i przechodząc z tłumaczonych na skompilowane języki. O ile nie tworzysz oprogramowania dla innych użytkowników końcowych, sprzęt jest tani w porównaniu do stawki godzinowej programisty, szczególnie w przypadku dostępności w chmurze.

Ponadto musisz rozważyć zwiększenie szybkości wykonywania programu z czytelnością kodu po tym, jak zostaniesz potrącony przez magistralę, wyjdziesz lub wrócisz do bazy kodu, aby zmienić go rok po napisaniu ostatniej wersji.


-3

Poleciłbym uczenie się algorytmów: sortowania, powiązanych list, drzew binarnych, mieszania itp.

Naucz się także lisp, patrz Struktura i interpretacja programów komputerowych. kilka prymitywnych poleceń, jedno prymitywne seplenienie i niektóre prowokujące asemblery).

Na koniec, jeśli musisz nauczyć się asemblera, naucz się łatwego, takiego jak ARM (również jest on używany w około 4 razy większej liczbie urządzeń niż x86).


-8

Odpowiedź brzmi: po prostu dlatego, że używany język musi zostać zinterpretowany lub skompilowany na końcu w asemblerze. Bez względu na język lub maszynę.

Konstrukcja języków wywodzi się ze sposobu działania procesora. Więcej o programach niskiego poziomu, mniej o programach wysokiego poziomu.

Zakończę stwierdzeniem, że nie tylko musisz znać mały asembler, ale także architekturę procesora, której uczysz się poprzez naukę asemblera.

Kilka przykładów: Istnieje wielu programistów Java, którzy nie rozumieją, dlaczego to nie działa, a nawet mniej niż wiedzą, co się dzieje po uruchomieniu.

String a = "X";
String b = "X";
if(a==b)  
    return true;

Gdybyś znał małego asemblera, zawsze wiedziałbyś, że nie jest to ta sama zawartość lokalizacji w pamięci, co liczba w zmiennej wskaźnika, która „wskazuje” na tę lokalizację.

Co gorsza, nawet w opublikowanych książkach przeczytasz coś takiego jak w prymitywach JAVA przekazywanych przez wartość, a obiekty przez odniesienie, co jest całkowicie niepoprawne. Wszystkie argumenty w Javie są przekazywane przez wartość, a Java NIE może przekazywać obiektów do funkcji, tylko wskaźniki, które są przekazywane przez wartość.

Jeśli teraz zgromadzisz, to oczywiste, co się dzieje, jeśli nie, wyjaśnienie tego jest tak skomplikowane, że większość autorów po prostu kłamie.

Oczywiście ich konsekwencje są subtelne, ale mogą później sprawić ci poważne kłopoty. Jeśli wiesz, że asembler to nie problem, jeśli nie, czeka cię długa noc debugowania.


5
Twój pierwszy akapit jest całkowicie niepoprawny: języki nie są kompilowane w ASM, są kompilowane w Kod Maszynowy. Tłumacze nie kompilują się również w ASM, interpretują kod lub kod bajtowy oraz wywołują funkcje lub metody na wstępnie skompilowanym kodzie maszynowym.

6
Każda rzecz, którą twierdzisz o Javie, jest również niepoprawna. Zaczynając od tego, String a = "X"; String b = "X"; if( a==b) return true;co robi w rzeczywistości z == truepowodu czegoś, co nazywa String interningsię kompilatorem. Wszystkie pozostałe instrukcje Java są również błędne. Java nie ma wskaźników, ma odwołania, które nie są tym samym. I nic z tego nie ma nic wspólnego z asemblerem w żaden sposób. Java przekazuje prymitywy według wartości, a także referencje według wartości. Java nie ma wskaźników, więc nie może ich pominąć. Znowu wszystko nie ma znaczenia dla znajomości ASM.

Zawsze myślałem, że języki wyższego poziomu są wkompilowane w obiekt (kod maszynowy) lub pseudo-kod, a nie w ASM.
Frank R.

@FrankComputer jest poprawny, ale kod maszyny bajtuje w zasadzie mapę 1: 1 do instrukcji asemblera, dzięki czemu można łatwo tłumaczyć między obiektem kodu a ASM (dekompilacją lub
asemblacją

2
@FrankComputer ostatni raz szukałem gcc skompilowanego C / C ++ / fortran / java / ada / etc do wewnętrznego kodu bajtów i wewnętrznego kodu bajtów do asemblera. Następnie wysyła ten kod asemblera do asemblera, aby przekonwertować go na kod maszynowy.
ctrl-alt-delor
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.