Darazsak írása assemblerben. Assembly nyelviskola: operációs rendszer fejlesztés. Az assembly nyelv előnyei

  • Dátum: 14.05.2021

Eredeti: AsmSchool: Készíts operációs rendszert
Szerző: Mike Saunders
Megjelenés dátuma: 2016. április 15
Fordítás: A. Panin
Az átutalás időpontja: 2016. április 16

4. rész: A sorozat korábbi cikkeiből elsajátított készségekkel megkezdheti saját operációs rendszerének fejlesztését!

Mire való?

  • A fordítók működésének megértéséhez.
  • Az utasítások megértéséhez CPU.
  • A kód optimalizálása a teljesítmény szempontjából.

Néhány hónap leforgása alatt hosszú utat tettünk meg, amely egyszerű assembly nyelvű programok fejlesztésével kezdődött Linuxra, és a sorozat utolsó cikkében végződött a személyi számítógépen futó önálló kód kifejlesztésével. operációs rendszer nélkül. Nos, most megpróbáljuk összegyűjteni az összes információt, és létrehozni egy valódi operációs rendszert. Igen, Linus Torvalds nyomdokaiba lépünk, de először érdemes a következő kérdésekre válaszolni: "Mi az operációs rendszer? Melyik funkcióját kell majd újra létrehoznunk?".

Ebben a cikkben csak az operációs rendszer fő funkcióira összpontosítunk: a programok betöltésére és végrehajtására. Az összetett operációs rendszerek sokkal több funkciót látnak el, mint például a virtuális memória kezelése és a hálózati csomagok feldolgozása, de ezek helyes megvalósítása évekig tartó folyamatos munkát igényel, ezért ebben a cikkben csak azokat a fő funkciókat vesszük figyelembe, amelyek bármely operációs rendszerben jelen vannak. A múlt hónapban kifejlesztettünk egy kis programot, amely egy hajlékonylemez 512 bájtos szektorába (az első szektorába) illeszkedik, most pedig egy kicsit módosítunk rajta, hogy hozzáadjuk a lemezről további adatok betöltésének funkcióját.

Bootloader fejlesztés

Megpróbálhatnánk, hogy az operációs rendszerünk binárisan a lehető legkisebb legyen, hogy a hajlékonylemez első 512 bájtos szektorába kerüljön, abba, amelyet a BIOS tölt be, de ebben az esetben nem tudjuk megvalósítani. bármilyen érdekes funkciót. Ezért ezt az 512 bájtot használjuk egy egyszerű rendszerbetöltő bináris kódjának elhelyezésére, amely betölti az operációs rendszer kernelének bináris kódját a RAM-ba, és végrehajtja azt. (Ezek után fejlesztjük magát az operációs rendszer kernelt, ami a többi program bináris kódját is betölti a lemezről és le is hajtja, de erről kicsit később lesz szó.)

A cikkben tárgyalt példák forráskódja letölthető a www.linuxvoice.com/code/lv015/asmschool.zip címről. Ez pedig a bootloaderünk kódja a boot.asm nevű fájlból:

BITS 16 jmp rövid indítás ; Ugrás a címkére, lemezleírás átugrása nop ; Hozzáadás a lemez leírása előtt %include "bpb.asm" start: mov ax, 07C0h ; Betöltési cím mov ds, ax ; Adatszegmens mov ax, 9000h ; Verem előkészítése mov ss, ax mov sp, 0FFFFh ; A verem egyre csökken! cld ; Irányjelző beállítása mov si, kern_filename hívás load_file jmp 2000h:0000h ; Ugrás a kern_fájlnév db "MYKERNELBIN" fájlból betöltött operációs rendszer kernel bináris fájljára %include "disk.asm" szor 510-($-$$) db 0 ; Bináris kód nulla kitöltése 510 bájtig dw 0AA55h ; Boot loader bináris kód végjel puffer: ; Indítsa el a puffert a lemez tartalmához

Ebben a kódban az első CPU utasítás a jmp utasítás, amely a BITS direktíva után található, amely közli a NASM assemblerrel, hogy 16 bites mód van használatban. A sorozat előző cikkéből bizonyára emlékszik rá, hogy a BIOS által a lemezről betöltött 512 bájtos bináris kód végrehajtása a legelején kezdődik, de a speciális adatkészlet kihagyásához a címkére kell ugranunk. Nyilvánvalóan a múlt hónapban csak a kódot írtuk a lemez elejére (a dd segédprogrammal), és a lemezterület többi részét üresen hagytuk.

Egyelőre egy hajlékonylemezt kell használnunk megfelelő fájlrendszer MS-DOS (FAT12), és ahhoz, hogy megfelelően működjön ezzel a fájlrendszerrel, hozzá kell adnia egy speciális adatkészletet a szektor elejéhez. Ezt a készletet "BIOS-paraméterblokknak" (BPB) nevezik, és olyan adatokat tartalmaz, mint a lemezcímke, a szektorok száma stb. Ez most nem érdekelhet bennünket, mivel az ilyen témákat több cikksorozatnak is lehet szentelni, ezért minden ezzel kapcsolatos utasítást és adatot egy külön forráskód-fájlba helyeztünk el bpb.asm néven.

A fentiek alapján ez a kódunkból származó irányelv rendkívül fontos:

%include "bpb.asm"

Ez egy NASM direktíva a tartalom felvételére megadott fájl forráskódot az aktuális forrásfájlba az összeállítás során. Így a BIOS paraméterblokk megvalósításának minden részletét külön fájlba mozgatva a lehető legrövidebbé és érthetőbbé tudjuk tenni rendszerbetöltőnk kódját. A BIOS paraméterblokkjának a szektor indítása után három bájttal kell elhelyezkednie, és mivel a jmp utasítás csak két bájtot foglal el, a nop utasítást kell használnunk (a neve a "no operation" rövidítése - ez egy olyan utasítás, amely nem csinál semmit de pazarolja a CPU ciklusait ) a fennmaradó bájt kitöltéséhez.

Munka a veremmel

Ezután az előző cikkben tárgyalthoz hasonló utasításokat kell használnunk a regiszterek és a verem elkészítéséhez, valamint a cld utasítást (a "clear direction" rövidítése), amely lehetővé teszi bizonyos utasítások irányjelzőjének beállítását, mint például a lodsb utasítás, amely végrehajtása esetén az SI regiszterben lévő értéket növeli, nem pedig csökkenti.

Ezt követően beírjuk a string címét az SI regiszterbe, és meghívjuk a load_file függvényünket. De gondoljon egy pillanatra – ezt a funkciót még nem fejlesztettük ki! Igen, ez igaz, de megvalósítása egy másik forráskódfájlban található, amelyet disk.asm néven használunk.

Az MS-DOS-ban formázott hajlékonylemezeken használt FAT12 fájlrendszer a létező legegyszerűbb fájlrendszerek egyike, de jó mennyiségű kódot is igényel, hogy a tartalmával működjön. A load_file szubrutin körülbelül 200 soros, és ebben a cikkben nem fog megjelenni, mivel egy operációs rendszer fejlesztését fontolgatjuk, nem pedig egy adott fájlrendszer illesztőprogramját, ezért nem túl bölcs dolog helyet pazarolni a naplóoldalakon. ilyen módon. Általánosságban elmondható, hogy a disk.asm forráskódfájlt majdnem az aktuális forrásfájl vége előtt helyeztük el, és ezt elfelejthetjük. (Ha továbbra is érdekel a FAT12 fájlrendszer felépítése, elolvashatja a kiváló áttekintést a http://tinyurl.com/fat12spec címen, majd belenézhet a disk.asm forráskódfájlba – az abban található kód jól kommentálva.)

Mindenesetre a load_file szubrutin az SI regiszterben megadott nevű fájl bináris kódját a 2000-es szegmensbe tölti be 0 eltolás mellett, majd ennek elejére ugrunk a végrehajtáshoz. És ez minden - az operációs rendszer kernelje betöltődött, és a rendszerbetöltő befejezte a feladatát!

Talán észrevette, hogy kódunk a MYKERNEL.BIN helyett a MYKERNELBIN-t használja az operációs rendszer kernelfájljának neveként, ami jól illeszkedik a DOS-ban a hajlékonylemezeken használt 8+3 elnevezési sémához. Valójában a FAT12 fájlrendszer a fájlnevek belső reprezentációját használja, és helyet takarítunk meg olyan fájlnév használatával, amely garantáltan nem igényli a load_file szubrutinunkat, hogy olyan mechanizmust valósítson meg, amely a pont karaktert keresi, és a fájlnevet a fájl belső reprezentációjává alakítja. fájlrendszer.

A disk.asm forráskódfájl csatlakoztatására vonatkozó direktívát tartalmazó sor után két sor található, amelyek a rendszerbetöltő bináris kódját nullákkal töltik fel 512 bájtig, és tartalmazzák a bináris kódjának végjelét (erről a cikkben volt szó az utolsó cikk). Végül a kód legvégén található a "puffer" címke, amelyet a load_file szubrutin használ. Általában a load_file szubrutinnak szabad területre van szüksége véletlen hozzáférésű memória hogy végre hajtsunk néhány közbenső műveletet a lemezen lévő fájl keresése során, és van elég szabad hely a rendszerbetöltő betöltése után, ezért itt helyezzük el a puffert.

A rendszerbetöltő összeállításához használja a következő parancsot:

nasm -f bin -o boot.bin boot.asm

Most létre kell hoznunk egy MS-DOS virtuális hajlékonylemez-képet, és hozzá kell adnunk a rendszerbetöltő binárisunkat az első 512 bájthoz a következő parancsokkal:

Mkdosfs -C floppy.img 1440 dd conv=notrunc if=boot.bin of=floppy.img

Ezzel a rendszerbetöltő fejlesztési folyamat befejeződött! Most már van egy rendszerindító hajlékonylemez-képünk, amely lehetővé teszi, hogy betöltsük az operációs rendszer kernel bináris fájlját a mykernel.bin nevű fájlból, és végrehajtsuk azt. Ezután a munka egy érdekesebb részére várunk - magának az operációs rendszer kernelének fejlesztésére.

operációs rendszer kernel

Azt akarjuk, hogy operációs rendszermagunk számos fontos feladatot végezzen el: üdvözlő üzenetet jelenítsen meg, fogadjon bemenetet a felhasználótól, meghatározza, hogy a bemenet támogatott parancs-e, és a programokat lemezről hajtsa végre, miután a felhasználó megadta a nevét. Ez az operációs rendszer kernelkódja a mykernel.asm fájlból:

Mov ax, 2000h mov ds, ax mov es, ax loop: mov si, prompt call lib_print_string mov si, user_input call lib_input_string cmp byte , 0 je loop cmp word , "ls" je list_files mov ax, fili276x, filib_86 jc load_fail call 32768 jmp loop load_fail: mov si, load_fail_msg hívás lib_print_string jmp hurok list_files: mov si, file_list call lib_get_file_list call lib_print_string jmp loop prompt db fail 13, 10, msgt1, db fail 13, 10, "0 db 3 ", msgt ", 0 user_input times 256 db 0 file_list times 1024 db 0 %clude "lib.asm"

Mielőtt megnézné a kódot, ügyeljen a direktíva utolsó sorára, hogy belefoglalja a lib.asm forráskódfájlt is, amely szintén a weboldalunk asmschool.zip archívumában található. Ez egy hasznos szubrutin könyvtára a képernyővel, billentyűzettel, sorokkal és lemezekkel való munkához, amelyeket szintén használhat – ebben az esetben ezt a forráskódfájlt az operációs rendszer kernel fő forráskódfájljának legvégére helyezzük el annak érdekében, hogy hogy az utóbbi minél kompaktabb és szebb legyen . Tekintse meg a "lib.asm Library Rutinok" részt az összes elérhető rutinnal kapcsolatos további információkért.

Az operációs rendszer kernelkódjának első három sorában a szegmensregisztereket feltöltjük adatokkal, hogy arra a 2000-es szegmensre mutassunk, amelybe a bináris kód betöltődött. Ez fontos annak biztosítására, hogy az olyan utasítások, mint például a lodsb , amelyeknek az aktuális szegmensből kell kiolvasniuk az adatokat, nem másból, megfelelően működjenek. Ezt követően nem hajtunk végre további műveleteket a szegmenseken; operációs rendszerünk 64 KB RAM-mal fog futni!

A kódban további címke található, amely megfelel a ciklus kezdetének. Először is a lib.asm könyvtár egyik rutinját használjuk, mégpedig a lib_print_string , hogy kinyomtassuk az üdvözlést. Az üdvözlő sor előtti 13. és 10. bájtok újsor karakterek, amelyek miatt az üdvözlet nem közvetlenül a program kimenete után jelenik meg, hanem mindig új sorban.

Ezt követően a lib.asm könyvtárból egy másik, lib_input_string nevű rutint használunk, amely a felhasználó által a billentyűzet segítségével beírt karaktereket veszi és egy pufferben tárolja, aminek a mutatója az SI regiszterben van. Esetünkben a puffer deklarálása az operációs rendszer kernelkódjának vége felé a következőképpen történik:

Felhasználói_beviteli idők 256 db 0

Ez a deklaráció lehetővé teszi egy 256 karakterből álló, nullával töltött puffert, amelynek elég hosszúnak kell lennie ahhoz, hogy parancsokat tároljon egy olyan egyszerű operációs rendszerhez, mint a miénk!

Ezután végrehajtjuk a felhasználói bevitel érvényesítését. Ha a user_input puffer első bájtja null, akkor a felhasználó egyszerűen megnyomta az Enter billentyűt anélkül, hogy parancsot adott volna; ne felejtse el, hogy minden karakterlánc null karakterrel végződik. Tehát ebben az esetben csak ugorjunk a ciklus elejére, és nyomtassuk ki újra az üdvözlést. Ha azonban a felhasználó bármilyen parancsot beír, először ellenőriznünk kell, hogy beírta-e az ls parancsot. Eddig csak egyes bájtok összehasonlítását láthatta assembly nyelvi programjainkban, de ne feledje, hogy lehetőség van kétbájtos értékek vagy gépszavak összehasonlítására is. Ebben a kódban összehasonlítjuk a user_input puffer első gépi szavát az ls sornak megfelelő gépi szóval, és ha azonosak, akkor áttérünk az alábbi kódblokkra. Ezen a kódblokkon belül egy másik rutint használunk a lib.asm könyvtárból, hogy megkapjuk a lemezen lévő fájlok vesszővel elválasztott listáját (amelyet a file_list pufferben kell tárolni), kinyomtatjuk a listát a képernyőre, majd visszahurkoljuk a feldolgozáshoz. felhasználói bevitel.

Harmadik féltől származó programok végrehajtása

Ha a felhasználó nem írja be az ls parancsot, akkor feltételezzük, hogy a program nevét lemezről írta be, így érdemes megpróbálni betölteni. A lib.asm könyvtárunk egy hasznos lib_load_file szubrutin megvalósítását tartalmazza, amely elemzi a lemez FAT12 fájlrendszerének tábláit: egy mutatót visz egy sor elejére egy fájlnévvel az AX regiszter segítségével, valamint egy offset érték bináris kód betöltéséhez programfájlból a CX regiszter használatával. Már az SI regisztert használjuk a felhasználói bemeneti karakterlánc mutatójának tárolására, ezért ezt a mutatót bemásoljuk az AX regiszterbe, majd beírjuk a 32768 értéket, amelyet eltolásként használunk a bináris kód betöltéséhez a programfájlból. a CX regiszterbe.

De miért használjuk ezt az értéket eltolásként a bináris kód programfájlból való betöltéséhez? Nos, ez csak az egyik memóriatérkép opció az operációs rendszerünkhöz. Mivel egyetlen 64 KB-os szegmensben dolgozunk, és a kernel bináris fájlja 0 eltolásnál van betöltve, az első 32 KB-ot a kerneladatokhoz, a maradék 32 KB-ot pedig a betölthető programadatokhoz kell használnunk. Így a 32768 offset a szegmensünk közepe, és lehetővé teszi, hogy elegendő mennyiségű RAM-ot biztosítsunk mind az operációs rendszer kernelének, mind a betöltött programoknak.

Ezt követően a lib_load_file rutin egy nagyon fontos műveletet hajt végre: ha nem talál a megadott nevű fájlt a lemezen, vagy valamilyen oknál fogva nem tudja olvasni a lemezről, egyszerűen kilép és beállít egy speciális átviteli jelzőt. Ez egy olyan CPU állapotjelző, amely bizonyos matematikai műveletek során kerül beállításra, és jelenleg nem érdekelhet bennünket, de a jelző jelenlétét meghatározhatjuk a gyors döntések meghozatalához. Ha a lib_load_asm szubrutin beállítja a carry jelzőt, akkor a jc (jump if carry) utasítással arra a kódblokkra ugorunk, amely kiírja a hibaüzenetet, és visszatér a felhasználói beviteli ciklus elejére.

Ugyanebben az esetben, ha az átviteli jelző nincs beállítva, arra a következtetésre juthatunk, hogy a lib_load_asm szubrutin sikeresen betöltötte a bináris kódot a programfájlból a 32768-as RAM-ba. Ebben az esetben csak a bináris kód végrehajtását kell elindítani. ezen a címen töltve be , azaz indítsa el a felhasználó által megadott program végrehajtását! És miután ebben a programban a ret utasítást használjuk (a hívó kódhoz való visszatéréshez), csak vissza kell térnünk a felhasználói beviteli hurokhoz. Így létrehoztunk egy operációs rendszert: a parancsok elemzésére és a programok betöltésére szolgáló legegyszerűbb mechanizmusokból áll, mintegy 40 soros összeállítási kódon belül implementálva, bár a lib.asm könyvtár szubrutinjainak nagy segítsége mellett.

Az operációs rendszer kernelkódjának összeállításához használja a következő parancsot:

Nasm -f bin -o mykernel.bin mykernel.asm

Ezt követően valahogyan hozzá kell adnunk a mykernel.bin fájlt a hajlékonylemez képfájljához. Ha ismeri a lemezképek loopback eszközökkel történő csatlakoztatásának trükkjét, akkor a floppy.img lemezkép tartalmához hozzáférhet vele, de van egy egyszerűbb módja a GNU Mtools (www.gnu.org/software /mtools) használatával. ). Ez egy olyan programkészlet az MS-DOS/FAT12 fájlrendszert használó hajlékonylemezekkel való munkához, amelyek a csomagtárakból érhetők el. szoftver mind népszerű Linux disztribúciók, tehát nincs más dolgod, mint az apt-get , yum , pacman , vagy bármilyen más segédprogram használata, amellyel szoftvercsomagokat telepíthetsz a disztribúciódra.

A megfelelő szoftvercsomag telepítése után a mykernel.bin fájl floppy.img lemezképfájlhoz való hozzáadásához a következő parancsot kell futtatnia:

Mcopy -i floppy.img mykernel.bin::/

Figyelje meg a vicces karaktereket a parancs végén: kettőspont, kettőspont és perjel. Most már majdnem készen állunk az operációs rendszerünk elindítására, de mi értelme van ennek, amíg nincsenek rá alkalmazások? Javítsuk ki ezt a félreértést egy rendkívül egyszerű alkalmazás fejlesztésével. Igen, most egy alkalmazást fog fejleszteni a saját operációs rendszeréhez – képzelje el, mennyit fog emelkedni a tekintélye a geekek sorában. Mentse el a következő kódot egy test.asm nevű fájlba:

Org 32768 mov ah, 0Eh mov al, "X" int 10h ret

Ez a kód egyszerűen a BIOS funkció segítségével megjeleníti az "X" karaktert a képernyőn, ami után visszaadja az irányítást az őt hívó kódnak - esetünkben ez a kód az operációs rendszer kódja. Az alkalmazás forráskódját elindító org sor nem CPU utasítás, hanem egy NASM assembler direktíva, amely azt mondja neki, hogy a bináris kód a 32768-as eltolásnál kerül betöltésre a RAM-ba, ezért minden eltolást újra kell számítani ennek a körülménynek a figyelembevételével. .

Ezt a kódot is össze kell állítani, és a kapott bináris fájlt hozzá kell adni a hajlékonylemez képfájlhoz:

Nasm -f bin -o test.bin test.asm mcopy -i floppy.img test.bin::/

Most vegyen egy mély levegőt, készüljön fel saját munkája felülmúlhatatlan eredményének szemtanúira, és indítsa el a floppy lemezképet egy PC-emulátor, például a Qemu vagy a VirtualBox segítségével. Például a következő parancs használható erre a célra:

Qemu-system-i386 -fda floppy.img

Voila: a lemezkép első szektorába integrált boot.img rendszerbetöltő betölti a mykernel.bin operációs rendszer kernelt, amely üdvözlést jelenít meg. Írja be az ls parancsot, hogy megkapja a lemezen lévő két fájl nevét (mykernel.bin és test.bin), majd írja be az utoljára végrehajtandó fájl nevét, és jelenítse meg az X karaktert a képernyőn.

Ez klassz, nem? Most megkezdheti az operációs rendszer héjának testreszabását, új parancsok megvalósítását, és további programfájlok hozzáadását a lemezre. Ha ezt az operációs rendszert valódi PC-n szeretnéd futtatni, akkor olvasd el a sorozat előző cikkének "A rendszertöltő futtatása valódi hardverplatformon" című részt - pontosan ugyanazokra a parancsokra lesz szükséged. A következő hónapban hatékonyabbá tesszük operációs rendszerünket azáltal, hogy lehetővé tesszük a letölthető programok számára a rendszerfunkciók használatát, így megvalósítjuk a kódleválasztás koncepcióját a kódduplikáció csökkentése érdekében. A munka nagy része még hátra van.

lib.asm könyvtári rutinok

Ahogy korábban említettük, a lib.asm könyvtár hasznos szubrutinok széles készletét kínálja az operációs rendszer kerneleiben és az egyes programokban való használatra. Egyesek olyan utasításokat és fogalmakat használnak, amelyekkel a sorozat cikkei még nem foglalkoztak, mások (például a lemezekkel való munkavégzés rutinjai) szorosan kapcsolódnak a fájlrendszerek felépítéséhez, de ha kompetensnek tartja magát ezekben a kérdésekben, megismerkedhet azok megvalósításával és megértheti a munka elvét. Azonban sokkal fontosabb megérteni, hogyan hívhatja meg őket a saját kódjából:

  • lib_print_string – Mutatót visz egy null-végződésű karakterláncra az SI-regiszteren keresztül, és kinyomtatja a karakterláncot a képernyőre.
  • lib_input_string - egy mutatót visz egy pufferre az SI regiszteren keresztül, és feltölti ezt a puffert a felhasználó által a billentyűzet segítségével beírt karakterekkel. Miután a felhasználó megnyomta az Enter billentyűt, a pufferben lévő karakterlánc null-végű lesz, és a vezérlés visszatér a hívó program kódjához.
  • lib_move_cursor - A kurzort a képernyőn a DH (sorszám) és DL (oszlopszám) regisztereken átmenő koordinátákkal rendelkező pozícióba mozgatja.
  • lib_get_cursor_pos - hívja meg ezt az alprogramot, hogy megkapja az aktuális sor- és oszlopszámokat a DH és DL regiszterek használatával.
  • lib_string_uppercase – Az AX-regiszter segítségével egy null-végződésű karakterlánc elejére viszi a mutatót, és a karakterláncban lévő karaktereket nagybetűssé alakítja.
  • lib_string_length – Az AX regiszter használatával egy null-végű karakterlánc elejére visz egy mutatót, és az AX regiszter használatával adja vissza a hosszát.
  • lib_string_compare – Mutatókat visz két null-végződésű karakterlánc elejére az SI és DI regisztereken keresztül, és összehasonlítja ezeket a karakterláncokat. Beállítja a carry flaget, ha a karakterláncok azonosak (a jc carry jelzőtől függően ugró utasítás használatához), vagy törli ezt a jelzőt, ha a karakterláncok különböznek (a jnc utasítás használatához).
  • lib_get_file_list – Mutatót visz egy puffer elejére az SI-regiszteren keresztül, és egy null-végződésű karakterláncot helyez el, amely a lemezről származó fájlnevek vesszővel elválasztott listáját tartalmazza a pufferbe.
  • lib_load_file - Az AX regiszter használatával egy fájlnevet tartalmazó karakterlánc elejére visz egy mutatót, és a CX regiszter által megadott eltolásnak megfelelően betölti a fájl tartalmát. Visszaadja a memóriába másolt bájtok számát (vagyis a fájl méretét) a BX regiszter segítségével, vagy beállítja a carry flaget, ha nem található a megadott nevű fájl.

Nemrég úgy döntöttem, hogy megtanulom az assemblert, de nem érdekelt a kódsorok pazarlása. Arra gondoltam, hogy miközben az assemblert tanulok, elsajátítok néhány tantárgyat. Így a választásom a rendszerbetöltő írására esett. Megállapításaim eredménye itt található ebben a blogban.

Azonnal szeretném elmondani, hogy szeretem az elméletet a gyakorlattal kombinálva, úgyhogy kezdjük.

Először megmutatom, hogyan készíts egy egyszerű MBR hogy mihamarabb élvezhessük az eredményt. Ahogy egyre bonyolultabbak vagyunk gyakorlati példák, elméleti információkat adok.

Először készítsünk egy USB flash meghajtó rendszerbetöltőt!

Figyelem!!! Az első assembler programunk mind flash meghajtóhoz, mind más eszközökhöz fog működni, mint például a hajlékonylemez vagy HDD. Ezt követően annak érdekében, hogy az összes példa megfelelően működjön, számos magyarázatot adok a kód különböző eszközökön történő működésére vonatkozóan.

írunk majd Fasm, mivel ezt tartják a legjobb fordítónak az írásbetöltők számára, ami az MBR. A másik ok, amiért a Fasm-ot választja, az, hogy nagyban leegyszerűsíti a fájlok fordításának folyamatát. Nincsenek parancssori direktívák stb. ostobaság, ami teljesen eltántoríthatja az assembler tanulását és a céljai elérését. Tehát a kezdeti szakaszban két programra van szükségünk és néhány szükségtelen kis flash meghajtó. Előkotortam 1Gb-ot (gyorsan formázva, és nem kár, ha valami). A rendszerbetöltőnk működése után a flash meghajtó nem fog megfelelően működni. a Windows 7 nem hajlandó formázni a flash meghajtót. Azt tanácsolom, hogy egy segédprogrammal állítsa életre a flash meghajtót HP USB Disk Storage Format Tool ( HPUSBFW.EXE) vagy más segédprogramok a flash meghajtók formázásához.

Telepítse őket, és dobja a megfelelő parancsikonokat az asztalra vagy bárhová, ahol tetszik.

A felkészülés véget ért, folytassuk a cselekvést

Nyissa meg a Fasmw.exe fájlt, és írja oda a következőket. Felvázoljuk a minimális kódot, hogy lássuk az eredményt. Később elemezzük, mi is az a nakalyakano. Röviden kommentálom.

FASM kód: ============= boot.asm ===============

org 7C00h ; programunk címeit ezen irányelv szerint számítjuk ki

használat16 ; hexadecimális kód jön létre

cli ; tiltsa le a megszakításokat a szegmensregiszterekben a címek megváltoztatásához

mov ax, 0

mov sp, 7C00h

sti ; megszakítás engedélyezése (címváltás után)

mov ax, 0003h ; állítsa be a videó módot a karakterlánc megjelenítéséhez a képernyőn

int 10h

mov ax, 1301h ; tényleges karakterlánc kimeneti függvény 13h int 10h (erről később)

mov bp, stroka ;kimeneti karakterlánc címe

mov dx, 0000h ;sor és oszlop, amelyben szöveg jelenik meg

mov cx, 15 ;a karakterek száma a kimeneti karakterláncban

mov bx, 000eh ;00-videó oldalszáma (jobb, ha nem érinti) 0e-karakter attribútumok (szín, háttér)

int 10h

jmp $ ;stalk a helyén (ezen a ponton hurkolja a programot)

line db "Ok, MBR betöltve!"

szor 510 - ($ - $$) db 0 ;az előző bájt és az utolsó bájt közötti rést nullákkal kitöltve

db 0x55 ,0xAA ;az utolsó két bájt

Fordítsa le ezt a kódot (Ctrl + F9) a fasm "e-be, és a kapott bináris fájlt mentse el boot.bin néven egy kényelmes helyre. Mielőtt a bináris fájlunkat USB flash meghajtóra írná, egy kis elmélet.

Amikor az USB flash meghajtót bedugtad a számítógépbe, a BIOS rendszer számára egyáltalán nem nyilvánvaló, hogy az USB flash meghajtóról akarsz bootolni, ezért a BIOS beállításainál ki kell választanod, hogy melyik eszközről szeretnél indítani. az USB-ről való indítást választottuk (ezt magadnak kell kitalálnia, mert a bios interfésznek különböző változatai vannak... a google-ban megtalálhatod a BIOS beállításait alaplap. Általában nincs semmi bonyolult).

Most, hogy a BIOS tudja, hogy a flash meghajtóról kíván indítani, meg kell győződnie arról, hogy a flash meghajtó nulla szektora indítható. Ehhez a BIOS úgy néz ki nulla szektor utolsó két bájtjaés ha egyenlők 0x55 0xAA-val, akkor csak akkor töltődik be a RAM-ba. Ellenkező esetben a BIOS egyszerűen elhalad a flash meghajtó mellett. Miután megtalálta ezt a két mágikus bájtot, betölti a nulla szektort a RAM-ba a 0000: 7C00h címen, majd elfelejti a flash meghajtót, és átadja a vezérlést erre a címre. Most a számítógép feletti teljes hatalom a rendszerbetöltőhöz tartozik, és már a RAM-ból is képes további kódot betölteni az USB flash meghajtóról. Most meglátjuk, hogyan néz ki ez a szektor a DMDE programban.

1. Helyezze be a flash meghajtót a számítógépbe, és ellenőrizze, hogy nem tartalmazza-e a szükséges információkat.

2. Nyissa meg a DMDE programot. Olvassa el az összes további műveletet a képeken:

Miután megnézte ezt a képregényt, képes lesz letölteni az MBR-t egy flash meghajtóra. És így néz ki a bootloaderünk régóta várt eredménye:


Mellesleg, ha a minimális betöltő kódról beszélünk, akkor ez így nézhet ki:

Org 7C00h
jmp$
db 508 dup(0)
db 0x55,0xAA

Egy ilyen betöltő, miután megkapta az irányítást, egyszerűen leteszi a számítógépet, és egy cikluson belül egyetlen értelmetlen jmp $ parancsot hajt végre. Én pangásnak hívom.

Feltettem egy videót a YouTube-ra, ami segíthet:

Végül néhány rövid tény a rendszerbetöltő munkájáról:

1. A Bootloader, más néven bootloader, más néven MBR mérete 512 bájt. Történelmileg
hogy ennek a feltételnek teljesülnie kell a régebbi adathordozók és eszközök támogatásához.
2. A rendszerbetöltő mindig a flash meghajtó, floppy hajlékonylemez nulla szektorában található, merevlemez, a DMDE program vagy más hexa szerkesztők szempontjából, amelyek lehetővé teszik az eszközökkel való munkát. Ha egy bináris fájlt (a mi boot.bin-ünket) szeretnénk betölteni a felsorolt ​​eszközök valamelyikére, nem kell a belső fizikai szerkezetükre gondolnunk. A DMDE program csak tudja, hogyan kell beolvasni a szektorokat ezeken az eszközökön, és LBA módban jeleníti meg őket (egyszerűen számozza őket 0-tól az utolsó szektorig). Az LBA-ról olvashatsz
3. A rendszerbetöltőnek mindig két 0x55 0xAA bájttal kell végződnie.
4. A betöltő mindig 0000:7C00h-nál töltődik be a memóriába.
5. A rendszerbetöltő elindítja az operációs rendszert.


Ma a Kunstkameránkban egy érdekes példa egy tiszta assemblerben írt operációs rendszer. A sofőrökkel együtt grafikus héj, több tucat előre telepített program és játék, kevesebb mint másfél megabájtot vesz igénybe. Ismerkedjen meg a kivételesen gyors és túlnyomórészt orosz OS Hummingbirddel.

A Hummingbird fejlesztése meglehetősen gyorsan ment egészen 2009-ig. A madár különböző hardvereken tanult meg repülni, amihez az első Pentium minimumára és nyolc megabájt RAM-ra volt szüksége. A Hummingbird minimális rendszerkövetelményei a következők:

  • CPU: Pentium, AMD 5x86 vagy Cyrix 5x86 MMX nélkül 100 MHz-en;
  • RAM: 8 MB;
  • Grafikus kártya: VESA-kompatibilis, támogatja a VGA módot (640 × 480 × 16).

A modern Hummingbird a 2009 végén megjelent legújabb hivatalos verzió rendszeresen frissített "éjszakai buildje". A 2017. augusztus 20-i 0.7.7.0+ buildet teszteltük.

FIGYELEM

Az alapértelmezett beállítások szerint a KolibriOS nem fér hozzá a BIOS-on keresztül látható lemezekhez. Gondolja át alaposan, és készítsen biztonsági másolatot a beállítás módosítása előtt.

Bár az éjszakai építményekben a változások kicsik, az évek során eléggé felhalmozódtak. A frissített Hummingbird képes FAT16-32 / ext2 - ext4 partíciókra írni, és olvasási módban támogat más népszerű fájlrendszereket (NTFS, XFS, ISO-9660). Hozzáadta az USB és a hálózati kártyák támogatását, TCP / IP verem és hangkodekek kerültek hozzáadásra. Általánosságban elmondható, hogy már lehet valamit csinálni benne, és nem csak egyszer ránézni egy ultrakönnyű, grafikus felülettel rendelkező operációs rendszerre, és lenyűgözni az indítási sebesség.



A korábbi verziókhoz hasonlóan a legújabb Hummingbird is flat assemblerben (FASM) íródott, és egy hajlékonylemezt foglal el – 1,44 MB. Ennek köszönhetően teljesen elhelyezhető valamilyen speciális memóriában. Például a kézművesek közvetlenül a Flash BIOS-ba írták a KolibriOS-t. Működés közben egyes processzorok gyorsítótárában teljes egészében megtalálható lehet. Képzelje csak el: az egész operációs rendszer a programokkal és az illesztőprogramokkal együtt gyorsítótárban van!

INFO

A kolibrios.org webhely meglátogatásakor a böngésző figyelmeztethet a veszélyre. Az ok nyilvánvalóan a disztribúcióban található assembler programok. A VirusTotal mostantól teljesen biztonságosként határozza meg a webhelyet.

A "kolibri" könnyen betölthető hajlékonylemezről, merevlemezről, flash meghajtóról, Live CD-ről vagy Virtuális gép. Az emulációhoz elegendő megadni az „egyéb” operációs rendszer típusát, hozzárendelni egy processzormagot és némi RAM-ot. Nem szükséges lemezt csatlakoztatni, és ha van DHCP-vel rendelkező router, a Hummingbird azonnal csatlakozik az internethez és helyi hálózat. A letöltés után azonnal megjelenik egy értesítés.


Egy probléma: a HTTPS protokollt nem támogatja a beépített Hummingbird böngésző. Ezért nem lehetett megnézni a webhelyet, valamint megnyitni a Google, a Yandex, a Wikipédia, a Sberbank oldalait ... valójában nincs szokásos cím. Mindenki biztonságos protokollra váltott már régen. Az egyetlen old-school tiszta HTTP-t tartalmazó webhely, amelyre ráakadtam, az "orosz kormány portálja" volt, de az is benézett szöveges böngésző nem a legjobb módon.



A Hummingbird megjelenési beállításai javultak az évek során, de még mindig messze vannak az ideálistól. A támogatott videomódok listája megjelenik a Hummingbird rendszerindító képernyőjén, amikor megnyomja az a betűt.



Az elérhető opciók listája kicsi, és előfordulhat, hogy a kívánt felbontás nem szerepel benne. Ha AMD (ATI) GPU-val rendelkező grafikus kártyája van, azonnal hozzáadhatja az egyéni beállításokat. Ehhez át kell adni az -m paramétert az ATIKMS rendszerbetöltőnek x x , Például:

/RD/1/DRIVERS/ATIKMS -m1280x800x60 -1

Itt az /RD/1/DRIVERS/ATIKMS a rendszerbetöltő (RD - RAM Disk) elérési útja.

A rendszer működése közben a kiválasztott videó mód a vmode paranccsal megtekinthető és (elméletileg) manuálisan váltható. Ha a Hummingbird egy virtuális gépen fut, akkor ez az ablak üres marad, de tiszta rendszerindítással Intel videó-illesztőprogramok adhatók hozzá az i915-től a Skylake-ig.

Meglepő módon egy csomó játék elfér a KolibriOS-ben. Vannak köztük logikai és arcade játékok, címkék, kígyó, tankok (nem, nem WoT) - egy egész "Game Center"! Még a Doom és a Quake is átkerült a Hummingbirdre.



Egy másik fontos dolog az FB2READ olvasó volt. Megfelelően működik cirill betűkkel és szöveges megjelenítési beállításokkal rendelkezik.



Azt javaslom, hogy az összes felhasználói fájlt USB flash meghajtón tárolja, de azt USB 2.0 porton keresztül kell csatlakoztatni. USB 3.0 flash meghajtónk (be USB csatlakozó 2.0) 16 GB kapacitású NTFS fájlrendszerrel azonnal meghatározásra került. Ha fájlokat kell írnia, akkor csatlakoztasson egy FAT32 partícióval rendelkező USB flash meghajtót.



A Hummingbird disztribúció három fájlkezelőt, képek és dokumentumok megtekintésére szolgáló segédprogramokat, audio- és videolejátszókat és egyéb felhasználói alkalmazásokat tartalmaz. A hangsúly azonban az assembly nyelvi fejlesztésen van.



beépített szöveg szerkesztő ASM szintaxis kiemeléssel rendelkezik, sőt lehetővé teszi a begépelt programok azonnali futtatását is.



A fejlesztőeszközök között megtalálható az Oberon-07/11 fordító i386 Windows, Linux és KolibriOS rendszerekhez, valamint alacsony szintű emulátorok: az E80 egy ZX Spectrum emulátor, az FCE Ultra pedig az egyik legjobb emulátorok NES, DOSBox v.0.74 és mások. Mindegyiket speciálisan a Hummingbirdre vitték.

Ha néhány percre elhagyja a KolibriOS rendszert, a képernyővédő elindul. A képernyőn kódsorok fognak futni, amelyekben a MenuetOS-re való hivatkozás látható.

Továbbra is csak a tagok számára elérhető

1. lehetőség: Csatlakozzon a "webhely" közösséghez, hogy elolvassa az oldalon található összes anyagot

A közösségben való tagság a megadott időszakban hozzáférést biztosít az ÖSSZES Hacker anyaghoz, növeli a személyes kumulatív kedvezményt, és lehetővé teszi, hogy professzionális Xakep Score értékelést gyűjtsön!

Azonnal azt mondom, ne zárja le a cikket azzal a gondolattal, hogy „A fenébe, még egy Popov”. Neki csak egy nyalott Ubuntu van, nekem pedig a semmiből van mindenem, beleértve a kernelt és az alkalmazásokat is. Szóval, folytatás a vágás alatt.

OS csoport: itt.
Először is dobok egy képernyőképet.

Nincs több belőlük, és most részletesebben arról, hogy miért írom.

Meleg áprilisi este volt, csütörtök. Gyerekkorom óta arról álmodoztam, hogy operációs rendszert írok, amikor hirtelen arra gondoltam: „Most már ismerem az előnyöket és az asm-ot, miért ne valósíthatná meg az álmomat?”. Kerestem a google-ban a témával foglalkozó oldalakat, és találtam egy cikket Habrtól: "Hogyan kezdjük el és ne hagyjuk abba az operációs rendszer írását". Köszönet szerzőjének az alábbi OSDev Wiki linkért. Odamentem és elkezdtem dolgozni. Egy cikkben volt minden adat a minimális operációs rendszerről. Elkezdtem cross-gcc-t és binutils-t építeni, majd onnan mindent átírtam. Látnod kellett volna az örömömet, amikor megláttam a "Hello, kernel World!" feliratot. Felugrottam a székről, és rájöttem – nem adom fel. Azt írtam, hogy "konzol" (idézőjelbe, nem fértem hozzá a billentyűzethez), de aztán úgy döntöttem, hogy ablakrendszert írok. Ennek eredményeként működött, de nem fértem hozzá a billentyűzethez. Aztán úgy döntöttem, hogy kitalálok egy nevet az X Window System alapján. A Google által keresett Y ablakrendszer – ez az. Ennek eredményeként elnevezte a Z Window System 0.1-et, amely az OS365 pre-alpha 0.1-ben található. És igen, rajtam kívül senki nem látta. Aztán rájöttem, hogyan kell megvalósítani a billentyűzet támogatást. Képernyőkép a legelső verzióról, amikor még semmi, még ablakrendszer sem volt:

Még a szöveg kurzort sem mozgatta, amint látható. Aztán írtam pár egyszerű Z-alapú alkalmazást.És itt az 1.0.0 alpha kiadás. Sok minden volt, még a rendszermenü is. A fájl kezelőés a számológép egyszerűen nem működött.

Egy barátom direkt terrorizált, akit csak a csinosság érdekel (Mitrofan, bocsánat). Azt mondta: „Lemostam a VBE módot 1024 * 768 * 32, lemostam, lemostam! Hát berúgtak! Nos, már belefáradtam a hallgatásába, és még mindig lemostam. A megvalósításról bővebben alább.

Mindent a bootloaderrel csináltam, mégpedig a GRUB "ohm-mal. Ezzel a Multiboot fejléchez néhány varázssort hozzáadva bonyodalmak nélkül beállíthatod a grafikus módot.

Állítsa be az ALIGN, 1<<0 .set MEMINFO, 1<<1 .set GRAPH, 1<<2 .set FLAGS, ALIGN | MEMINFO | GRAPH .set MAGIC, 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) .align 4 .long MAGIC .long FLAGS .long CHECKSUM .long 0, 0, 0, 0, 0 .long 0 # 0 = set graphics mode .long 1024, 768, 32 # Width, height, depth
Utána pedig kiveszem a Multiboot információs struktúrából a framebuffer címét és a képernyő felbontását, és oda írok pixeleket. A VESA mindent nagyon zavartan csinált - az RGB színeket fordított sorrendben kell megadni (nem R G B, hanem B G R). Több napig nem értettem - miért nem jelennek meg a pixelek!? A végén rájöttem, hogy elfelejtettem 16 színállandó értékét 0...15-ről RGB megfelelőire módosítani. Ennek eredményeként elengedtem, egyúttal lemostam a gradiens hátteret. Aztán csináltam egy konzolt, 2 alkalmazást és kiadtam az 1.2-t. Ó igen, majdnem elfelejtettem – letöltheti az operációs rendszert a címről

szerelő

szerelő(az angol assemble - to assemble szóból) - egy fordító az assembly nyelvről a gépi nyelvi parancsokra.
Minden processzorarchitektúrához és minden operációs rendszerhez vagy operációs rendszer családhoz tartozik egy Assembler. Léteznek úgynevezett „keresztösszeállítók” is, amelyek lehetővé teszik az egy architektúrájú gépeken (vagy egy operációs rendszer környezetében), hogy programokat állítsanak össze egy másik célarchitektúrához vagy egy másik operációs rendszerhez, és olyan formátumú futtatható kódot kapjanak, amely alkalmas a futtatásra. a cél architektúrában vagy a célkörnyezetben.

x86 architektúra

Összeszerelők DOS-hoz

A DOS operációs rendszer legismertebb összeszerelői a Borland Turbo Assembler (TASM) és a Microsoft Macro Assembler (MASM) voltak. Egy időben az egyszerű A86 összeszerelő is népszerű volt.
Kezdetben csak a 16 bites utasításokat támogatták (az Intel 80386 processzor megjelenése előtt). A TASM és MASM későbbi verziói egyaránt támogatják a 32 bites utasításokat, valamint a modernebb processzorokban bevezetett összes utasítást és az architektúra-specifikus utasításrendszereket (például MMX, SSE, 3DNow! stb.).

Microsoft Windows

A Microsoft Windows operációs rendszer megjelenésével megjelent a TASM32 névre keresztelt TASM bővítmény, amely lehetővé tette Windows környezetben futtatható programok készítését. A Tasm legújabb ismert verziója az 5.3, amely támogatja az MMX utasításokat, és jelenleg a Turbo C++ Explorer része. De hivatalosan a program fejlesztése teljesen leállt.
A Microsoft karbantartja a Microsoft Macro Assembler nevű terméket. A mai napig folyamatosan fejlődik, a legújabb verziókat a DDK-k tartalmazzák. De a program DOS-hoz való programok létrehozását célzó verzióját nem fejlesztik. Ezen kívül Stephen Hutchesson készített egy MASM programozási csomagot "MASM32" néven.

GNU és GNU/Linux

A GNU operációs rendszer tartalmazza a gcc fordítót, amely tartalmazza az AT&T szintaxist használó gas assemblert (GNU Assembler), ellentétben a legtöbb népszerű, Intel szintaxist használó assemblerrel.

Hordozható összeszerelők

Létezik egy nyílt assembler projekt is, amelynek különböző operációs rendszerekhez elérhető verziói vannak, és amely lehetővé teszi objektumfájlok beszerzését ezekhez a rendszerekhez. Ezt az összeszerelőt NASM-nek (Netwide Assembler) hívják.
A YASM a NASM újraírt változata, amely a semmiből licencelt (néhány kivételtől eltekintve).
A FASM (Flat Assembler) egy fiatal összeszerelő BSD-licenc alatt, amelyet úgy módosítottak, hogy tiltsa az újraengedélyezést (beleértve a GNU GPL-t is). Vannak KolibriOS, GNU/Linux, MS-DOS és Microsoft Windows verziók, Intel szintaxist használnak és támogatják az AMD64 utasításokat.

RISC architektúrák


MCS-51
AVR
Jelenleg 2 Atmel fordító létezik (AVRStudio 3 és AVRStudio4). A második verzió egy kísérlet a nem túl sikeres első kijavítására. A WinAVR-ben is van assembler.
KAR
AVR32
MSP430
PowerPC

Összeállítás és összeállítás

Az assembly nyelvű program objektumkódra fordításának folyamatát assemblynek nevezzük. Az összeállítással ellentétben az összeállítás többé-kevésbé egyértelmű és visszafordítható folyamat. Az assembly nyelvben minden mnemonika egy gépi utasításnak felel meg, míg a magas szintű programozási nyelvekben nagyszámú különböző utasítás bújhat meg minden kifejezés mögött. Ez a felosztás elvileg meglehetősen önkényes, ezért néha az assembler programok fordítását fordításnak is nevezik.

Assembly nyelv

Assembly nyelv- egyfajta alacsony szintű programozási nyelv, amely a gépi utasítások rögzítésének olyan formátuma, amely kényelmes az emberi érzékelés számára. A rövidség kedvéért gyakran egyszerűen assemblernek nevezik, ami nem igaz.

Az összeállítási nyelvi parancsok egyenként megfelelnek a processzorparancsoknak, és valójában a parancsok és argumentumaik kényelmes szimbolikus jelölési formáját (mnemonikus kódját) képviselik. Az assembly nyelv alapvető szoftveres absztrakciókat is biztosít: programrészek és adatok összekapcsolása szimbolikus névvel ellátott címkéken keresztül (az összeállítás során minden címkéhez címet számítanak ki, amely után a címke minden előfordulását ez a cím helyettesíti) és direktívák.
Az összeállítási direktívák lehetővé teszik (explicit módon leírt vagy fájlból kiolvasott) adatblokkok beillesztését a programba; ismételjen meg egy bizonyos töredéket meghatározott számú alkalommal; állítsa össze a töredéket a feltételnek megfelelően; állítsa be a töredék végrehajtási címét a memóriahely címétől eltérőre [adja meg!]; módosítsa a címkeértékeket az összeállítás során; makródefiníciókat használjon paraméterekkel stb.
Minden processzormodellnek elvileg megvan a maga utasításkészlete és a megfelelő assembly nyelv (vagy dialektus).

Előnyök és hátrányok

Az assembly nyelv előnyei

A redundáns kód minimális mennyisége, vagyis a kevesebb utasítás és memória-hozzáférés használata lehetővé teszi a program sebességének növelését és méretének csökkentését.
A kívánt platform teljes kompatibilitásának és képességeinek maximális kihasználásának biztosítása: a platform speciális utasításainak és műszaki jellemzőinek használata.
Az assemblerben történő programozás során speciális funkciók válnak elérhetővé: közvetlen hozzáférés a hardverhez, az I / O portokhoz és a speciális processzorregiszterekhez, valamint lehetőség van önmódosító kód írására (vagyis metaprogramozásra, szoftveres értelmező nélkül) .
Az operációs rendszerekben megvalósított legújabb biztonsági technológiák nem teszik lehetővé az önmódosító kód készítését, mivel kizárják az utasítások egyidejű végrehajtását és az azonos memóriaterületre történő írást (W^X technológia BSD rendszerekben, DEP Windowsban).

Az assembly nyelv hátrányai

Nagy mennyiségű kód és sok további apró feladat, ami azt eredményezi, hogy a kód nagyon nehezen olvasható és érthetővé válik, és emiatt nehezebb lesz a program hibakeresése és finomítása, valamint a programozás megvalósítása. paradigmák és egyéb konvenciók. ami az együttműködésen alapuló fejlesztés bonyolultságához vezet.
Kevesebb elérhető könyvtár, alacsony a kompatibilitásuk egymással.
Nem hordozható más platformra (a bináris kompatibilis kivételével).

Alkalmazás

Közvetlenül az előnyeiből és hátrányaiból következik.
Mivel rendkívül kényelmetlen nagy programokat assembly nyelven írni, ezért magas szintű nyelveken íródnak. Az assemblerben kis töredékeket vagy modulokat írnak, amelyekhez kritikusak:
teljesítmény (vezetők);
kódméret (boot szektorok, szoftverek korlátozott erőforrásokkal rendelkező mikrokontrollerekhez és processzorokhoz, vírusok, szoftvervédelem);
speciális jellemzők: közvetlen munkavégzés hardverrel vagy gépi kóddal, azaz operációs rendszer betöltőkkel, illesztőprogramokkal, vírusokkal, védelmi rendszerekkel.

Összeállítási kód összekapcsolása más nyelvekkel

Mivel a programnak leggyakrabban csak töredékei íródnak az assemblerben, ezeket össze kell kapcsolni más nyelvű részekkel. Ezt 2 fő módon lehet elérni:
Összeállítási időben- assembler töredékek beillesztése a programba (eng. inline assembler) speciális nyelvi direktívákkal, beleértve az assembler nyelvű írási eljárásokat is. A módszer kényelmes az egyszerű adattranszformációkhoz, de teljes értékű assembler kód, adatokkal és szubrutinokkal, beleértve a sok bemenettel és kimenettel rendelkező, magas szintű nyelvek által nem támogatott szubrutinokat, nem végezhető vele.
Építési szakaszban, vagy külön összeállítás. Az összekapcsoló modulok interakciójához elegendő, ha az összekapcsolási funkciók támogatják a szükséges hívási konvenciókat és adattípusokat. Külön modulok írhatók bármilyen nyelven, beleértve az assembly nyelvet is.

Szintaxis

Az assembly nyelvek szintaxisára nincs általánosan elfogadott szabvány. Vannak azonban olyan szabványok, amelyeket a legtöbb assembly nyelvi fejlesztő betart. A fő ilyen szabványok az Intel szintaxis és az AT&T szintaxis.

Utasítás

Az utasítások írásának általános formátuma mindkét szabvány esetében azonos:

[címke:] opcode [operandusok] [;megjegyzés]

ahol az opcode közvetlenül a processzornak szóló utasítás emlékeztetője. Előtagok adhatók hozzá (ismétlések, címzéstípus változtatások stb.).
Az operandusok lehetnek konstansok, regiszternevek, RAM-címek stb. Az Intel és az AT&T szabványok közötti különbségek főként az operandusok felsorolásának sorrendjében és a különböző címzési módszerek szintaxisában vannak.
A használt mnemonikák általában ugyanazok az azonos architektúrájú vagy architektúracsalád összes processzoránál (a széles körben ismert mnemonikák közé tartoznak a Motorola, ARM, x86 processzorok és vezérlők). Ezek leírása a processzor specifikációjában található. Lehetséges kivételek:
Ha az assembler platformok közötti AT&T szintaxist használ (az eredeti mnemonikat AT&T szintaxisra konvertálják)
Ha kezdetben két szabvány volt a mnemonika írására (az utasításrendszert egy másik gyártó processzorától örökölték).
Például a Zilog Z80 processzor megörökölte az Intel i8080 utasításkészletét, kibővítette, és a maga módján megváltoztatta a mnemonikát (és a regisztermegnevezéseket). Például az Intel mov-ját ld-re cseréltem. A Motorola Fireball processzorai megörökölték a Z80-as utasításkészletet, kicsit lefaragva. A Motorola azonban hivatalosan is visszatért az Intel mnemonikájához. És jelenleg a Fireball összeszerelők fele Intel, fele pedig Zilog mnemonikával dolgozik.

irányelveket

Az utasításokon kívül a program tartalmazhat direktívákat: olyan parancsokat, amelyek nem fordítódnak közvetlenül gépi utasításokká, hanem a fordító működését vezérlik. Beállításuk és szintaxisuk jelentősen eltér, és nem a hardverplatformtól, hanem a használt fordítótól függ (ami az azonos architektúracsaládon belüli nyelvek dialektusait eredményezi). Az irányelvek "úri halmazaként" kiemelhetjük:
adatok meghatározása (állandók és változók)
a program memóriában való szervezésének és a kimeneti fájl paramétereinek kezelése
a fordítómód beállítása
mindenféle absztrakció (azaz magas szintű nyelvek elemei) - az eljárások és funkciók tervezésétől (a procedurális programozási paradigma megvalósításának egyszerűsítése érdekében) a feltételes struktúrákig és ciklusokig (a strukturált programozási paradigmához)
makrók

Program példa

Példa egy Hello world programra MS-DOS-hoz x86 architektúrához a TASM dialektusban:

.MODEL TINY CODE SZEGMENT TÉTELEZÉS CS:CODE, DS:CODE ORG 100h START: mov ah,9 mov dx,OFFSET Üzenet int 21h int 20h Üzenet DB "Hello World",13,10,"$" KÓD VÉGE VÉGE KEZDE

Az „assembly language” kifejezés eredete és kritikája

Ez a nyelvtípus az ezekből a nyelvekből származó fordító (fordító) nevéből kapta a nevét - assembler (angol assembler - assembler). Utóbbi elnevezése annak köszönhető, hogy az első számítógépeken nem voltak magasabb szintű nyelvek, és az assembler segítségével történő programkészítés egyetlen alternatívája a közvetlen kódokban történő programozás volt.
Az orosz összeszerelési nyelvet gyakran "összeszerelőnek" (és valami ehhez kapcsolódónak - "összeszerelőnek") nevezik, ami a szó angol fordítása szerint helytelen, de beleillik az orosz nyelv szabályaiba. Magát az assemblert (programot) azonban egyszerűen "assembler"-nek is nevezik, nem pedig "assembler nyelvi fordítónak" stb.
Az „assembly language” kifejezés használata is ahhoz a tévhithez vezethet, hogy egyetlen alacsony szintű nyelv létezik, vagy legalábbis az ilyen nyelvek szabványa. Az adott program megírásának nyelvének megnevezésénél kívánatos megadni, hogy melyik architektúrára szánják, és a nyelv melyik dialektusában írják.