Assembler este ușor! Învățați să eliberați programul n 014 (bler)

Oh, prietenii mei! Și eu eram bolnavă! O săptămână întreagă. Din păcate, nu am putut lansa acest newsletter la timp. În acest sens, îmi cer scuze pentru o astfel de întârziere. Aș dori să vă avertizez: fii atent! Nu fi bolnav!







Dragi abonați! Am imprimat buletinul de știri astfel încât să puteți învăța cum să scrieți programe în Assembler. Mai mult, chiar vreau să vă insuflez în tine o dragoste față de limba în sine și să arăt că nu este atât de complicată. Sunt foarte bucuros că mulți oameni folosesc informațiile de la corespondență pentru a scrie controlul și / sau munca de laborator. Sunt fericit că aș putea ajuta pe cineva!

Cu toate acestea, aș fi foarte dezamăgit să aflu că informațiile de la "Assembler? Este ușor de învățat să programe" informații sunt folosite de cineva în scopuri comerciale. Te rog: respect, te rog, munca altcuiva! Dacă aveți o propunere de a utiliza informațiile din buletinul informativ, nu numai pentru uz, personal, dar, de asemenea, în scopuri comerciale (aceasta nu include scrierea dvs. rezumate proprii, de control și de laborator locul de muncă etc.), atunci, dacă vă rog: scrie-mi oferta ta! Vom găsi un limbaj comun!

De ce scriem doar fișierele * .com? Da, deoarece modelul de memorie din Windows este foarte asemănător modelului de memorie al fișierelor * .com, pe care îl analizăm acum. Desigur, vom scrie câteva exemple de fișiere * .exe, dar va fi mai târziu.

Apropo. Modelul de memorie din fișierele * .com este numit TINY (tiny). În Windows - FLAT (plat sau așa?).

Vreau să întreb oamenii educați: există un cuvânt "amintit" în limba rusă. Dacă nu, cum o puteți înlocui cu un cuvânt?

Cel mai recent am pus pe site-ul meu un mic album foto. în care puteți vedea fotografii ale soției, fiului meu, fratelui, surorii, tatălui, mamei, precum și personalului meu. Dacă sunteți interesat, puteți să vă uitați în timpul liber.

Deci, a sosit timpul! Unii s-au familiarizat deja cu termenii de pe site. dar tot recomand să citesc ce e în această listă de discuții și tuturor abonaților.

Nu toată lumea are acces direct și permanent la Web. În acest sens, voi încerca să explic pe scurt esența experimentului nostru ca să spun așa.

De ce am decis să fac asta?

Pentru mine, există multe scrisori cu diverse întrebări (atât pentru Assembler, cât și pentru alte subiecte, de exemplu, care lucrează cu DOS). Eu, așa cum deja am scris, nu aveți timp să răspundeți la toate scrisorile. Prin urmare, am decis să realizez un mic experiment: să creez așa-numitul. "Clubul de experți".

Ce este acest "club de experți" (?)?

Poate include orice persoană care decide să-și asume o sarcină responsabilă și dificilă și să încerce în rolul de "profesor" să devină așa-numitul "profesor". expert. Sau, mai simplu, răspundeți competent la întrebările abonatului. De exemplu:

  • Vasya nu știe cum să lucreze cu DOS (nu știe cum să înceapă programul, să despacheteze fișierul, să utilizeze MASM / TASM etc.);
  • Petit avea o întrebare despre lucrarea dezasamblării;
  • Sasha și-a scris programul utilizând cunoștințele primite de pe lista de discuții, dar - asta e problema! - nu funcționează așa cum ar fi plăcut Sasha. Ce ar trebui să fac?
  • În general, Vova sa înscris și nu știe ce da. Unde și cine să contactați?
  • Dima nu a înțeles nimic pe stack. Avea o întrebare. Cine poate ajuta abonatul nostru?
  • și altele.

Dar Serghei are timp, anumite cunoștințe și dorința de a răspunde la întrebări, pentru ai ajuta pe alții să-l stăpânească pe Assembler, dar nu există nicio posibilitate. Mai mult decât atât, Serghei știe că atunci când explică un subiect sau când răspunde la o întrebare, el însuși începe să înțeleagă ceva. Ie el însuși va învăța învățând pe alții.

Vreau să dau această ocazie Serghei și tuturor celor care au aceeași dorință.

Care este principiul clubului?

Ce pot oferi experților?

Trei lideri au ocazia:

Un expert care a câștigat primul loc poate primi, pe lângă cele de mai sus, și un ban pentru munca sa. Nu-mi promit prea mult; Voi plăti din buzunar, dar suficient pentru o bere.

De ce am scris "pot"? Deoarece pentru un timp (până când sistemul nu funcționează într-un anumit ritm, dacă funcționează deloc!), Banii nu vor fi plătiți. Dar atunci puteți câștiga nu numai bere, ci și pe bloc. Și acolo, vedeți, și înainte de a veni crocodilul. Cel puțin sper foarte mult.

Dar nu totul este atât de simplu. Toți experții trebuie să respecte anumite reguli, care le vor fi trimise în scurt timp. Numărul de experți este limitat la 10 persoane pe aceeași temă.

Ce este necesar ca abonații să pună întrebări?

Mai întâi de toate, decența și atenția. Și anume:

Toate cele de mai sus sunt cele mai importante! Pentru a face acest lucru, vreau să sărind mai întâi literele prin cutia mea.

Asigurați-vă că câmpul "Subiect" al întrebării dvs. are o linie corespunzătoare care se înscrie după "? Subject =".

Întrebările pe care mi le-ați trimis și nu ați primit un răspuns, adresați-vă experților relevanți. Mulțumesc.

Astăzi avem o problemă destul de obositoare și neinteresantă. Dar ceea ce vom considera în ea este foarte important! Va trebui să vă amintiți elementele de bază ale matematicii și să vă "mișcați creierul". Da, da, prietenii mei! Și cum ai vrut să înveți asamblorul fără cunoștințe elementare de matematică? Subliniez: elementar. Trebuie să muncești din greu azi! Deși, cea mai mare parte a muncii pe care am făcut-o pentru dvs., și anume: a gândit algoritmul pentru afișarea oricărei ferestre (sau a cadrului) pe ecran în centrul ecranului. Trebuie doar să citiți cu atenție și să o înțelegeți.







Cerere completă: citiți cu atenție această versiune și fișierul atașat Sshell14.rar!

Să convenim asupra unor definiții. pentru că programul va fi mare, pentru a facilita lizibilitatea și căutarea procedurii necesare, voi indica în paranteze procedura și fișierul în care trebuie să căutați ceva despre care voi scrie în buletinul informativ. De exemplu,

"Apoi ștergem fișierul (Delete_file, FILES.ASM)."

Aici: Delete_file este procedura care șterge fișierul și FILES.ASM este fișierul în care doriți să îl căutați.

Ne uităm imediat la fișierul MAIN.ASM. Mai întâi de toate, ceea ce trebuie să facem este să ascundem cursorul (Hide_cursor, DISPLAY.ASM). Înainte de a face acest lucru, trebuie să vă amintiți poziția sa actuală. Acest lucru vă permite să faceți funcția 3 întrerupe 10h:

Asta facem (Save_mainscr, DISPLAY.ASM). Aici întâlnim noi operatori: PUSHA și POPA (POPA înseamnă POP All - împingeți tot (și nu asta), Și PUSHA - PUSH All - împingeți totul înăuntru). Ie acest operator împinge registrele în următoarea ordine:

AX, CX, DX, BX, SP, BP, SI și DI

și, în consecință, operatorul POPA îi îndepărtează din stivă în ordine inversă, și anume:

DI, SI, BP, SP, BX, DX, CX și AX.

Acești operatori sunt utilizați numai de procesorul 286+. Când scriu, de exemplu, că un astfel de operator este utilizat în procesorul 386 +, înseamnă că acest operator va lucra la procesoarele 80386, 80486, Pentium etc. dar nu pe 8086 (PC / XT) și 80286 (PC / AT).

În cazul nostru, comenzile PUSHA și POPA vor funcționa pe procesoarele 80286 și mai târziu (mai moderne). Pentru a face acest lucru, la începutul fișierului SSHELL.ASM, specificăm așa-numitul. Directiva 0.286, indicând faptul că de asamblare (MASM, TASM), că acest program se poate întâlni echipa (instrucțiunile) nu numai 8086, dar, de asemenea, la 80286. „De ce, am avut nimic de genul de scris?“ cititorul atent va întreba. „În cazul în care nici unul din acest punct, de asamblare (MASM, TASM) consideră că numai 8086 manual, programul pe care am făcut-o încă.“ - răspunde la umilul tău servitor.

Desigur, comenzile PUSHA și POPA sunt utile atunci când trebuie să stocăm mai multe registre în stivă. Reduce dimensiunea programului.

Acordați atenție, de asemenea, pe măsură ce punem numărul în registrul de segmente:

Acesta este un octet mai scurt decât dacă am făcut acest lucru:

În plus, nu atingem registrul AX, care este util în unele cazuri.

De asemenea, funcționează pe procesoare 80286+ (pentru a fi precis, ruleaza pe CPU 80186+, dar din moment ce aceste procesoare nu devin pe scară largă datorită faptului că la câteva luni după lansarea 80186 a apărut 80286, ceva despre ei (despre 80186), în general, foarte puțini oameni știu).

Orice altceva în această procedură (Save_mainscr, DISPLAY.ASM) trebuie să fie clar. Exact ca în procedura de restaurare a ecranului (Restore_mainscr, DISPLAY.ASM).

Acum cel mai plictisitor (în opinia mea).

Am întâlnit deja această metodă atunci când încercăm să afișăm o "față" pe ecran. Acum, ia în considerare în detaliu.

Trebuie menționat faptul că acesta este cel mai rapid mod de afișare a caracterelor pe ecran. Mai rapid nu mai există. Aici totul depinde de profesionalismul programatorului și, ca o consecință, de algoritmul de ieșire, viteza de execuție a acestuia.

