Mam pytanie do wszystkich zagorzałych hakerów niskiego poziomu. Natknąłem się na to zdanie na blogu. Nie sądzę, żeby źródło miało znaczenie (jeśli naprawdę cię to obchodzi, to Haack), ponieważ wydaje się, że jest to powszechne stwierdzenie.
Na przykład wiele współczesnych gier trójwymiarowych ma swój silnik rdzeniowy o wysokiej wydajności napisany w C ++ i asemblerze.
Jeśli chodzi o asemblację - czy kod jest napisany w asemblerze, ponieważ nie chcesz, aby kompilator emitował dodatkowe instrukcje lub używał nadmiernych bajtów, lub czy używasz lepszych algorytmów, których nie możesz wyrazić w C (lub nie możesz wyrazić bez kompilator zastanawia się nad nimi)?
Całkowicie rozumiem, że ważne jest zrozumienie rzeczy niskiego poziomu. Chcę tylko zrozumieć, dlaczego program w asemblerze to zrozumiesz.
źródło
Odpowiedzi:
Myślę, że źle czytasz to stwierdzenie:
Gry (i większość programów w dzisiejszych czasach) nie są „napisane w asemblerze” w ten sam sposób, w jaki są „napisane w C ++”. Ten blog nie mówi, że znaczna część gry jest projektowana w asemblerze lub że zespół programistów siedzi i rozwija się w asemblerze jako podstawowym języku.
To naprawdę oznacza, że programiści najpierw piszą grę i uruchamiają ją w C ++. Następnie profilują to, ustalają, jakie są wąskie gardła i jeśli to jest warte zachodu, optymalizują je w montażu. Lub, jeśli mają już doświadczenie, wiedzą, które części będą wąskimi gardłami, i mają zoptymalizowane elementy z innych gier, które stworzyli.
Punkt programowania w montażu jest taka sama jak zawsze była: prędkość . Byłoby absurdem pisać dużo kodu w asemblerze, ale są pewne optymalizacje, których kompilator nie jest świadomy, a dla wystarczająco małego okna kodu człowiek poradzi sobie lepiej.
Na przykład kompilatory zmiennoprzecinkowe wydają się być dość konserwatywne i mogą nie być świadome niektórych bardziej zaawansowanych funkcji Twojej architektury. Jeśli jesteś skłonny zaakceptować jakiś błąd, zwykle możesz zrobić lepiej niż kompilator i warto napisać ten mały fragment kodu w asemblerze, jeśli okaże się, że poświęca się na to dużo czasu.
Oto kilka bardziej odpowiednich przykładów:
Przykłady z gier
Artykuł Intela na temat optymalizacji silnika gry przy użyciu elementów wbudowanych SSE. Ostateczny kod używa elementów wewnętrznych (nie wbudowanego asemblera), więc ilość czystego asemblacji jest bardzo mała. Ale patrzą na wyjście asemblera przez kompilator, aby dowiedzieć się, co dokładnie zoptymalizować.
Szybka odwrotność pierwiastka kwadratowego Quake'a . Ponownie, procedura nie zawiera asemblera, ale musisz wiedzieć coś o architekturze, aby wykonać tego rodzaju optymalizację. Autorzy wiedzą, które operacje są szybkie (mnożenie, przesuwanie), a które wolne (dzielenie, sqrt). Dlatego wymyślają bardzo skomplikowaną implementację pierwiastka kwadratowego, która pozwala całkowicie uniknąć powolnych operacji.
Obliczenia o wysokiej wydajności
Poza domeną gier ludzie zajmujący się komputerami naukowymi często optymalizują bzdury, aby szybko działały na najnowszym sprzęcie. Pomyśl o tym jak o grach, w których nie możesz oszukiwać w fizyce.
Świetnym, niedawnym przykładem tego jest kratowa chromodynamika kwantowa (krata QCD) . Dokument ten opisuje, w jaki sposób problem praktycznie sprowadza się do jednej bardzo małej obliczeniowej jądra, które zostało zoptymalizowane dla PowerPC 440 ciężko jest na z IBM Blue Gene / L . Każdy 440 ma dwa FPU i obsługują one specjalne operacje trójskładnikowe, które są trudne do wykorzystania przez kompilatory. Bez tych optymalizacji Lattice QCD działałby znacznie wolniej, co jest kosztowne, gdy problem wymaga milionów godzin pracy procesora na drogich maszynach.
Jeśli zastanawiasz się, dlaczego jest to ważne, przeczytaj artykuł w Science, który powstał w wyniku tej pracy. Używając Lattice QCD, ci faceci obliczyli masę protonu na podstawie pierwszych zasad i wykazali w zeszłym roku, że 90% masy pochodzi z energii wiązania siły silnej, a reszta z kwarków. To jest E = mc 2 w akcji. Oto podsumowanie .
W przypadku wszystkich powyższych, aplikacje nie są projektowane ani pisane w 100% w montażu - nawet nie są bliskie. Ale kiedy ludzie naprawdę potrzebują szybkości, skupiają się na pisaniu kluczowych części swojego kodu, aby latać na określonym sprzęcie.
źródło
Od wielu lat nie kodowałem w asemblerze, ale mogę podać kilka powodów, które często widziałem:
Nie wszystkie kompilatory mogą korzystać z pewnych optymalizacji procesora i zestawu instrukcji (np. Nowych zestawów instrukcji, które Intel dodaje od czasu do czasu). Czekanie, aż autorzy kompilatorów nadrobią zaległości, oznacza utratę przewagi konkurencyjnej.
Łatwiejsze dopasowanie rzeczywistego kodu do znanej architektury procesora i optymalizacji. Na przykład rzeczy, które wiesz o mechanizmie pobierania, buforowaniu itp. Ma to być przezroczyste dla programisty, ale faktem jest, że tak nie jest, dlatego twórcy kompilatorów mogą optymalizować.
Pewne dostępy na poziomie sprzętu są możliwe / praktyczne tylko poprzez język asemblera (np. Podczas pisania sterownika urządzenia).
Formalne rozumowanie jest czasem łatwiejsze w asemblerze niż w języku wysokiego poziomu, ponieważ wiesz już, jaki jest ostateczny lub prawie ostateczny układ kodu.
Programowanie niektórych kart graficznych 3D (około późnych lat 90. XX wieku) przy braku API było często bardziej praktyczne i wydajne w języku asemblerowym, a czasami nie było możliwe w innych językach. Ale znowu, dotyczyło to gier na poziomie eksperckim opartych na architekturze akceleratora, takich jak ręczne przenoszenie i usuwanie danych w określonej kolejności.
Wątpię, aby wiele osób użyło asemblera, gdy zrobiłby to język wyższego poziomu, zwłaszcza gdy tym językiem jest C. Ręczna optymalizacja dużych ilości kodu ogólnego przeznaczenia jest niepraktyczna.
źródło
Jest jeden aspekt programowania w asemblerze, o którym inni nie wspominali - poczucie satysfakcji, które odczuwasz, wiedząc, że każdy bajt w aplikacji jest wynikiem twojego własnego wysiłku, a nie kompilatora. Nie chciałbym nawet przez sekundę wracać do pisania całych aplikacji w asemblerze, jak to robiłem na początku lat 80., ale czasami tęsknię za tym uczuciem ...
źródło
Zwykle asemblacja laika jest wolniejsza niż C (ze względu na optymalizację C), ale wiele gier ( doskonale pamiętam Doom ) musiało mieć określone sekcje gry w asemblerze, aby działała płynnie na normalnych maszynach.
Oto przykład, do którego się odwołuję.
źródło
Programowanie w języku asemblerowym zacząłem w mojej pierwszej pracy (lata 80-te). W przypadku systemów wbudowanych wymagania dotyczące pamięci - RAM i EPROM - były niskie. Możesz napisać zwarty kod, który byłby łatwy w użyciu zasobów.
Pod koniec lat 80-tych przerzuciłem się na C. Kod był łatwiejszy do pisania, debugowania i utrzymania. Bardzo małe fragmenty kodu zostały napisane w asemblerze - dla mnie było to, gdy pisałem przełączanie kontekstu w systemie RTOS typu roll-your-own. (Coś, czego nie powinieneś już robić, chyba że jest to „projekt naukowy”).
W kodzie jądra Linuksa zobaczysz fragmenty kodu asemblera. Ostatnio przeglądałem go w spinlockach i innym kodzie synchronizacyjnym. Te fragmenty kodu muszą uzyskać dostęp do atomowych operacji testowania i ustawiania, manipulowania pamięciami podręcznymi itp.
Myślę, że byłoby trudno zoptymalizować nowoczesne kompilatory C dla większości programów.
Zgadzam się z @altCognito, że prawdopodobnie lepiej spędzić czas na dokładniejszym myśleniu o problemie i lepszym wykonywaniu zadań. Z jakiegoś powodu programiści często koncentrują się na mikroefektywnościach i zaniedbują makroefektywności. Asembler poprawiający wydajność to mikroefektywność. Cofnięcie się do szerszego widoku systemu może ujawnić problemy z makrami w systemie. Rozwiązanie problemów makro często może przynieść lepszy wzrost wydajności. Gdy problemy makro zostaną rozwiązane, zejdź do poziomu mikro.
Wydaje mi się, że mikro problemy są pod kontrolą jednego programisty iw mniejszej domenie. Zmiana zachowania na poziomie makro wymaga komunikacji z większą liczbą osób - czego niektórzy programiści unikają. Cały ten kowboj kontra drużyna.
źródło
"Tak". Ale zrozum, że w większości przypadków korzyści płynące z pisania kodu w asemblerze nie są warte wysiłku. Zwrot uzyskany za napisanie tego w trakcie montażu jest zwykle mniejszy niż zwykłe skupienie się na dokładniejszym myśleniu o problemie i spędzaniu czasu na myśleniu o lepszym sposobie wykonywania zadań.
John Carmack i Michael Abrash, którzy byli w dużej mierze odpowiedzialni za napisanie Quake'a i cały kod o wysokiej wydajności, który znalazł się w silnikach gier ID, opisują szczegółowo tę książkę w tej książce .
Zgodziłbym się również z Ólafurem Waage'em, że dziś kompilatory są dość sprytne i często wykorzystują wiele technik, które wykorzystują ukryte ulepszenia architektoniczne.
źródło
W dzisiejszych czasach, przynajmniej w przypadku kodów sekwencyjnych, przyzwoity kompilator prawie zawsze pokonuje nawet bardzo doświadczonego programistę asemblerowego. Ale w przypadku kodów wektorowych to inna historia. Na przykład szeroko rozpowszechnione kompilatory nie wykonują tak świetnej pracy, wykorzystując możliwości równoległości wektorów jednostki x86 SSE. Jestem autorem kompilatorów, a wykorzystanie SSE znajduje się na szczycie mojej listy powodów, dla których warto iść na własną rękę, zamiast ufać kompilatorowi.
źródło
Kod SSE działa lepiej w asemblerze niż elementy wewnętrzne kompilatora, przynajmniej w MSVC. (tj. nie tworzy dodatkowych kopii danych)
źródło
Mam trzy lub cztery procedury asemblera (w źródle około 20 MB) w moich źródłach w pracy. Wszystkie z nich są SSE (2) i są związane z operacjami na (dość dużych - pomyśl o 2400x2048 i większych) obrazach.
Hobby pracuję nad kompilatorem i tam masz więcej asemblera. Biblioteki środowiska wykonawczego są dość często pełne, większość z nich ma do czynienia z rzeczami, które są sprzeczne z normalnym reżimem proceduralnym (jak pomocnicy wyjątków itp.)
Nie mam żadnego asemblera do mojego mikrokontrolera. Większość współczesnych mikrokontrolerów ma tak wiele urządzeń peryferyjnych (liczniki sterowane przerwaniami, nawet całe kwadraturowe enkodery i szeregowe bloki konstrukcyjne), że używanie asemblera do optymalizacji pętli często nie jest już potrzebne. Przy obecnych cenach flash to samo dotyczy pamięci kodów. Istnieje również wiele różnych urządzeń zgodnych ze stykami, więc skalowanie w górę, jeśli systematycznie kończy się moc procesora lub przestrzeń flash, często nie stanowi problemu
Chyba że naprawdę wysyłasz 100000 urządzeń, a asembler programowania umożliwia naprawdę duże oszczędności, po prostu umieszczając chip flash o kategorii mniejszej. Ale ja nie jestem w tej kategorii.
Wiele osób uważa, że systemy wbudowane są usprawiedliwieniem dla asemblera, ale ich kontrolery mają większą moc procesora niż maszyny, na których opracowano system Unix . (Microchip dostarczany z mikrokontrolerami 40 i 60 MIPS za mniej niż 10 USD ).
Jednak wiele osób utknęło w spuściźnie, ponieważ zmiana architektury mikroczipa nie jest łatwa. Również kod HLL jest bardzo zależny od architektury (ponieważ wykorzystuje peryferia sprzętowe, rejestry do sterowania I / O itp.). Czasami są więc dobre powody, aby nadal utrzymywać projekt w asemblerze (miałem szczęście, że mogłem skonfigurować sprawy na nowej architekturze od zera). Ale często ludzie oszukują samych siebie, że naprawdę potrzebują asemblera.
Nadal podoba mi się odpowiedź, jakiej udzielił profesor, gdy zapytaliśmy, czy możemy użyć GOTO (ale możesz to przeczytać również jako MONTAŻ): „jeśli uważasz, że warto napisać 3-stronicowy esej o tym, dlaczego potrzebujesz tej funkcji, możesz jej użyć . Prześlij esej z wynikami ”.
Użyłem tego jako przewodniej zasady dla funkcji niskiego poziomu. Nie bądź zbyt ciasny, aby go używać, ale upewnij się, że odpowiednio go motywujesz. Podnieś nawet sztuczną barierę lub dwie (jak w eseju), aby uniknąć zawiłego rozumowania jako uzasadnienia.
źródło
Niektórych instrukcji / flag / kontrolek po prostu nie ma na poziomie C.
Na przykład sprawdzanie przepełnienia na x86 jest prostą flagą przepełnienia. Ta opcja nie jest dostępna w C.
źródło
Defekty pojawiają się zazwyczaj w każdym wierszu (instrukcja, punkt kodowy itp.); Chociaż prawdą jest, że w przypadku większości problemów asembler używałby znacznie więcej linii niż języki wyższego poziomu, czasami zdarzają się przypadki, w których najlepiej (najbardziej zwięzłe, najmniej wierszy) jest odwzorowanie danego problemu. Większość z tych przypadków dotyczy zwykłych podejrzanych, takich jak sterowniki i bicie bitów w systemach wbudowanych.
źródło
Innym powodem może być sytuacja, w której dostępny kompilator nie jest wystarczająco dobry dla danej architektury, a ilość kodu potrzebnego w programie nie jest tak długa ani skomplikowana, aby programista mógł się w nim zgubić. Spróbuj zaprogramować mikrokontroler dla systemu wbudowanego, zwykle montaż będzie znacznie łatwiejszy.
źródło
Oprócz innych wymienionych rzeczy, wszystkie wyższe języki mają pewne ograniczenia. Dlatego niektórzy decydują się na programowanie w ASM, aby mieć pełną kontrolę nad swoim kodem.
Inni cieszą się bardzo małymi plikami wykonywalnymi, w zakresie 20-60KB, na przykład sprawdź HiEditor , który jest zaimplementowany przez autora kontrolki HiEdit, znakomitą, potężną kontrolę edycji dla Windows z podświetlaniem składni i zakładkami tylko ~ 50kb). W swojej kolekcji mam ponad 20 takich złotych kontrolek, od Excell jak ssheets po rendery html.
źródło
Myślę, że wielu twórców gier byłoby zaskoczonych tą odrobiną informacji.
Większość znanych mi gier używa możliwie najmniej asemblacji. W niektórych przypadkach w ogóle, aw najgorszym przypadku jedna lub dwie pętle lub funkcje.
Ten cytat jest zbyt uogólniony i nie jest tak prawdziwy, jak dziesięć lat temu.
Ale hej, same fakty nie powinny przeszkadzać prawdziwej krucjacie hakera na rzecz zgromadzeń. ;)
źródło
Jeśli programujesz low-endowy 8-bitowy mikrokontroler ze 128 bajtami pamięci RAM i 4K pamięci programu, nie masz dużego wyboru, jeśli chodzi o użycie asemblera. Czasami jednak, gdy używasz mocniejszego mikrokontrolera, potrzebujesz określonej akcji, która ma zostać wykonana w określonym czasie. Przydaje się wtedy język asemblera, ponieważ możesz liczyć instrukcje i mierzyć cykle zegara używane przez kod.
źródło
Gdybyś był w pobliżu wszystkich wysiłków naprawczych Y2K, mógłbyś zarobić dużo pieniędzy, gdybyś znał Assembly. Wciąż istnieje wiele starszego kodu, który został w nim napisany, a ten kod czasami wymaga konserwacji.
źródło
Poza bardzo małymi projektami na bardzo małych procesorach, nie zamierzałbym kiedykolwiek programować całego projektu w asemblerze. Jednak często zdarza się, że wąskie gardło wydajności można złagodzić dzięki strategicznemu kodowaniu ręcznemu niektórych wewnętrznych pętli.
W niektórych przypadkach wszystko, co jest naprawdę potrzebne, to zastąpić jakąś konstrukcję językową instrukcją, której nie można oczekiwać od optymalizatora, aby dowiedzieć się, jak go użyć. Typowym przykładem są aplikacje DSP, w których operacje wektorowe i operacje wielokrotnej akumulacji są trudne do wykrycia dla optymalizatora, ale kod jest łatwy w obsłudze.
Na przykład niektóre modele SH4 zawierają macierz 4x4 i 4 instrukcje wektorowe. Widziałem ogromną poprawę wydajności algorytmu korekcji kolorów poprzez zastąpienie równoważnych operacji C na macierzy 3x3 odpowiednimi instrukcjami, niewielkim kosztem powiększenia macierzy korekcji do 4x4, aby dopasować się do założenia sprzętowego. Osiągnięto to, pisząc nie więcej niż tuzin linii montażowych i przenosząc dopasowania dopasowanych do powiązanych typów danych i pamięci w kilku miejscach w otaczającym kodzie C.
źródło
Wydaje się, że nie ma o tym wzmianki, więc pomyślałem, że dodam to: w tworzeniu nowoczesnych gier myślę, że przynajmniej część tworzonego zestawu w ogóle nie jest przeznaczona dla procesora. To jest dla GPU w postaci programów shaderowych .
Może to być potrzebne z różnych powodów, czasami po prostu dlatego, że jakikolwiek używany język cieniowania wyższego poziomu nie pozwala na wyrażenie dokładnej operacji w dokładnej liczbie żądanych instrukcji, w celu dopasowania do pewnego ograniczenia rozmiaru, szybkości lub dowolnej kombinacji . Wydaje mi się, że tak jak zwykle w przypadku programowania w języku asemblerowym.
źródło
Prawie każdy średni i duży silnik lub biblioteka gier, które widziałem do tej pory, ma kilka ręcznie zoptymalizowanych wersji montażu dostępnych dla operacji na macierzach, takich jak łączenie macierzy 4x4. Wydaje się, że kompilatory nieuchronnie pomijają niektóre sprytne optymalizacje (ponowne wykorzystanie rejestrów, rozwijanie pętli w maksymalnie efektywny sposób, wykorzystanie instrukcji specyficznych dla maszyny itp.) Podczas pracy z dużymi macierzami. Te funkcje manipulacji macierzą są prawie zawsze „aktywnymi punktami” w profilu.
Widziałem również ręcznie kodowany zestaw używany często do niestandardowej wysyłki - rzeczy takie jak FastDelegate, ale specyficzne dla kompilatora i maszyny.
Wreszcie, jeśli masz procedury obsługi przerwań, asm może zrobić wielką różnicę na świecie - są pewne operacje, których po prostu nie chcesz, aby były wykonywane w trakcie przerwania, i chcesz, aby programy obsługi przerwań „wchodziły i wychodziły szybko”. .. prawie dokładnie wiesz , co się stanie w twoim ISR, jeśli jest w asm, i zachęca cię to do skracania cholernych rzeczy (co i tak jest dobrą praktyką).
źródło
Gry są dość wymagające wydajności i chociaż w międzyczasie optymalizatory są całkiem niezłe, „główny programista” wciąż jest w stanie wycisnąć trochę więcej wydajności, ręcznie kodując odpowiednie części podczas montażu.
Nigdy, przenigdy nie rozpoczynaj optymalizacji programu bez uprzedniego jego sprofilowania. Po profilowaniu powinieneś być w stanie zidentyfikować wąskie gardła, a jeśli znalezienie lepszych algorytmów i tym podobnych, już ich nie usunie, możesz spróbować ręcznie zakodować coś w asemblerze.
źródło
Osobiście rozmawiałem tylko z jednym deweloperem o jego zastosowaniu w montażu. Pracował nad oprogramowaniem, które zajmowało się sterowaniem przenośnego odtwarzacza mp3. Wykonywanie prac montażowych miało 2 cele:
źródło
Jedyne kodowanie asemblera, które nadal robię, dotyczy wbudowanego sprzętu z niewielkimi zasobami. Jak wspomina Leander, assembler nadal dobrze pasuje do ISR gdzie kod musi być szybki i dobrze zrozumiany.
Drugim powodem jest dla mnie utrzymanie mojej wiedzy na temat montażu. Możliwość zbadania i zrozumienia kroków, które podejmuje procesor, aby wykonać moje rozkazy, jest po prostu przyjemna.
źródło
Ostatni raz, kiedy pisałem w asemblerze, nie mogłem przekonać kompilatora do generowania wolnego od libc, niezależnego od pozycji kodu.
Następnym razem prawdopodobnie będzie z tego samego powodu.
Oczywiście miałem inne powody .
źródło
Wiele osób uwielbia oczerniać język asemblera, ponieważ nigdy nie nauczyli się go kodować i napotkali go tylko niejasno, a to wprawiło ich w przerażenie lub nieco onieśmielenie. Prawdziwie utalentowani programiści zrozumieją, że walenie w C lub Assembly jest bezsensowne, ponieważ są komplementarne. w rzeczywistości zaletą jednego jest wada drugiego. Zorganizowane reguły składniowe języka C poprawiają klarowność, ale jednocześnie rezygnują z wszelkich reguł strukturalnych, jakie zgromadzenie mocy ma! Instrukcje kodu C mają na celu utworzenie kodu nieblokującego, który można argumentować, wymusza przejrzystość intencji programowania, ale jest to utrata mocy. W C kompilator nie pozwoli na skok do wnętrza if / elseif / else / end. Lub nie możesz napisać dwóch pętli for / end na różnych zmiennych, które nakładają się na siebie, nie możesz pisać samomodyfikującego się kodu (lub nie możesz w łatwy sposób) itp. konwencjonalni programiści są wystraszeni powyższym i nie mieliby pojęcia, jak wykorzystać moc tych podejść, ponieważ zostały one wychowane zgodnie z konwencjonalnymi zasadami . Oto prawda: dziś mamy maszynę o mocy obliczeniowej, która może zrobić znacznie więcej niż aplikacja, do której ich używamy, ale ludzki mózg jest zbyt niezdolny do kodowania ich w środowisku kodowania wolnym od reguł (= montaż) i potrzebuje restrykcyjnych reguł, które bardzo zmniejszyć widmo i upraszcza kodowanie. Sam napisałem kod, którego nie da się napisać w języku C, nie stając się nieefektywnym ze względu na wspomniane powyżej ograniczenia. I jeszcze nie mówiłem o szybkości, która według większości ludzi jest głównym powodem pisania na montażu, cóż, jeśli umysł jest ograniczony do myślenia w języku C, to na zawsze jesteś niewolnikiem swojego kompilatora. Zawsze myślałem, że mistrzowie szachistów będą idealnymi programistami asemblerowymi, podczas gdy programiści C po prostu grają w „Damy”.
źródło
goto
pozwala jednak na nieustrukturyzowane skoki w funkcji. Włączanie do bloku wewnątrzif()
pętli lub w tej samej funkcji. np . godbolt.org/z/IINHTg . Zobacz także Urządzenie Duffa, w którym używa się przełącznika / obudowy dodo{}while()
pętli, aby wyrazić skok do rozwiniętej pętli. Ale w pewnym momencie pisanie jako asm może stać się jaśniejsze, jeśli schodzisz do tego poziomu bałaganu.Już nie prędkość, ale kontrola . Szybkość czasami zależy od kontroli, ale jest to jedyny powód do kodowania w asemblerze. Każdy inny powód sprowadza się do kontroli (tj. Optymalizacji SSE i innych stron, sterowników urządzeń i kodu zależnego od urządzenia itp.).
źródło
Jeśli będę w stanie przewyższyć GCC i Visual C ++ 2008 (znanym również jako Visual C ++ 9.0), ludzie będą zainteresowani przeprowadzeniem ze mną wywiadu, jak to jest możliwe.
Dlatego w tej chwili po prostu czytam rzeczy w asemblerze i po prostu piszę __asm int 3, gdy jest to wymagane.
Mam nadzieję, że ta pomoc ...
źródło
Od kilku lat nie pisałem w asemblerze, ale dwa powody to:
Wciąż patrzę na montaż kodowania i to nic innego jak wyzwanie i radość z tego. Nie mam innego powodu :-)
źródło
Kiedyś przejąłem projekt DSP, który poprzedni programista napisał głównie w kodzie asemblera, z wyjątkiem logiki wykrywania tonów, która została napisana w C, używając zmiennoprzecinkowego (na stałym punkcie DSP!). Logika wykrywania tonu działała około 1/20 czasu rzeczywistego.
Skończyło się na przepisaniu prawie wszystkiego od zera. Prawie wszystko było w C, z wyjątkiem kilku małych programów obsługi przerwań i kilkudziesięciu linii kodu związanych z obsługą przerwań i wykrywaniem niskich częstotliwości, które działają ponad 100 razy szybciej niż stary kod.
Myślę, że ważną rzeczą, o której należy pamiętać, jest to, że w wielu przypadkach będzie znacznie większe możliwości zwiększenia szybkości przy użyciu małych procedur niż dużych, zwłaszcza jeśli ręcznie napisany asembler może zmieścić wszystko w rejestrach, ale kompilator nie całkiem poradzić sobie. Jeśli pętla jest na tyle duża, że i tak nie może przechowywać wszystkiego w rejestrach, jest znacznie mniej okazji do poprawy.
źródło
Maszyna wirtualna Dalvik, która interpretuje kod bajtowy aplikacji Java na telefonach z systemem Android, korzysta z asemblera jako dyspozytora. Ten film (około 31 minut, ale warto obejrzeć cały film!) Wyjaśnia, jak to zrobić
źródło
Nie robię tego, ale postanowiłem przynajmniej spróbować i bardzo się postarać w przyszłości (miejmy nadzieję, że wkrótce). Nie może być nic złego, aby dowiedzieć się więcej na temat rzeczy niskiego poziomu i tego, jak działają one za kulisami, gdy programuję w języku wysokiego poziomu. Niestety, trudno o pracę na pełny etat jako programista / konsultant i rodzic. Ale poddam się w odpowiednim czasie, to na pewno.
źródło