Programarea listei de asamblare a limbilor, programare

2.8. Bazele programării. Assembler Assembler
Asamblorii moderni conțin așa-numitele macro-mijloace și, din acest motiv, sunt uneori numite macroassemblers. Ideea generală a macrocomenzii este că, prin includerea limbii speciale a mijloacelor macro (limba macro) în codul sursă al programului, gestionăm într-o oarecare măsură procesul de traducere a programului. Limbajul macro permite sau nu efectuează traducerea secțiunilor individuale ale programului, în funcție de anumite condiții definite de noi (traducere condiționată); să reproducă o secțiune a textului sursă al programului, inclusiv, cu modificarea fiecărei repetări (blocuri de repetare); includeți în program scrise separat fragmente cu ajustarea textului lor în conformitate cu parametrii specificați (macro-uri). Obiectele create folosind directivele macro-limbaj sunt de obicei numite macrocomenzi. Uneori însă, termenul macro se referă numai la un anumit tip de macrocomandă, adică la o macrocomandă. Utilizarea macrocomenzilor simplifică compilarea codului sursă al programului și, uneori, face ca acest text să fie mai vizibil, deși în unele cazuri, ca și în cazul directivelor de traducere condiționată, dimpotrivă, poate duce la o complicație semnificativă a textului sursă.






Ca și în orice limbaj de programare, există multe tipuri diferite de subtilități în limba macro mijloacelor, dar în programarea aplicațiilor, sunt adesea folosite doar capabilitățile de bază ale acestei limbi. Prin urmare, ne limităm aici la luarea în considerare a principalelor mijloace macro ale asamblorului.
Repetați blocurile
Blocările de repetare determină traducătorul să repete blocul specificat de text sursă specificat de câte ori. Un bloc repetat poate consta din directive de descriere a datelor (și apoi este inclus în segmentul de date) sau din instrucțiunile procesorului (și apoi este descris în segmentul de programe). De exemplu, următorul segment al segmentului de date vă permite să creați o matrice compusă din coduri ASCII de litere rusești mari:

sim = 'A' Valoarea inițială a variabilei temporare
simboluri:; numele matricei pentru ao face referire
repet 32; Repetați de câte ori
db sym; Repetați directiva
sim = sym + l; modificați variabila
sfârșitul blocului de repetare

După cum puteți vedea din fragmentul de mai sus, blocul de repetare începe cu directiva rept de asamblare (de la repetare, repetare) și se termină cu directiva endm (macro sfârșit, sfârșitul macro-ului). De fapt, în segmentul de date, sunt alocate 32 de octeți, umplută cu numere de la 81h la 9Fh, care ar trebui tratate ca o succesiune de litere rusești. Același rezultat ar putea fi obținut cu ajutorul următoarei propoziții:

simbolurile db "A", "B", "B", "G" etc. până la litera I
sau mai ușor, deși mai puțin evident:

simbolurile db 128,129,130,131 etc. până la numărul 159.
Macro-ul de repetare scurtează într-o oarecare măsură timpul necesar pentru a descrie matricea dorită în textul programului, deși poate reduce vizibilitatea acestei descrieri.
Când conectați un echipament de măsură sau de control la un computer, uneori devine necesar să încetiniți procesorul atunci când accesați porturile acestui echipament. Decelerația se realizează prin includerea în textul programului a uneia sau, dacă este necesar, a mai multor comenzi de tranziție necondiționată la următoarea frază:

în AL, 300h; Primul acces la echipament
jmp a; Întârziere de timp
a: jmp b;
b: jmp cu trei comenzi jmp
c: în AL, 301h; accesul ulterior la echipament

Pentru a nu crea multe etichete inutile, de fapt, această propoziție este scrisă adesea după cum urmează:

în AL, 300h; Primul acces la echipament
jmp $ + 2; Întârziere de timp
jmp $ + 2; execuție
jmp $ + 2; trei comenzi jmp
în AL, 301h; accesul ulterior la echipament

rept 6 jmp $ + 2 endm

Acest lucru, vă rog, este mai ușor decât să scrieți 6 comenzi pentru jmp.
Macroanele de repetare au mai multe varietăți, pe care nu le vom lua în considerare aici.
macro-uri
Programele scrise în limbajul de asamblare conțin adesea secțiuni repetate ale textului cu aceeași structură. O astfel de secțiune a textului poate fi emisă sub forma unei definiții macro, caracterizată printr-un nume arbitrar și o listă opțională de argumente formale. După ce se face o astfel de definiție, apariția în program a unui șir care conține numele definiției macro și lista argumentelor efective (toate denumite împreună macro) conduc la generarea întregului text necesar, numit macroextension. Variați argumentele reale, puteți să vă schimbați elementele individuale, păstrând structura neschimbată a expansiunii macro.
Definiția macro trebuie să înceapă cu un șir cu numele macro și directiva macro, în câmpul argument al căruia este specificată lista de argumente formale. Macrocomanda se încheie cu directiva endm.
Permiteți în mod repetat programului să stocheze conținutul a trei registre pe stivă, dar în fiecare caz specific, numerele de registru și ordinea lor diferă. Să luăm aceste acțiuni sub forma unei definiții macro:

împingeți a
împinge b
împingeți cu
endm

Aspect în codul sursă al liniei de program

va genera următorul fragment de text:

împinge AX împinge BX împinge CX

Dacă în textul sursă există o linie

atunci expansiunea macro corespunzătoare va arăta astfel:

împingeți DX
împinge ES
împinge BP

Ca argumente actuale, orice notație de asamblare care este valabilă pentru această comandă poate acționa. În special, apelul macro







psh mem, [BX], ES: [17h]

duce la următoarea extindere macro:

împinge mem
împingeți [BX]
împinge ES. [17h]

Dacă trebuie marcate anumite linii macro (de exemplu, în scopul organizării buclelor), atunci denumirile etichetelor ar trebui declarate locale folosind operatorul local. În acest caz, asamblorul, generând macroextenzii, va crea propriile denumiri de etichete care nu se repetă atunci când apelurile repetate ale aceleiași macrocomenzi:

întârziere macro
punct local
mov CX, 200
punct: punctul de buclă
endm

Macro-ul de întârziere creează o întârziere cu o durată fixă. Dacă includeți două macrocomenzi de întârziere în textul programului
...
întârziere
...
întârziere

atunci macroextențiile lor, înlocuite în textul programului, vor arăta astfel:

Cu înlocuirea repetată a definiției macro, traducătorul înlocuiește notația pentru eticheta de punct cu diferite notații. 0000. 0001, etc. asigurând astfel executarea corectă a comenzilor ciclurilor și tranzițiilor.
Macrorele sunt similare cu subrutinele, deoarece în ambele cazuri descriem o singură dată un fragment de program, dar îl adresăm în mod repetat, eventual cu transmiterea de diverși parametri. Cu toate acestea, aceste computere diferă în modul în care utilizează și în capacitățile lor.
Subrutinele vă permit să reduceți cantitatea de fișier executabil prin descrierea secțiunilor repetitive ale programului o singură dată. De fiecare dată când se cheamă subrutina, comanda de apel trece la același fragment de program care conține subrutina, iar după executarea subrutinei se întoarce la punctul de apel. Textul subrutinei este complet definit în stadiul scrierii sale, iar schimbările în cursul subrutinei sunt posibile numai pe seama transferului anumitor valori specifice.
Mecanismul de utilizare a unei macrocomenzi este diferit. Fiecare macro prezentată de translator în textul programului este înlocuită cu textul integral al definiției macro. Dacă macrocomanda conține parametri, atunci în timpul acestei înlocuiri, parametrii sunt înlocuiți în textul definiției macro. Macroextinderea formată în acest fel face parte din textul programului, care nu se deosebește de restul propunerilor programului și nu are nevoie de apeluri. Datorită acestor circumstanțe, macrocomenzile sunt oarecum mai eficiente decât subrutinele pentru viteza de execuție, mai ales dacă țineți cont de timpul necesar pregătirii parametrilor înainte de a apela o subrutină (de exemplu, împingându-i pe stivă). Cu toate acestea, este greu de făcut o astfel de comparație. Subrutinele și macro-urile au diferite domenii de aplicare.
Subrutinele servesc la reducerea mărimii programului, la creșterea vizibilității acestuia și la simplificarea reorganizării algoritmului de executare a întregului pachet software prin schimbarea compoziției și ordinii subrutinelor numite. În același timp, utilizarea activă a subrutinelor poate reduce dimensiunea întregului program în zeci de ori.
Semnificația utilizării macrocomenzilor este foarte diferită. Macroanele vă permit să simplificați procesul de scriere a unui program și, se poate spune, sunt un mijloc de automatizare a programării. În acest caz, limbajul macro-urilor oferă oportunități excelente pentru modificarea textului extensiei macro, în funcție de parametrii specificați în macrocomandă. Să ilustrăm aceste posibilități pe un exemplu simplu de ieșire macro la simbolul ecranului. O astfel de macrocomandă poate fi utilizată în timpul depanării programelor complexe pentru a obține informații despre conținutul celulelor de memorie. Exemplul este conceput ca un program complet, care este pur demonstrativ.

Fig. 2.18. Rezultatul programului 2.1.

Sfârșitul programului macro endpropr
endpr macro; macro-uri fără parametri
mov AX, 4C00h
int 2 In
endm Macro
; Macro-întârziere a întârzierii programabile
timp de întârziere macro; Parametru - număr de pași
locallabell, Iabel2; etichete locale
apăsați CX; salvați contorul extern
mov CX, time; Obțineți parametrul real
Iabel2. apăsați CX; salvați-l în stivă
mov CX, 0; să fie pași de 64K
labell: loop lanell; bucla internă
pop CX; extrageți contorul extern
buclă Iabel2; bucla externă
pop CX; Restaurați programul CX
endm Macro

Pentru ca traducătorul să poată accesa macrocomenzile din fișierul MYMACRO.MAC, ar trebui să fie conectat la textul sursă al programului prin directiva de asamblare include:

include macro-ul meu, mac

Toate macrocomenzile incluse în acest fișier pot fi utilizate oriunde în program.
Condiționate directive de traducere
Direcționarea translatărilor direcționate (ansamblu condițional) vă permite să aveți în codul sursă al programului diferite versiuni ale fragmentelor individuale ale programului și specificând anumite condiții pentru a gestiona procesul de traducere. Astfel, de exemplu, puteți să includeți sau să excludeți serviciul, să debifați fragmente din textul programului sau să configurați programul pentru a rula pe procesorul specificat.
Să permitem, de exemplu, în procesul de depanare a unui program complex, să folosim subrutina regs pentru a afișa conținutul tuturor registrelor procesorului. Inclusiv în diferite locuri ale programului apelul acestei subrutine, avem capacitatea de a monitoriza progresul execuției sale, inclusiv momentele subtile cum ar fi, de exemplu, localizarea programului în memorie sau intensitatea utilizării stivei. Pentru a controla procesul de traducere, vom furniza o depanare constantă (depanare), o valoare a cărei valoare nu va fi zero va necesita o versiune de depanare a traducerii și zero a lucrătorului. Începutul programului, precum și zonele cu apelul subrutinei de depanare vor arăta astfel:

; debug = l; Ștergeți caracterul ";" pentru depanare
; debug = 0; ștergeți ";" pentru difuzarea de lucru
. ; Textul programului
dacă debug; Traduceți numai dacă debug = l
apela regs; Apelarea unei subrutine de depanare
endif block translation condițional
... Continuarea programului
dacă debug; Următoarea includere a blocului de depanare
apela reg
endif
. ; Continuarea programului
Desigur, este posibil să se depana un program în versiunea de depanare, apoi ștergeți toate apelurile subrutine auxiliare REGS obține manual un exemplu de realizare de lucru, dar, în practică, de obicei, (sau întotdeauna), se pare că, după operarea programului de ceva timp detectat neobservat eroare anterior că duce la necesitatea de a reintroduce în ea șiruri de depanare. Adesea, această procedură trebuie repetată de mai multe ori. Utilizarea directivelor programului procedura de traducere condiționată reduce program de conversie din opțiunea de depanare la locul de muncă, sau vice-versa la operația de ștergere a unui simbol „;“ la începutul programului și a elimina posibilitatea introducerii accidentale în programul de bug-uri noi în procesul de îndepărtare sau inserarea de siruri de caractere de depanare.
Să luăm în considerare încă un exemplu de utilizare a directivelor de traducere condiționată. Așa cum am menționat deja, procesoarele moderne furnizează programatorului un număr semnificativ de comenzi suplimentare care pot fi utilizate în programe în modul real, dar numai dacă, desigur, calculatorul este echipat cu procesorul adecvat. Nu este dificil să creați un program universal, care să se poată realiza atât pe procesoare moderne (într-un mod mai eficient) cât și pe cele vechi (cu o oarecare pierdere de eficiență), dacă includeți directive direcționale de traducere pentru aceste comenzi suplimentare. Aceste comenzi includ, în special, comenzile pentru a stoca toate registrele împușcături de uz general pe stivă și pentru a restabili toate registrele hârlui. Să dăm un exemplu de traducere condiționată a acestor comenzi, în care se utilizează instrucțiunea macro-language if. altceva. endif:

i386 = l
dacă i386
.386
endif
utilizarea segmentului de cod16
presupun CS: cod
principala proc
...
dacă i386
împinge; salvarea tuturor registrelor cu o singură comandă
altfel
împinge AX
împingeți CX
împingeți DX
împinge BX
împinge BP
împingeți SI
împingeți DI
endif
. Utilizarea registrelor după
, păstrând valorile lor
dacă 1386
Restabiliți toate registrele cu o singură comandă
altfel
pop DI
pop SI
pop BP
pop BX
pop DX
pop CX
pop AX
endif







Articole similare

Trimiteți-le prietenilor: