Internet Windows Android

Sistem de operare asamblator. Școala de asamblare: Dezvoltarea sistemului de operare

Recent m-am hotărât să învăț assembler, dar nu eram interesat să irosesc linii de cod. M-am gândit că, pe măsură ce învăț asamblare, voi stăpâni o anumită materie. Deci, alegerea mea a căzut pe scrierea unui bootloader. Rezultatul descoperirilor mele este aici pe acest blog.

Aș vrea să spun imediat că îmi place teoria combinată cu practica, așa că să începem.

În primul rând, vă voi arăta cum să creați cel mai simplu MBR astfel incat sa ne bucuram de rezultat in cel mai scurt timp posibil. Pe măsură ce complicăm exemplele practice, voi oferi informații teoretice.

Mai întâi, să facem un bootloader pentru stick-ul USB!

Atenţie!!! Primul nostru program de asamblare va funcționa atât pentru o unitate flash USB, cât și pentru alte dispozitive precum Floppy - disc sau Hard disk. Ulterior, pentru ca toate exemplele să funcționeze corect, voi oferi o serie de clarificări cu privire la modul în care funcționează codul pe diferite dispozitive.

Vom scrie mai departe Fasm, deoarece el este considerat cel mai bun compilator pentru scrierea încărcătoarelor, adică MBR. Al doilea motiv pentru a alege Fasm este că simplifică foarte mult procesul de compilare a fișierelor. Fără directive de linie de comandă etc. prostii care pot descuraja complet pe asamblatorul care învață și să ne atingă obiectivele. Deci, la etapa inițială, avem nevoie de două programe și câteva inutil Unitate flash USB de dimensiune minimă. Am dezgropat 1Gb de la mine (este format rapid și nu e păcat, dacă asta). După munca bootloader-ului nostru, unitatea flash nu va mai funcționa normal. Windows-ul meu 7 refuză să-mi formateze stick-ul. Vă sfătuiesc să readuceți la viață unitatea flash cu utilitarul Instrument de formatare de stocare pe disc HP USB ( HPUSBFW.EXE) sau alte utilitare pentru formatarea unităților flash.

Le instalăm și aruncăm comenzile rapide corespunzătoare pe desktop sau oriunde doriți.

Pregătirea s-a terminat, să trecem la acțiune

Deschideți Fasmw.exe și scrieți următoarele acolo. Vom schița strictul minim de cod pentru a vedea rezultatul. Mai târziu vom analiza ce este cald aici. Pe scurt, dau comentarii.

Cod FASM: ============== boot.asm ==============

org 7C00h; adresele programului nostru sunt calculate ținând cont de această directivă

utilizare16; se generează un cod hexazecimal

cli; dezactivați întreruperile pentru schimbarea adreselor în registrele de segmente

mov ax, 0

mov sp, 7C00h

sti; activați întreruperi (după schimbarea adreselor)

mov ax, 0003h; setarea modului video pentru afișarea unei linii pe ecran

int 10h

mov ax, 1301h; de fapt, ieșirea funcției șir 13h int 10h (mai detaliat mai târziu)

mov bp, stroka; adresa liniei de ieșire

mov dx, 0000h; linia și coloana în care este afișat textul

mov cx, 15; numărul de caractere din șirul de ieșire

mov bx, 000eh; 00-număr de pagină video (mai bine să nu atingeți) 0e-caracter atribute (culoare, fundal)

int 10h

jmp $; marcați timpul (în bucla programul în acest moment)

stroka db "Ok, MBR încărcat!"

ori 510 - ($ - $$) db 0; umplerea cu zerouri a decalajului dintre octetul anterior și ultimul

db 0x55, 0xAA; ultimii doi octeți

Compilați acest cod (Ctrl + F9) în fasm "e și salvați fișierul binar rezultat ca boot.bin undeva convenabil. Înainte de a scrie binarul nostru pe o unitate flash USB, puțină teorie.

Când ați conectat unitatea flash USB la computer, pentru sistemul BIOS nu este absolut evident că doriți să porniți de pe unitatea flash USB, așa că în setările BIOS trebuie să selectați dispozitivul de pe care doriți să porniți. a ales să pornească de pe USB (va trebui să vă dați seama cum să faceți acest lucru singur, deoarece interfața BIOS are diferite variante... puteți căuta pe Google setările BIOS pentru placa dvs. de bază. Nu este nimic complicat, de regulă).

Acum că BIOS-ul știe că doriți să porniți de pe unitatea flash, trebuie să se asigure că sectorul zero de pe unitatea flash este bootabil. Pentru a face acest lucru, BIOS-ul se uită la ultimii doi octeți ai sectorului zeroși, dacă sunt egale cu 0x55 0xAA, atunci numai atunci va fi încărcat în RAM. În caz contrar, BIOS-ul va trece doar pe lângă unitatea flash. După ce a găsit acești doi octeți magici, el încarcă sectorul zero în RAM la adresa 0000: 7C00h, apoi uită de unitatea flash USB și transferă controlul la această adresă. Acum toată puterea asupra computerului aparține bootloader-ului și acesta, acționând deja din RAM, poate încărca cod suplimentar de pe unitatea flash. Acum vom vedea cum arată acest sector în programul DMDE.

1. Introduceți unitatea flash USB în computer și asigurați-vă că nu conține informațiile de care aveți nevoie.

2. Deschideți programul DMDE. Citiți toate acțiunile suplimentare din cifre:

După ce vizionați această benzi desenate, veți avea abilitatea de a descărca MBR-ul dvs. pe o unitate flash USB. Și așa arată rezultatul mult așteptat al lucrării bootloader-ului nostru:


Apropo, dacă vorbim despre codul minim de bootloader, atunci ar putea arăta astfel:

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

Un astfel de încărcător, după ce a primit controlul, pur și simplu închide computerul, executând o comandă fără sens jmp $ într-o buclă. O numesc timpul de marcare.

Am postat un videoclip pe YouTube care te poate ajuta:

În cele din urmă, câteva fapte rapide despre bootloader:

1. Bootloader, cunoscut și sub numele de bootloader, cunoscut și sub numele de MBR, are o dimensiune de 512 octeți. Din punct de vedere istoric,
că această condiție trebuie îndeplinită pentru a suporta medii și dispozitive mai vechi.
2. Încărcătorul este întotdeauna situat în sectorul zero al unei unități flash, dischete, hard disk, din punctul de vedere al programului DMDE sau al altor editori hexadecimale care vă permit să lucrați cu dispozitive. Pentru a descărca binarul (boot.bin-ul nostru) pe unul dintre dispozitivele enumerate, nu trebuie să ne gândim la structura lor fizică internă. Programul DMDE știe doar să citească sectoarele de pe aceste dispozitive și le afișează în modul LBA (doar le numește de la 0 la ultimul sector). Puteți citi despre LBA
3. Bootloader-ul trebuie să se termine întotdeauna cu doi octeți 0x55 0xAA.
4. Încărcătorul este întotdeauna încărcat în memorie la adresa 0000: 7C00h.
5. Sistemul de operare începe cu bootloader-ul.


Spun imediat, nu închide articolul cu gândurile „La naiba, un alt Popov”. Are doar un Ubuntu lins și am totul de la zero, inclusiv nucleul și aplicațiile. Deci, continuarea sub tăietură.

grup OS: Aici.
Îți voi da mai întâi o captură de ecran.

Nu mai există, iar acum mai detaliat despre motivul pentru care îl scriu.

Era o seară caldă de aprilie, joi. Încă din copilărie, visam să scriu un sistem de operare, când mă gândeam brusc: „Acum știu argumentele pro și contra, de ce să nu-mi devin visul?” Am căutat pe Google pe acest subiect și am găsit un articol de la Habr: „Cum să începi și să nu renunți la scrierea sistemului de operare”. Mulțumim autorului pentru link-ul către OSDev Wiki de mai jos. M-am dus acolo și am început munca. Erau într-un articol toate datele despre sistemul de operare minim. Am început să construiesc cross-gcc și binutils și apoi am rescris totul de acolo. Ar fi trebuit să-mi vezi bucuria când am văzut inscripția „Hello, kernel World!” Am sărit chiar de pe scaun și mi-am dat seama - nu voi renunța. Am scris „consola” (între ghilimele, nu aveam acces la tastatură), dar apoi am decis să scriu un sistem de ferestre. Drept urmare, a funcționat, dar nu am avut acces la tastatură. Și apoi am decis să vin cu un nume bazat pe sistemul X Window. Googled Y Window System - este. Drept urmare, am numit Z Window System 0.1, inclus în OS365 pre-alpha 0.1. Și da, nimeni nu a văzut-o în afară de mine. Apoi mi-am dat seama cum să implementez suportul pentru tastatură. Captură de ecran a primei versiuni, când încă nu era nimic, nici măcar sistemul de ferestre:

Cursorul de text nici măcar nu s-a deplasat în el, după cum puteți vedea. Apoi am scris câteva aplicații simple bazate pe Z. Și aici vine versiunea 1.0.0 alfa. Au fost o mulțime de lucruri, chiar și meniul de sistem. Și managerul de fișiere și calculatorul pur și simplu nu au funcționat.

Am fost terorizat direct de un prieten căruia îi pasă numai de frumusețe (Mitrofan, scuze). El a spus: „L-am coborât la modul VBE 1024 * 768 * 32, l-am coborât, l-am coborât! Ei bine, bea-l jos!” Ei bine, deja m-am săturat să-l ascult și totuși l-am spălat. Despre implementarea de mai jos.

Am făcut totul bootloader-ul meu, și anume GRUB. Cu el, poți seta modul grafic fără complicații adăugând câteva linii magice la antetul Multiboot.

Setați 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
Și apoi din structura de informații Multiboot iau adresa framebuffer-ului și rezoluția ecranului și scriu pixeli acolo. VESA a făcut totul foarte confuz - culorile RGB trebuie introduse în ordine inversă (nu R G B, ci B G R). De câteva zile nu am înțeles - de ce pixelii nu sunt afișați!? Drept urmare, mi-am dat seama că am uitat să schimb valorile a 16 constante de culoare de la 0 ... 15 la echivalentele lor RGB. Drept urmare, am eliberat, în același timp am spălat fundalul gradient. Apoi am făcut o consolă, 2 aplicații și am lansat 1.2. Da, aproape am uitat - puteți descărca sistemul de operare de la

Original: AsmSchool: Creați un sistem de operare
Autor: Mike Saunders
Data publicării: 15 aprilie 2016
Traducere: A. Panin
Data transferului: 16 aprilie 2016

Partea 4: Cu abilitățile pe care le-ați învățat din articolele anterioare din serie, puteți începe să vă dezvoltați propriul sistem de operare!

Pentru ce este?

  • Pentru a înțelege cum funcționează compilatoarele.
  • Pentru a înțelege instrucțiunile CPU.
  • Pentru a vă optimiza codul pentru performanță.

De-a lungul mai multor luni, am trecut printr-o cale dificilă, care a început cu dezvoltarea unor programe simple în limbaj de asamblare pentru Linux și s-a încheiat în ultimul articol al seriei cu dezvoltarea unui cod autosuficient, care rulează pe un sistem personal. computer fără sistem de operare. Ei bine, acum vom încerca să colectăm toate informațiile împreună și să creăm un sistem de operare real. Da, vom merge pe urmele lui Linus Torvalds, dar mai întâi merită să răspundem la următoarele întrebări: "Ce este un sistem de operare? Pe care dintre funcțiile lui va trebui să recreăm?"

În acest articol, ne vom concentra doar pe principalele funcții ale sistemului de operare: încărcarea și executarea programelor. Sistemele de operare complexe îndeplinesc mult mai multe funcții, cum ar fi managementul memoriei virtuale și procesarea pachetelor de rețea, dar necesită ani de funcționare continuă pentru a fi implementate corect, așa că în acest articol vom acoperi doar funcțiile de bază care sunt prezente în orice sistem de operare. Luna trecută am dezvoltat un mic program care se încadrează într-un sector de 512 octeți al unei dischete (primul său sector), iar acum îl vom modifica ușor pentru a adăuga funcția de încărcare a datelor suplimentare de pe disc.

Dezvoltare încărcător de pornire

Am putea încerca să reducem cât mai mult dimensiunea codului binar al sistemului nostru de operare pentru a-l plasa în primul sector de 512 octeți al unei dischete, același care se încarcă prin BIOS, dar în acest în cazul în care nu vom putea implementa nicio funcție interesantă. Prin urmare, vom folosi acești 512 octeți pentru a găzdui codul binar al unui bootloader simplu care va încărca codul binar al nucleului OS în RAM și îl va executa. (După aceea, vom dezvolta însuși nucleul sistemului de operare, care va încărca codul binar al altor programe de pe disc și, de asemenea, îl va executa, dar acest lucru va fi discutat puțin mai târziu.)

Puteți descărca codul sursă pentru exemplele discutate în acest articol de la www.linuxvoice.com/code/lv015/asmschool.zip. Și acesta este codul nostru de încărcare de pornire dintr-un fișier numit boot.asm:

BITS 16 jmp pornire scurtă; Salt la etichetă săriți disc descriere nop; Adăugarea înainte de descrierea discului% include "bpb.asm" start: mov ax, 07C0h; Adresă de încărcare mov ds, ax; Segment de date mov ax, 9000h; Pregătiți stiva mov ss, axe mov sp, 0FFFFh; Stiva crește în jos! cld; Direction flag setting mov si, kern_filename call load_file jmp 2000h: 0000h; Salt la codul binar al nucleului sistemului de operare încărcat din fișierul kern_filename db „MYKERNELBIN”% include „disk.asm” ori 510 - ($ - $$) db 0; Completarea codului binar cu zerouri până la 510 octeți dw 0AA55h; Bufferul etichetei de sfârșit de cod binar al bootloaderului:; Pornirea tamponului pentru conținutul discului

În acest cod, prima instrucțiune CPU este instrucțiunea jmp, care se află după directiva BITS care spune asamblatorului NASM să folosească modul pe 16 biți. După cum probabil vă amintiți din articolul anterior din serie, execuția unui cod binar de 512 de octeți încărcat cu ajutorul BIOS-ului de pe disc începe de la bun început, dar trebuie să mergem la etichetă pentru a sări peste un set special de date. Evident, luna trecută tocmai am scris codul la începutul discului (folosind utilitarul dd) și am lăsat restul spațiului pe disc gol.

Acum trebuie să folosim o dischetă cu un sistem de fișiere MS-DOS adecvat (FAT12), iar pentru a funcționa corect cu acest sistem de fișiere, trebuie să adăugăm un set de date speciale aproape de începutul sectorului. Acest set se numește BIOS Parameter Block (BPB) și conține informații precum eticheta discului, numărul de sectoare și așa mai departe. Nu ar trebui să ne intereseze în această etapă, deoarece mai mult de o serie de articole pot fi dedicate unor astfel de subiecte, motiv pentru care am plasat toate instrucțiunile și datele aferente într-un fișier separat de cod sursă numit bpb.asm.

Pe baza celor de mai sus, această directivă din codul nostru este extrem de importantă:

% includ „bpb.asm”

Aceasta este o directivă NASM care permite ca conținutul unui fișier sursă specificat să fie inclus în fișierul sursă curent în timpul asamblarii. Astfel, vom putea face codul bootloader-ului nostru cât mai scurt și ușor de înțeles posibil, după ce am scos toate detaliile implementării blocului de parametri BIOS într-un fișier separat. Blocul parametrilor BIOS ar trebui să fie localizat la trei octeți după începutul sectorului și, deoarece instrucțiunea jmp ia doar doi octeți, trebuie să folosim instrucțiunea nop (numele ei înseamnă „nicio operație” - aceasta este o instrucțiune care nu face nimic cu excepția ciclurilor CPU uzate ) pentru a completa octetul rămas.

Lucrul cu stiva

În continuare, va trebui să folosim instrucțiuni similare cu cele discutate în articolul anterior pentru a pregăti registrele și stiva, precum și instrucțiunea cld (subsemnează „direcție clară”), care vă permite să setați pavilionul de direcție pentru anumite instrucțiuni, precum instrucțiunea lodsb, care după executarea ei va crește valoarea în registrul SI, nu o scade.

După aceea, punem adresa șirului în registrul SI și apelăm funcția load_file. Dar gândiți-vă un minut - încă nu am dezvoltat această funcție! Da, este adevărat, dar implementarea sa poate fi găsită într-un alt fișier sursă pe care îl includem, numit disk.asm.

Sistemul de fișiere FAT12 folosit pe dischetele care sunt formatate în MS-DOS este unul dintre cele mai simple sisteme de fișiere existente, dar necesită și mult cod pentru a lucra cu conținutul său. Subrutina load_file are aproximativ 200 de linii și nu va fi prezentată în acest articol, deoarece luăm în considerare procesul de dezvoltare a unui sistem de operare și nu un driver pentru un anumit sistem de fișiere, prin urmare, nu este foarte rezonabil să pierdem spațiu pe paginile jurnalului în acest fel. În general, am inclus fișierul sursă disk.asm aproape înainte de sfârșitul fișierului sursă curent și putem uita de el. (Dacă sunteți încă interesat de structura sistemului de fișiere FAT12, puteți consulta o prezentare generală excelentă la http://tinyurl.com/fat12spec, apoi căutați fișierul sursă disk.asm - codul conținut în acesta este bine comentat .)

În orice caz, subrutina load_file încarcă codul binar din fișierul cu numele specificat în registrul SI în segmentul 2000 cu un offset de 0, după care sărim la începutul său pentru execuție. Și asta este tot - nucleul sistemului de operare este încărcat și încărcătorul de pornire și-a făcut treaba!

Poate ați observat că codul nostru folosește MYKERNELBIN ca nume al fișierului kernel al sistemului de operare în loc de MYKERNEL.BIN, care se potrivește bine cu schema de denumire 8 + 3 folosită pe dischetele DOS. De fapt, sistemul de fișiere FAT12 utilizează reprezentarea internă a numelor de fișiere și economisim spațiu utilizând un nume de fișier, care este garantat că nu va necesita implementarea unui mecanism în cadrul subrutinei noastre load_file pentru a găsi caracterul punct și a converti numele fișierului. la reprezentarea sistemului de fișiere intern.

După linia cu directiva de conectare a fișierului de cod sursă disk.asm, există două linii destinate să completeze codul binar al încărctorului de pornire cu zerouri până la 512 octeți și să includă marcajul final al codului său binar (acest lucru a fost discutat în ultimul articol). În cele din urmă, la sfârșitul codului se află eticheta „buffer”, care este folosită de subrutina load_file. În general, subrutina load_file necesită spațiu liber în RAM pentru a efectua niște pași intermediari în procesul de căutare a unui fișier pe disc și avem suficient spațiu liber după încărcarea bootloader-ului, așa că plasăm buffer-ul aici.

Pentru a asambla încărcătorul de pornire, utilizați următoarea comandă:

Nasm -f bin -o boot.bin boot.asm

Acum trebuie să creăm o imagine de dischetă virtuală în format MS-DOS și să adăugăm codul binar al bootloader-ului nostru la primii 512 octeți folosind următoarele comenzi:

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

Acest lucru completează procesul de dezvoltare a încărcător de pornire! Acum avem o imagine de dischetă de pornire care ne permite să încărcăm nucleul binar al sistemului de operare dintr-un fișier numit mykernel.bin și să-l executăm. În continuare, ne așteaptă o parte mai interesantă a lucrării - dezvoltarea nucleului sistemului de operare în sine

Nucleul sistemului de operare

Dorim ca nucleul sistemului nostru de operare să îndeplinească multe sarcini importante: afișarea unui salut, acceptarea intrării de la utilizator, determinarea dacă intrarea este o comandă acceptată și executarea programelor de pe disc după ce utilizatorul le specifică numele. Acesta este codul nucleului sistemului de operare din fișierul mykernel.asm:

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, si mov cx, 32768 call lib_load_file jc load_fail apel 32768 jmp loop load_fail: mov si, load_fail_msg call lib_print_string jmp loop list_files: mov si, file_list apel lib_get_file_list apel lib_print_string jmp loop prompt db 13, 10, "MyOS>", 0 ori user_10, 10, 10, 2000 256 db 0 file_list ori 1024 db 0% include" lib.asm "

Înainte de a privi codul, ar trebui să fiți atenți la ultima linie cu directiva de a include fișierul cod sursă lib.asm, care se află și în arhiva asmschool.zip de pe site-ul nostru. Aceasta este o bibliotecă de rutine utile pentru lucrul cu ecranul, tastatura, șirurile de caractere și discurile pe care le puteți utiliza și - în acest caz, includem acest fișier de cod sursă la sfârșitul fișierului sursă principal al nucleului sistemului de operare, în ordine pentru a-l face pe acesta din urmă cât mai compact și frumos posibil... Consultați secțiunea „Rutine lib.asm” pentru mai multe informații despre toate rutinele disponibile.

În primele trei rânduri ale codului nucleului sistemului de operare, umplem registrele de segment cu date pentru a indica segmentul 2000, în care a fost încărcat codul binar. Acest lucru este important pentru a vă asigura că instrucțiunile precum lodsb funcționează corect, care ar trebui să citească datele din segmentul curent și nu din orice alt segment. După aceea, nu vom efectua operații suplimentare cu segmente; sistemul nostru de operare va rula cu 64 KB de RAM!

Mai departe în cod este eticheta corespunzătoare începutului buclei. În primul rând, folosim una dintre rutinele bibliotecii lib.asm, lib_print_string, pentru a imprima salutul. Octeții 13 și 10 dinaintea liniei de salut sunt caractere newline, astfel încât salutul nu va fi afișat imediat după ieșirea oricărui program, ci întotdeauna pe o nouă linie.

Folosim apoi o altă subrutină lib.asm numită lib_input_string, care preia caracterele introduse de utilizator folosind tastatura și le stochează într-un buffer indicat în registrul SI. În cazul nostru, tamponul este declarat aproape de sfârșitul codului kernel-ului sistemului de operare, după cum urmează:

User_input ori 256 db 0

Această declarație vă permite să creați un buffer de 256 de caractere plin cu zerouri - trebuie să fie suficient de lung pentru a stoca comenzi pentru un sistem de operare simplu ca al nostru!

Apoi, validăm intrarea utilizatorului. Dacă primul octet al buffer-ului user_input este zero, atunci utilizatorul a apăsat pur și simplu tasta Enter fără a introduce nicio comandă; nu uitați că toate șirurile sunt terminate cu nul. Deci, în acest caz, trebuie doar să mergem la începutul buclei și să imprimăm din nou salutul. Totuși, în cazul în care utilizatorul introduce orice comandă, va trebui mai întâi să verificăm dacă a introdus comanda ls. Până acum, ați văzut doar comparații de octeți individuali în programele noastre de limbaj de asamblare, dar nu uitați că este posibil să comparați și valori de doi octeți sau cuvinte de mașină. În acest cod, comparăm primul cuvânt mașină din buffer-ul user_input cu cuvântul mașină corespunzător liniei ls și, dacă sunt identice, trecem la blocul de cod de mai jos. În cadrul acestui bloc de cod, folosim o altă subrutină din lib.asm pentru a obține o listă de fișiere separate prin virgulă de pe disc (care trebuie să fie stocată în buffer-ul file_list), afișăm acea listă și revenim la bucla pentru a procesa intrarea utilizatorului .

Executarea de programe terțe

Dacă utilizatorul nu introduce comanda ls, presupunem că a introdus numele programului de pe disc, așa că are sens să încercăm să-l încărcați. Biblioteca noastră lib.asm conține o implementare a unei subrutine utile lib_load_file, care analizează tabelele sistemului de fișiere FAT12 de pe un disc: acceptă un pointer către începutul unei linii cu un nume de fișier folosind registrul AX, precum și o valoare offset pentru încărcarea codului binar din fișierul program folosind registrul CX. Folosim deja registrul SI pentru a stoca un pointer către șirul de intrare de utilizator, așa că copiem acel pointer în registrul AX și apoi punem valoarea 32768, folosită ca offset pentru încărcarea binarului din fișierul de program, în CX Inregistreaza-te.

Dar de ce folosim această valoare specială ca o compensare pentru încărcarea codului binar din fișierul program? Ei bine, aceasta este doar una dintre opțiunile hărții de memorie pentru sistemul nostru de operare. Datorită faptului că lucrăm într-un segment de 64 KB, iar codul binar al nucleului nostru este încărcat la offset 0, trebuie să folosim primii 32 KB de memorie pentru datele kernelului și restul de 32 KB pentru date. a programelor încărcate. Astfel, offset 32768 este mijlocul segmentului nostru și ne permite să oferim suficientă RAM atât pentru nucleul sistemului de operare, cât și pentru programele încărcate.

După aceea, subrutina lib_load_file efectuează o operație extrem de importantă: dacă nu poate găsi un fișier cu numele specificat pe disc sau, dintr-un motiv oarecare, nu poate să-l citească de pe disc, pur și simplu iese și setează un flag de transport special. Acesta este un steag al stării procesorului central, care este setat în procesul de efectuare a unor operații matematice și în acest moment nu ar trebui să ne intereseze, dar în același timp putem determina prezența acestui steag pentru a lua decizii rapide. Dacă lib_load_asm setează indicatorul de transport, folosim instrucțiunea jc (jump if carry) pentru a sări la blocul de cod care imprimă mesajul de eroare și revine la începutul buclei de introducere a utilizatorului.

În același caz, dacă flag-ul de transport nu este setat, putem concluziona că subrutina lib_load_asm a încărcat cu succes codul binar din fișierul program în RAM la adresa 32768. Tot ce avem nevoie în acest caz este să inițiem execuția binarului. cod încărcat la această adresă, adică începeți executarea programului specificat de utilizator! Și după ce acest program folosește instrucțiunea ret (pentru a reveni la codul de apel), trebuie doar să revenim la bucla de procesare a intrărilor utilizatorului. Astfel, am creat un sistem de operare: este format din cele mai simple mecanisme de parsare a comenzilor și de încărcare a programelor, implementate în aproximativ 40 de linii de cod de asamblare, deși cu mult ajutor de la subrutinele din biblioteca lib.asm.

Pentru a asambla codul nucleului sistemului de operare, utilizați următoarea comandă:

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

După aceea, va trebui să adăugăm cumva fișierul mykernel.bin la fișierul imagine pe dischetă. Dacă sunteți familiarizat cu montarea imaginilor de disc folosind dispozitive loopback, puteți accesa conținutul imaginii de disc floppy.img folosindu-l, dar există o modalitate mai ușoară, și anume să utilizați setul de instrumente GNU Mtools (www.gnu.org/software). / mtools). Acesta este un set de programe pentru lucrul cu dischete care utilizează sistemele de fișiere MS-DOS / FAT12, disponibile din depozitele de pachete software ale tuturor distribuțiilor Linux populare, așa că trebuie doar să utilizați utilitarul apt-get, yum, pacman sau orice alt utilitar folosit pentru a instala pachete software în distribuția dvs.

După instalarea pachetului software corespunzător, va trebui să rulați următoarea comandă pentru a adăuga fișierul mykernel.bin la fișierul imagine de disc floppy.img:

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

Observați personajele amuzante de la sfârșitul comenzii: două puncte, două puncte și bară oblică. Acum suntem aproape gata să lansăm sistemul nostru de operare, dar ce rost are când încă nu există aplicații pentru acesta? Să remediem această neînțelegere dezvoltând o aplicație extrem de simplă. Da, acum vei dezvolta o aplicație pentru propriul tău sistem de operare - doar imaginează-ți cât de mult va crește autoritatea în rândurile tocilor. Salvați următorul cod într-un fișier numit test.asm:

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

Acest cod folosește pur și simplu o funcție BIOS pentru a afișa caracterul „X” pe ecran și apoi readuce controlul la codul care l-a numit - în cazul nostru, acest cod este codul sistemului de operare. Linia organizatorică, cu care începe codul sursă al aplicației, nu este o instrucțiune de la procesorul central, ci o directivă a asamblatorului NASM care îi spune că codul binar va fi încărcat în RAM la offset-ul 32768, prin urmare, este necesar să se recalculeze toate compensațiile ținând cont de această circumstanță.

Acest cod trebuie, de asemenea, asamblat, iar fișierul binar rezultat trebuie adăugat la fișierul imagine pe dischetă:

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

Acum respirați adânc, pregătiți-vă să contemplați rezultatele de neegalat ale propriei tale lucrări și încărcați imaginea de pe dischetă folosind un emulator de computer, cum ar fi Qemu sau VirtualBox. De exemplu, următoarea comandă poate fi utilizată în acest scop:

Qemu-system-i386 -fda floppy.img

Voila: bootloader-ul boot.img, pe care l-am integrat în primul sector al imaginii de disc, încarcă nucleul sistemului de operare mykernel.bin, care afișează un mesaj de bun venit. Introduceți comanda ls pentru a obține numele a două fișiere aflate pe disc (mykernel.bin și test.bin), apoi introduceți numele ultimului fișier pentru a-l executa și afișa un X pe ecran.

E tare, nu-i așa? Acum puteți începe să modificați shell-ul sistemului de operare, să adăugați noi implementări de comenzi și să adăugați fișiere de program suplimentare pe disc. Dacă doriți să rulați acest sistem de operare pe un computer real, ar trebui să vă referiți la secțiunea „Running the Boot Loader on a Real Hardware Platform” din articolul anterior din serie - veți avea nevoie de exact aceleași comenzi. Luna viitoare, vom face sistemul nostru de operare mai puternic, permițând programelor descărcabile să folosească funcțiile sistemului și implementând astfel conceptul de partajare a codului pentru a reduce dublarea. Majoritatea lucrărilor sunt încă înainte.

Rutine de bibliotecă Lib.asm

După cum am menționat mai devreme, lib.asm oferă un set mare de rutine utile pentru utilizare în nucleele sistemului de operare și în programele individuale. Unii dintre ei folosesc instrucțiuni și concepte care nu au fost încă atinse în articolele acestei serii, altele (cum ar fi rutinele pentru lucrul cu discuri) sunt strâns legate de particularitățile structurii sistemelor de fișiere, dar dacă vă considerați competent în aceste chestiuni, vă puteți citi cu implementările lor și puteți înțelege principiul de lucru. Acestea fiind spuse, este mai important să vă dați seama cum să le apelați din propriul cod:

  • lib_print_string - Preia un pointer către un șir terminat cu nul prin registrul SI și tipărește acel șir pe ecran.
  • lib_input_string - Acceptă un pointer către un buffer prin registrul SI și umple acest buffer cu caractere introduse de utilizator folosind tastatura. După ce utilizatorul apasă tasta Enter, linia din buffer este terminată nul și controlul revine la codul programului apelant.
  • lib_move_cursor - Mută ​​cursorul pe ecran în poziția cu coordonatele trecute prin registrele DH (număr de linie) și DL (număr de coloană).
  • lib_get_cursor_pos - această subrutină ar trebui apelată pentru a obține numerele rândului și coloanei curente prin registrele DH și, respectiv, DL.
  • lib_string_uppercase - Ia un pointer la începutul unui șir terminat cu nul prin registrul AX și convertește caracterele din șir în majuscule.
  • lib_string_length - Ia un pointer la începutul unui șir terminat cu nul prin registrul AX și returnează lungimea acestuia prin registrul AX.
  • lib_string_compare - Preia indicatori la începutul a două șiruri terminate nul prin registrele SI și DI și compară șirurile. Setează indicatorul de transport dacă liniile sunt identice (pentru a utiliza o instrucțiune de ramificare în funcție de flagul de transport jc) sau șterge acest indicator dacă liniile sunt diferite (pentru a folosi instrucțiunea jnc).
  • lib_get_file_list - Ia un pointer la începutul buffer-ului prin registrul SI și plasează un șir terminat cu nul în buffer care conține o listă de nume de fișiere separate prin virgulă de pe disc.
  • lib_load_file - duce un pointer la începutul liniei care conține numele fișierului prin registrul AX și încarcă conținutul fișierului la offset-ul trecut prin registrul CX. Returnează numărul de octeți copiați în memorie (adică dimensiunea fișierului) folosind registrul BX sau setează indicatorul de transport dacă nu este găsit un fișier cu numele dat.

Astăzi există un exemplu curios în Cabinetul nostru de Curiozități - un sistem de operare scris în pur asamblator. Împreună cu drivere, un shell grafic, zeci de programe și jocuri preinstalate, este nevoie de mai puțin de un megaoctet și jumătate. Faceți cunoștință cu sistemul de operare „Kolibri” excepțional de rapid și predominant rus.

Dezvoltarea „Kolibri” a mers destul de repede până în 2009. Pasărea a învățat să zboare pe hardware diferit, necesitând minimum primul Pentium și opt megaocteți de memorie RAM. Cerințele minime de sistem pentru Hummingbird sunt:

  • CPU: Pentium, AMD 5x86 sau Cyrix 5x86 fără MMX @ 100 MHz;
  • RAM: 8 MB;
  • placă video: compatibilă VESA cu suport pentru modul VGA (640 × 480 × 16).

Modern „Hummingbird” este o „build de noapte” actualizată în mod regulat a ultimei versiuni oficiale, lansată la sfârșitul anului 2009. Am testat versiunea 0.7.7.0+ din 20 august 2017.

AVERTIZARE

În setările implicite, KolibriOS nu are acces la discuri care sunt vizibile prin BIOS. Gândiți-vă bine și faceți o copie de rezervă înainte de a schimba această setare.

Modificările în construcțiile nocturne, deși mici, s-au acumulat suficient de-a lungul anilor. „Kolibri” actualizat poate scrie în partițiile FAT16–32 / ext2 - ext4 și acceptă alte sisteme de fișiere populare (NTFS, XFS, ISO-9660) în modul de citire. A adăugat suport pentru carduri USB și de rețea, a adăugat o stivă TCP / IP și codecuri audio. În general, poți deja să faci ceva în el și nu doar să te uiți o dată la un sistem de operare ultraușor cu o interfață grafică și să fii impresionat de viteza de lansare.



Ca și versiunile anterioare, cel mai recent „Kolibri” este scris în asamblator plat (FASM) și ocupă o dischetă - 1,44 MB. Datorită acestui fapt, poate fi plasat în întregime într-un fel de memorie specializată. De exemplu, meșterii au scris KolibriOS direct în BIOS-ul Flash. În timpul funcționării, acesta poate fi localizat în întregime în memoria cache a unor procesoare. Imaginează-ți: toate sistemele de operare, împreună cu programele și driverele, sunt stocate în cache!

INFO

Când vizitați site-ul web kolibrios.org, browserul dumneavoastră vă poate avertiza asupra pericolului. Motivul pare să fie programele de asamblare din distribuție. VirusTotal definește acum site-ul ca fiind complet sigur.

„Kolibri” poate fi încărcat cu ușurință de pe o dischetă, hard disk, unitate flash, Live CD sau într-o mașină virtuală. Pentru emulare, este suficient să specificați tipul de sistem de operare „altul”, să îi alocați un nucleu de procesor și ceva RAM. Nu este necesar să conectați discul, iar dacă aveți un router cu DHCP, „Kolibri” se va conecta instantaneu la Internet și la rețeaua locală. Imediat după încărcare, veți vedea o notificare corespunzătoare.


O problemă este că protocolul HTTPS nu este acceptat de browserul Kolibri încorporat. Prin urmare, nu a fost posibil să se uite la site-ul din acesta, precum și să se deschidă paginile Google, Yandex, Wikipedia, „Sberbank” ... de fapt, nicio adresă familiară. Toată lumea a trecut la un protocol securizat cu mult timp în urmă. Singurul site cu HTTP pur vechi de școală pe care l-am întâlnit este „portalul Guvernului Rusiei”, dar nici într-un browser de text nu arăta cel mai bine.



Setările de aspect în Hummingbird s-au îmbunătățit de-a lungul anilor, dar sunt încă departe de a fi ideale. Lista modurilor video acceptate este afișată pe ecranul de încărcare „Hummingbird” prin apăsarea tastei cu litera latină a.



Lista de opțiuni disponibile este limitată și este posibil ca rezoluția necesară să nu apară. Dacă aveți o placă video cu un GPU AMD (ATI), puteți adăuga imediat setări personalizate. Pentru a face acest lucru, trebuie să transmiteți parametrul -m la încărcătorul ATIKMS X X , de exemplu:

/ RD / 1 / ȘOFERI / ATIKMS -m1280x800x60 -1

Aici / RD / 1 / DRIVERS / ATIKMS este calea către bootloader (RD - RAM Disk).

Când sistemul rulează, modul video selectat poate fi vizualizat cu comanda vmode și (teoretic) comutat manual. Dacă Kolibri rulează în mașina virtuală, atunci această fereastră va rămâne goală, dar cu o pornire curată, driverele video Intel pot fi adăugate de la i915 la Skylake inclusiv.

În mod surprinzător, o grămadă de jocuri se potrivesc în KolibriOS. Printre acestea se numără jocuri de logică și arcade, tag, șarpe, tancuri (nu, nu WoT) - un întreg „Game Center”! Chiar și Doom și Quake au fost portate la Hummingbird.



Un alt lucru important a fost cititorul FB2READ. Funcționează corect cu chirilic și are setări de afișare a textului.



Recomand să stocați toate fișierele utilizatorului pe o unitate flash USB, dar aceasta trebuie conectată printr-un port USB 2.0. Unitatea noastră flash USB 3.0 (în portul USB 2.0) cu o capacitate de 16 GB cu sistemul de fișiere NTFS a fost identificată imediat. Dacă trebuie să scrieți fișiere, atunci ar trebui să conectați o unitate flash USB cu o partiție FAT32.



Distribuția Kolibri include trei manageri de fișiere, utilitare pentru vizualizarea imaginilor și documentelor, playere audio și video și alte aplicații personalizate. Cu toate acestea, se concentrează pe dezvoltarea limbajului de asamblare.



Editorul de text încorporat are evidențierea sintaxelor ASM și vă permite chiar să rulați imediat programe tastate.



Instrumentele de dezvoltare includ compilatorul Oberon-07/11 pentru i386 Windows, Linux și KolibriOS, precum și emulatoare de nivel scăzut: E80 - emulator ZX Spectrum, FCE Ultra - unul dintre cei mai buni emulatori NES, DOSBox v.0.74 și altele. Toate au fost adaptate special la Hummingbird.

Dacă părăsiți KolibriOS pentru câteva minute, screensaver-ul va porni. Pe ecran vor rula linii de cod, în care puteți vedea o referință la MenuetOS.

Continuarea este disponibilă numai pentru participanți

Opțiunea 1. Alăturați-vă comunității „site” pentru a citi toate materialele de pe site

Calitatea de membru al comunității în perioada specificată vă va deschide accesul la TOATE materialele Hacker, vă va crește discountul cumulat personal și vă va permite să acumulați un scor profesional Xakep!

Asamblator

Asamblator(din engleză assemble - a assemble) - un compilator din limbajul de asamblare în comenzile limbajului mașinii.
Există un asamblator pentru fiecare arhitectură de procesor și pentru fiecare sistem de operare sau familie de sistem de operare. Există, de asemenea, așa-numitele „cross-assemblers” care permit, pe mașini cu aceeași arhitectură (sau în mediul unui sistem de operare), să asambleze programe pentru o altă arhitectură țintă sau un alt sistem de operare și să obțină cod executabil într-un format potrivit pentru executie pe arhitectura tinta sau in mediul tinta.OS.

Arhitectura X86

Asamblatori pentru DOS

Cei mai faimoși asamblatori pentru sistemul de operare DOS sunt Borland Turbo Assembler (TASM) și Microsoft Macro Assembler (MASM). Asamblatorul simplu A86 a fost, de asemenea, popular la un moment dat.
Inițial, au acceptat doar instrucțiuni pe 16 biți (înainte de sosirea procesorului Intel 80386). Versiunile ulterioare ale TASM și MASM acceptă atât instrucțiuni pe 32 de biți, cât și toate instrucțiunile introduse în procesoare mai noi și seturi de instrucțiuni specifice arhitecturii (cum ar fi MMX, SSE, 3DNow! Etc.)...

Microsoft Windows

Odată cu apariția sistemului de operare Microsoft Windows, a apărut extensia TASM, numită TASM32, care a făcut posibilă crearea de programe care să ruleze în mediul Windows. Cea mai recentă versiune cunoscută de Tasm este 5.3, care acceptă instrucțiuni MMX și este în prezent inclusă în Turbo C ++ Explorer. Dar oficial dezvoltarea programului este complet oprită.
Microsoft își menține produsul numit Microsoft Macro Assembler. Continuă să evolueze până în prezent, cu cele mai recente versiuni incluse în DDK-uri. Dar versiunea programului care vizează crearea de programe pentru DOS nu este în curs de dezvoltare. În plus, Stephen Hutchesson a creat un pachet de programare MASM numit „MASM32”.

GNU și GNU/Linux

Sistemul de operare GNU include compilatorul gcc, care include asamblatorul de gaz (GNU Assembler) folosind sintaxa AT&T, spre deosebire de majoritatea celorlalți asamblatori populari care folosesc sintaxa Intel.

Asambleri portabili

Există, de asemenea, un proiect de asamblare open source, ale cărui versiuni sunt disponibile pentru diferite sisteme de operare și care vă permite să obțineți fișiere obiect pentru aceste sisteme. Acest asamblator se numește NASM (Netwide Assembler).
YASM este o versiune cu licență BSD a NASM rescrisă de la zero (cu unele excepții).
FASM (Flat Assembler) este un tânăr asamblator sub o licență BSD modificată pentru a interzice relicențiarea (inclusiv sub GNU GPL). Există versiuni pentru KolibriOS, GNU/Linux, MS-DOS și Microsoft Windows, utilizează sintaxa Intel și acceptă instrucțiuni AMD64.

Arhitecturi RISC


MCS-51
AVR
În acest moment există 2 compilatoare de la Atmel (AVRStudio 3 și AVRStudio4). A doua versiune este o încercare de a remedia prima versiune care nu are prea mult succes. Există, de asemenea, un asamblator în WinAVR.
BRAŢ
AVR32
MSP430
PowerPC

Asamblarea și compilarea

Procesul de traducere a unui program în limbaj de asamblare în cod obiect se numește în mod obișnuit asamblare. Spre deosebire de compilare, asamblarea este mai mult sau mai puțin clară și reversibilă. În limbajul de asamblare, fiecare mnemonic corespunde unei instrucțiuni de mașină, în timp ce în limbajele de programare de nivel înalt, un număr mare de instrucțiuni diferite pot fi ascunse în spatele fiecărei expresii. În principiu, această împărțire este destul de arbitrară, așa că uneori traducerea programelor de asamblare este numită și compilare.

limbaj de asamblare

limbaj de asamblare- un tip de limbaj de programare de nivel scăzut, care este un format pentru înregistrarea instrucțiunilor mașinii care poate fi citit de om. Este adesea menționat ca un asamblator pentru concizie, ceea ce nu este adevărat.

Instrucțiunile din limbajul de asamblare corespund unu-la-unu cu instrucțiunile procesorului și, de fapt, reprezintă o formă simbolică convenabilă de notare (cod mnemonic) a comenzilor și a argumentelor acestora. De asemenea, limbajul de asamblare oferă abstracții de bază ale programului: legarea părților din program și a datelor prin etichete cu nume simbolice (în timpul asamblarii, se calculează o adresă pentru fiecare etichetă, după care fiecare apariție a etichetei este înlocuită cu această adresă) și directive.
Directivele Assembler vă permit să includeți blocuri de date (descrise explicit sau citite dintr-un fișier) în program; repetați un anumit fragment de un anumit număr de ori; compilați un fragment condiționat; setați adresa de execuție a fragmentului, diferită de adresa locației din memorie [specificați!]; modificați valorile etichetelor în timpul compilării; utilizați macrocomenzi cu parametri etc.
Fiecare model de procesor, în principiu, are propriul set de instrucțiuni și limbajul de asamblare (sau dialectul) corespunzător.

Avantaje și dezavantaje

Virtuțile limbajului de asamblare

Cantitatea minimă de cod redundant, adică utilizarea a mai puține instrucțiuni și accesări la memorie, vă permite să creșteți viteza și să reduceți dimensiunea programului.
Asigurarea compatibilității deplină și maximizarea capacităților platformei dorite: folosind instrucțiuni speciale și caracteristici tehnice ale acestei platforme.
La programarea în limbaj de asamblare, devin disponibile caracteristici speciale: acces direct la hardware, porturi I/O și registre speciale ale procesorului, precum și capacitatea de a scrie cod cu auto-modificare (adică metaprogramare și fără a fi nevoie de un interpret software).
Cele mai recente tehnologii de securitate implementate în sistemele de operare nu permit realizarea de coduri automodificabile, deoarece exclud executarea simultană a instrucțiunilor și scrierea în aceeași zonă de memorie (tehnologia W ^ X în sistemele BSD, DEP în Windows).

Dezavantajele limbajului de asamblare

Cantități mari de cod și un număr mare de sarcini suplimentare mici, ceea ce duce la faptul că codul devine foarte greu de citit și de înțeles și, prin urmare, mai dificil de depanat și rafinat programul, precum și la dificultatea implementării paradigmelor de programare și orice alte convenții. ceea ce duce la complexitatea dezvoltării colaborative.
Mai puține biblioteci disponibile, compatibilitatea lor scăzută între ele.
Neportabilitate pe alte platforme (cu excepția compatibilității binare).

Aplicație

Rezultă direct din avantaje și dezavantaje.
Deoarece este extrem de incomod să scrieți programe mari în limbaj de asamblare, acestea sunt scrise în limbaje de nivel înalt. În limbajul de asamblare, ei scriu fragmente mici sau module pentru care sunt foarte importante:
viteza (soferi);
dimensiunea codului (sectoare de pornire, software pentru microcontrolere și procesoare cu resurse limitate, viruși, protecție software);
caracteristici speciale: lucrează direct cu hardware sau cod de mașină, adică încărcătoare de sistem de operare, drivere, viruși, sisteme de protecție.

Conectarea codului de asamblare la alte limbi

Deoarece de cele mai multe ori doar fragmentele de program sunt scrise în asamblare, acestea trebuie să fie legate cu alte părți în alte limbi. Acest lucru se realizează în 2 moduri principale:
La momentul compilarii- inserarea fragmentelor de asamblare inline în program prin directive speciale de limbaj, inclusiv proceduri de scriere în limbaj de asamblare. Metoda este convenabilă pentru transformări simple de date, dar codul de asamblare cu drepturi depline, cu date și subrutine, inclusiv subrutine cu multe intrări și ieșiri care nu sunt acceptate de limbaje de nivel înalt, nu se poate face cu ea.
În stadiul de construcție, sau compilare separată. Pentru interacțiunea modulelor legate, este suficient ca funcțiile de legare să accepte convențiile de apelare și tipurile de date necesare. Modulele individuale pot fi scrise în orice limbă, inclusiv în asamblare.

Sintaxă

Nu există un standard universal acceptat pentru sintaxa limbajelor de asamblare. Cu toate acestea, există standarde pe care majoritatea dezvoltatorilor de limbaje de asamblare le respectă. Principalele astfel de standarde sunt sintaxa Intel și sintaxa AT&T.

Instrucțiuni

Formatul general de scriere a instrucțiunilor este același pentru ambele standarde:

[etichetă:] opcode [operanzi] [; comentariu]

unde opcode-ul este mnemonicul propriu-zis al instrucțiunii către procesor. I se pot adăuga prefixe (repetări, schimbarea tipului de adresare etc.).
Operanzii pot fi constante, nume de registre, adrese din RAM etc. Diferențele dintre standardele Intel și AT&T se referă în principal la ordinea de enumerare a operanzilor și sintaxa acestora pentru diferite metode de adresare.
Mnemoteciile folosite sunt de obicei aceleași pentru toate procesoarele din aceeași arhitectură sau familie de arhitecturi (printre cele cunoscute sunt mnemonicele Motorola, ARM, procesoare și controlere x86). Sunt descrise în specificația procesorului. Posibile excepții:
Dacă asamblatorul folosește sintaxa AT&T multiplatformă (mnemonicele originale sunt forțate la sintaxa AT&T)
Dacă inițial existau două standarde pentru înregistrarea mnemotecilor (sistemul de comandă a fost moștenit de la un procesor al altui producător).
De exemplu, procesorul Zilog Z80 a moștenit setul de instrucțiuni Intel i8080, l-a extins și a schimbat mnemonicii (și desemnările registrului) în felul său. De exemplu, am schimbat mov Intel la ld. Procesoarele Motorola Fireball au moștenit setul de instrucțiuni Z80, reducându-l ușor. În același timp, Motorola a revenit oficial la mnemonicii Intel. Și în acest moment, jumătate dintre asamblatorii pentru Fireball lucrează cu mnemonice Intel și jumătate cu mnemonice Zilog.

Directive

Pe lângă instrucțiuni, un program poate conține directive: instrucțiuni care nu se traduc direct în instrucțiuni de mașină, dar controlează funcționarea compilatorului. Setul și sintaxa lor variază considerabil și depind nu de platforma hardware, ci de compilatorul utilizat (dând naștere dialectelor de limbi în cadrul aceleiași familii de arhitecturi). Ca „set gentleman” de directive, se poate evidenția:
definirea datelor (constante și variabile)
gestionarea organizării programului în memorie și a parametrilor fișierului de ieșire
setarea modului compilatorului
tot felul de abstracții (adică elemente ale limbajelor de nivel înalt) - de la proiectarea procedurilor și funcțiilor (pentru a simplifica implementarea paradigmei de programare procedurală) până la constructe și bucle condiționate (pentru paradigma de programare structurată)
macro-uri

Exemplu de program

Exemplu de program Hello world pentru MS-DOS pentru arhitectura x86 în dialectul TASM:

.MODEL SEGMENT DE COD MINUS ASUMEAZĂ CS: COD, DS: COD ORG 100h START: mov ah, 9 mov dx, OFFSET Mess int 21h int 20h Mess DB "Hello World", 13,10, "$" COD SE TERMINĂ END START

Originea și critica termenului „limbaj de asamblare”

Acest tip de limbi și-a primit numele de la numele traducătorului (compilatorului) din aceste limbi - assembler (asambler englez). Numele acestuia din urmă se datorează faptului că pe primele computere nu existau limbaje de nivel superior, iar singura alternativă la crearea de programe folosind assembler era programarea direct în coduri.
Limba de asamblare în limba rusă este adesea numită „assembler” (și ceva legat de acesta - „assembler”), care, conform traducerii în engleză a cuvântului, este greșită, dar se încadrează în regulile limbii ruse. Cu toate acestea, asamblatorul (programul) în sine este numit și simplu „asamblator”, nu „compilator limbaj de asamblare”, etc.
Utilizarea termenului „limbaj de asamblare” poate duce, de asemenea, la concepția greșită că există un singur limbaj de nivel scăzut, sau cel puțin un standard pentru astfel de limbi. La denumirea limbii în care este scris un anumit program, este indicat să specificați pentru ce arhitectură este destinat și în ce dialect al limbii este scris.