Porady dla początkujących w asemblerze

0

Witam wszystkich. Jestem studentem 2. Roku informatyki i przede mną na 4. Semestrze przedmiot "Programowanie niskopoziomowe", na którym będziemy się uczyć języka Asembler. Jednakże najpierw podstaw Asemblera chciałbym się nauczyć samodzielnie, ale z tego, co czytałem w internecie, jeśli tego języka nauczę się metodą prób i błędów, to procesor komputera może się uszkodzić. W związku z tym, co mi doradzicie, żebym ja się nauczył samodzielnie języka Asembler? I czy są jakieś wirtualne procesory, na którym mógłbym "praktykować" podstawy Asemblera?

Dodatkowe pytanie: Jeśli uda mi się nauczyć Asemblera, to czy jest w ogóle praca w tym kierunku? Jeśli tak, to czego jeszcze wtedy musiałbym się nauczyć, aby dostać pracę związaną z Asemblerem?

3

Dobrze byłoby najpierw dowiedzieć się jakiego procesora będziecie używać na zajęciach: intel x86, ARM, MIPS albo innego? Poza tym typ architektury takiego procesora: 32-u bitowej czy 64-ro bitowej. Dalej trzebaby poczytać o strukturze samego procesora - ile i jakie ma rejestry i jak się ich używa. Różne rejestry mogą mieć różne przeznaczenie jak również dostęp do niektórych z nich może być w jakiś sposób zastrzeżony. Sposoby dostępu do pamięci są również istotne. Temat raczej dosyć obszerny.

Do eksperymentowania bezpośrednio na procesorze polecam użyć jakiejś emulacji - polecam używać qemu.

Odnośnie pracy w specjalizacji programowania niskopoziomowego - to tutaj może to być działka embedded. Ale w embedded zwykle (choć nie zawsze) potrzebna będzie dodatkowo znajomość elektroniki i techniki cyfrowej. Natomiast jeśli chodzi o zastosowania znajomości kodu maszynowego to w tej chwili bardzo mało tworzy się tego typu kodu - i raczej jego znajomość potrzebna jest do debugowania różnych bardziej skomplikowanych sytuacji. Czyli stosuje się go zazwyczaj do analizy kodu wygenerowanego przez kompilator aniżeli pisania kodu maszynowego od zera. Oprócz tego programowanie w kodzie maszynowym trzeba powiązać z jakimś systemem operacyjnym jak np. Linux czy Windows. Chyba że będziesz pisać własne bootloadery - wtedy odwołujesz się bezpośrednio do rejestrów architektury a nie tego co zapewnia system operacyjny.

Ogólnie - jest bardzo niszowa działka o wysokim progu wejścia, wymagająca zwykle dodatkowo znajomości działania elektroniki.

1
kondexor2000 napisał(a):

I czy są jakieś wirtualne procesory, na którym mógłbym "praktykować" podstawy Asemblera?

Tu coś jest:
https://schweigi.github.io/assembler-simulator/
i tu:
https://exuanbo.xyz/assembler-simulator/

nie wiem, ile to jest warte, po prostu wyskoczyło mi to w Google.
https://www.google.com/search?q=assembler+emulator

4

Co do uszkodzenia komputera przy motodzie prób i błędôw. O ile ne piszesz na jakimś specjalistycznym komputerze (nie PC) i nie przeniesiesz sie 40 lat postępu techniczengo wstecz - to nie uszkodzisz. Szansa zrobienia krzywdy praktycznie zerowa, a dodatkowo zabezpiecza cię OS.

3
jarekr000000 napisał(a):

Co do uszkodzenia komputera przy motodzie prób i błędôw. O ile ne piszesz na jakimś specjalistycznym komputerze (nie PC) i nie przeniesiesz sie 40 lat postępu techniczengo wstecz - to nie uszkodzisz. Szansa zrobienia krzywdy praktycznie zerowa, a dodatkowo zabezpiecza cię OS.

windows 98 se ma mniej niż 40 lat i nie zabezpieczył mnie przed nadpisaniem sektora https://pl.wikipedia.org/wiki/Master_Boot_Record (włączając w to nadpisanie kopii zapasowej) :] ale to raczej ciekawostka niż przestroga

* z tą kopią zapasową sektora mbr to już nie pamiętam dokładnie historii. być może chciałem coś kombinować z tym sektorem, ale najpierw sam robiłem kopię zapasową, kopiując zawartość do następnego sektora.

2

My mieliśmy zajęcia assemblera na DosBoxie. Polecam ten stan, bo:

  • dos jest prosty, x86 z tamtych czasów też więc mało nauki a nauczysz się myślenia
  • dosbox wszędzie działa tak samo więc nie ma problemów z przenoszeniem programów
1

Można też swojego assemblera zrobić - przez assemblera mam na myśli język z banalną składniową i prostymi założeniami, który będzie działać na rejestrach czy stosie - zrobienie maszyny stosowej jest banalne np. wymyślasz sobie instrukcje:

ładuj 3 
ładuj 5
dodaj 

gdzie "ładuj" będzie pchało na stos liczbę, a "dodaj" będzie pobierało 2 ostatnie liczby ze stosu, dodawało je do siebie(3+5) i umieszczało wartość(8) na stosie.
https://en.wikipedia.org/wiki/Stack_machine
można też jakieś rejestry sobie wymyślić, czy jakieś skoki czy inne rzeczy, które są w assemblerach. Można się inspirować jakimś prawdziwym assemblerem albo spojrzeć na instrukcje z jakichś wirtualnych maszyn (które zwykle będą działać na trochę wyższym poziomie abstrakcji) np. tutaj o bajtkodzie z V8 (silnik JSa)
https://www.alibabacloud.com/blog/599188

Jeszcze też zależy, co jest twoim celem. Czy chcesz poznać to od strony algorytmicznej, czy faktycznie chcesz się nauczyć konkretnego assemblera, żeby móc konkretne rzeczy robić.

Chociaż jedno drugiemu nie przeszkadza, bo możesz zrobić sobie swojego wymyślonego assemblera, żeby lepiej zrozumieć temat, ale jednocześnie uczyć się o jakimś konkretnym, który robi prawdziwe rzeczy.

0

Można też swojego assemblera zrobić

To mi przypomina że muszę sobie ogarnąć parser https://github.com/shinh/elvm/blob/master/ELVM.md w Haskellu. Bardzo ładny prosty asembler

3

@vtx dał trochę sensownych rad (dowiedzieć się jaka architektura procesora np, jeśli to pod zajęcia). Ale ja udzielę odpowiedzi ze swojej, trochę innej perspektywy:

Jednakże najpierw podstaw Asemblera chciałbym się nauczyć samodzielnie, ale z tego, co czytałem w internecie, jeśli tego języka nauczę się metodą prób i błędów, to procesor komputera może się uszkodzić

Nie ma takiej szansy. Dowód "na logikę": asembler to po prostu język kompilujący się do kodu maszynowego (jak inne, np. C++) i dający nad tym dużo kontroli. Gdyby dało się napisać taki kod maszynowy który pali procesor, to mógłbyś założyć sobie za $5 konto w AWS/GCP/DigitalOcean i spalić im całą serwerownię (odpalając swój kod na ich maszynach).

Dodatkowe pytanie: Jeśli uda mi się nauczyć Asemblera, to czy jest w ogóle praca w tym kierunku? Jeśli tak, to czego jeszcze wtedy musiałbym się nauczyć, aby dostać pracę związaną z Asemblerem?

Ja zarabiam tak na życie ;). Tylko że w sumie to czytaniem, a nie pisaniem. Poza bardzo dziwnymi przypadkami, nikt nie pisze już całych programów w asemblerze - pisze sie najwyżej małe fragmenty kodu, wrappery, shellcody, hooki, itp.
Natomiast zrozumienie jak działa asember jest równoważne ze zrozumieniem jak działa procesor pod spodem i kluczowe do otrzymania pracy w wielu "niskopoziomowych" zawodach. A nawet i bez takiej pracy, warto to w miare rozumieć jako każdy programista IMO.

W związku z tym, co mi doradzicie, żebym ja się nauczył samodzielnie języka Asembler? I czy są jakieś wirtualne procesory, na którym mógłbym "praktykować" podstawy Asemblera?

W odróżnieniu od innych tutaj, polecam programowanie od razu "bare metal" na fizycznej maszynie. Zakładając że używasz Linuxa i 64bitowego procesora x86, zrób sobie np. plik example1.asm z taką zawartością:

global _start
section .text

_start:
  mov rax, 1  ; write
  mov rdi, 1  ; stdout
  mov rsi, msg  ; text
  mov rdx, msglen  ; n
  syscall

  mov rax, 60  ; exit
  mov rdi, 0  ; retval
  syscall

section .rodata
  msg: db "Hello world", 10
  msglen: equ $ - msg

Skompiluj:

nasm -f elf64 -o example1.o example1.asm
ld -o example1 example1.o

Wykonaj:

./example1
Hello world

I zacznij modyfikować na własną rękę, albo poszukaj tutoriala asemblera który krok po kroku Ci wytłumaczy ten język.

Oczywiście prędzej czy później (raczej prędzej) zrobisz jakiś bug i program przestanie działać (np. będzie segfaultował po uruchomieniu). Wtedy do gry wchodzi debugger (polecam gdb na Linuxie, x64dbg na Windowsie). Uruchamasz go, single-steppujesz krok po kroku i czytasz rejestry aż znajdzesz problem. Umiejętność debugowania programów na niskim poziomie to inna praktyczna rzecz której uczy pisanie w asemblerze.

Ostatecznie, tak jak mówiłem, nikt nie pisze całych programów w asemblerze. Ale wstawki asemblerowe już tak. Możesz np. napisać taki kod w C:

extern void hello_world();
int main() {
    hello_world();
}

zmienić funkcję _start w poprzednim przykładzie na hello_world, a potem skompilowac i zlinkować je razem i zobaczyć że to faktycznie działa razem. Z praktycznych wersji tego ćwiczenia, napisać w C program który coś liczy, a później najwolniejsze funkcje w nim wymieniać na wersje w asemblerze.

1

Nie wiem co masz na myśli an temat uszkodzenia.

No tak procka nie uszkodzisz chyba, że kiepskie chłodzenie itp. to możliwe że jakoś go przegrzejesz i może się nie wyłączyć w porę bo są zabezpieczenia i się przepali coś.

I dyski twarde czasem się blokują na amen, czyli coś tam uszkodzisz, ale to raczej takie pierdoły, normalnie nic nie uszkodzisz w assemblerze, albo nie wiem że jest taka możliwość.
No chyba, że BIOS byś jakoś przeprogramował i wtedy by ci płyta główna nie wstała czy coś.

Tak nic nie zepsujesz nie ma opcji, trzeba być naprawdę zaawansowanym graczem, żeby coś zepsuć, amator nie da rady.

1

Jako porady dla początkującego, odczytaj plik w assemblerze, zrób parsowanie stringów do integerów, może jakiś quick sort na danych, dynamiczna alokacja lub na stosie, proste problemy a trudne zadania, i pamiętaj że debugger jak programujesz w assemblerze jesta bardziej potrzebny niż winnych językach, dodatkowo ci powiem, że jak robisz dzielenie to zeruj resztę z dzielenia inaczej ona się wlicza do obliczeń, i zeruj rejetsry bo potem się okaże że jakiś błąd był, i jak wywołujesz inne funkcje to dane musisz mieć schowane na stosie inaczej utracisz dane w rejestrach bo inne funkcje nadpiszą.

1

Nie ma takiej opcji żebyś coś popsuł, serio.
A jak już się boisz to są kompilatory online do tego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1