Luați în considerare pe scurt modele de monitoare, dintre care multe sunt deja urechi în trecut, și numai jucării vechi și bune le reamintesc periodic existența lor. Iată seria: MDA (Adaptor de afișare monocrom), Hercules. CGA (adaptor grafic color), EGA (Enchanced adaptor grafic), VGA (Video Graphic Array), mcGA (Multi-Color Adaptor grafic - similaritate VGA), SVGA (Super Video Graphic Array - faptul că multe utilizate în prezent în activitatea ).

Pentru o procedură (și poate nu doar pentru ea) vom avea două variabile: Height_X și Width_Y. În timp ce temporar. În viitor, vom învăța cum să transferăm datele în stack. Dar va fi mai târziu, dar acum variabila Height_X conține înălțimea cadrului și Width_Y este lățimea. Num_attr - culoarea cadrului (Main_proc, MAIN.ASM). Puteți apela procedura Draw_frame, care se află în fișierul DISPLAY.ASM.

Acum, să ne uităm la cel mai important lucru. Deci, procedura este Draw_frame.

Înainte de a apela această procedură, trebuie să introduceți unele numere în variabilele corespunzătoare (main.asm), și anume:

Height_X - conține înălțimea cadrului nostru;

Width_Y - conține lățimea cadrului nostru;

Num_attr - conține atributele cadrului de ieșire.

Asta e tot pentru moment. Vom merge mai departe - vor fi mai multe.

Deci, a adus. Se numește procedura Draw_frame (Display.asm).

Acum atenție! Este necesar să faceți niște calcule înainte de a muta cadrul "în nici un fel", adică chiar în centrul ecranului.

Trebuie să împărțim înălțimea cadrului cu 2 și să scădem din numărul rezultat mijlocul înălțimii. Aici:

(1) mov ax, înălțime_X

În linia (1), am pus în AX înălțimea cadrului care a fost indicată înainte de a fi apelată procedura. Apoi, în linia (2), operatorul SHR schimbă toți biții din registrul AL cu 1 în dreapta. Ce se întâmplă? Iată un exemplu:

mov ax, 16 --- AX = 10000b, adică 16

shr ax, 1 --- AX = 1000b, adică 8

shr ax, 1 --- AX = 100b, adică 4

shr ax, 1 --- AX = 10b, adică 2

shr ax, 1 --- AX = 1b, adică 1

astfel Trecerea de biți spre dreapta cu unul împarte numărul cu 2. Cele două sunt patru ori și așa mai departe. Acest lucru este mai rapid dacă am folosit operatorul DIV (care, apropo, nu am studiat încă) - împărțirea.

În linia (3), punem DH în mijloc (sau aproape mijlocul) ecranului (orizontal), adică 11. Și scade din 11 rezultatul obținut.

De exemplu, scoatem un cadru cu o înălțime de 5 rânduri. Iată ce obținem:

astfel Începem cu linia 6.

Tot ceea ce facem cu coloanele (pe verticală). Uită-te în exemplul atașat.

În principiu, deocamdată, nu vă concentrați în mod special pe aceasta: în timp, experiența va veni și o înțelegere mai exactă.

mov dh, 0; DH, de obicei, indică un șir

mov dl, 15, și DL - la o coloană (acest lucru vom face în toate procedurile noastre)

, astfel. ieșim în linia zero (adică cea mai mare pe ecran), 15 coloană.

Aici traducem două numere într-o matrice liniară (traduceți într-un singur număr - offset):

Multiplicați în două linii; Un caracter de pe ecran are două octeți: simbolul + atributul său

Linear = Linear + DH * 160

mov dh, 8; linia 8

mov dl, 56; coloana 56

acum Linear = 112

Linear = Linear + DH * 160

Acum liniar = 1392 sau 570h

Și ultimul exemplu. Executăm calculele pentru ultimul caracter de pe ecran (colțul din dreapta jos):

Linear = (24 * 160 + 80 * 2) - 2 = 0F9Eh

80 - numărul de coloane pe ecran, care trebuie înmulțit cu 2 (luând în considerare nu numai simbolul, ci și atributul său).

(A 24-a linie * 160 + 80 de caractere * 2) - 2

(24 * 160 + 80 * 2) - 2 = 3998 sau 0F9Eh

Aș prefera să vă spun cum arată în practică. Deci, procedura (Get_linear, DISPLAY.ASM) (deși, multe sunt clare din descrierile din fișier):

shl dl, 1; înmulți DL cu 2 (DL = DL * 2).

Doar mutați biții 1 spre stânga (prin principiul divizării, vezi mai sus).

mov al, dh; în AL - o serie,
mov bl, 160, care trebuie înmulțită cu 160
multiplicare: AL (rând) * 160; rezulta in AX

Ce e asta? Operatorul nou MUL? Să o luăm acum.

Deci, aici sunt tabelele cu noii operatori:







Trimiteți-le prietenilor: