programe isa x86
DESCRIPTION
În cadrul acestei lucrări se prezintă modul de editare, asamblare (compilare), link-editare, execuţie şi testare a unui program scris în limbaj de asamblare. De asemenea se prezintă directivele limbajului de asamblare.TRANSCRIPT
Lucrarea 8
Lucrarea 8
8 Dezvoltarea de programe n limbajul de asamblare ISA x86
8.1 Scopul lucrrii
n cadrul acestei lucrri se prezint modul de editare, asamblare (compilare), link-editare, execuie i testare a unui program scris n limbaj de asamblare. De asemenea se prezint directivele limbajului de asamblare.
8.2 Consideraii teoretice
8.2.1 Prezentare modului de elaborare a unui program n limbaj de asamblare
Elaborarea unei aplicaii ntr-un anumit limbaj de programare presupune parcurgerea mai multor etape:
editarea programului scrierea "programului surs" folosind instruciunile i directivele limbajului de programare
compilarea traducerea programului surs n secvene de coduri interpretabile i executabile de maina fizic; n urma compilrii se genereaz "module obiect"
editarea de legturi soluionarea referinelor externe (declaraii de variabile i proceduri n alte module dect cele care le utilizeaz sau le apeleaz), i includerea unor module coninute n bibliotecile limbajului de programare; n urma acestei faze se genereaz un program executabil
ncrcarea i execuia programului programul executabil se ncarc n memoria calculatorului, se actualizeaz adresele conform poziiei ocupate de program n memorie, dup care procesorul execut un salt la secvena de nceput a programului
n cazul utilizrii unor medii avansate de programare (ex: Visual Studio, Turbo Pascal, etc.) aceste etape sunt mai greu de sesizat, deoarece lansarea diferitelor programe i utilitare care soluioneaz aceste etape cade n sarcina mediului. n lipsa unui astfel de mediu, programatorul va lansa succesiv un editor de texte pentru scrierea programului surs, un compilator i un editor de legaturi. ncrcarea i lansarea n execuie a aplicaiei se face de ctre sistemul de operare la o comand dat de utilizator.
n figura 8.1 s-a indicat secvena de pai necesari pentru editarea compilarea i execuia unui program scris n limbaj de asamblare.
Editarea unui program surs n limbaj de asamblare se poate face cu orice editor de text care respect principiul " WYSWYG - what you see is what you get", adic imaginea de pe ecran este fidel cu coninutul fiierului generat. Editorul nu introduce coduri suplimentare de formatare i nu folosete tehnici de compactare. Astfel se poate utiliza un editor dintr-un alt mediu de programare (ex: din mediul Borland) sau editorul NotePad din Windows.
Compilarea programului (operaie denumit i asamblare) se poate realiza cu o anumit variant de asamblor: MASM (din mediul MS-DOS) sau TASM (din mediul Borland). Astfel se genereaz un fiier de tip OBJ care conine modulul obiect al programului scris. Editarea legturilor se realizeaz cu utilitarul LINK (mediul MS-DOS) sau TLINK (Mediul Borland). Aceast operaie este necesar chiar i n cazul n care programul este coninut ntr-un singur modul. n urma acestei operaii se genereaz un fiier EXE, care conine programul executabil.
Modulele de program scrise n limbaj de asamblare se pot combina cu alte module scrise n alte limbaje de programare sau cu module obiect coninute n biblioteci. Programul generat se poate executa numai dup ce a fost ncrcat n memoria calculatorului la o adres dat de sistemul de operare.
Pentru depanarea erorilor de programare i pentru testarea programului se poate utiliza unul din utilitarele: DEBUG (mediul MS-DOS), TD (turbo-debug, mediul Borland), AFD sau altele. Aceste utilitare permit ncrcarea n memorie a programului, execuia acestuia pas-cu-pas sau complect i vizualizarea memoriei i a registrelor procesorului.
8.2.2 Directivele limbajului de asamblare
Directivele sunt elemente de limbaj care au rol n procesul de elaborare, compilare i link-editare a unui program, dar care nu se regsesc n programul executabil. n consecin directivele nu sunt executabile i nu se genereaz cod pe baza acestora.
Totui scrierea unui program n limbaj de asamblare necesit utilizarea directivelor. Ele se folosesc pentru declararea variabilelor i a constantelor, pentru delimitarea procedurilor i a segmentelor i pentru a controla modul de compilare i link-editare al programului. n continuare se prezint acele directive care sunt strict necesare pentru scrierea unui program.
8.2.2.1 Declararea variabilelor
n limbaj de asamblare o variabil este o locaie de memorie, care se poate citi i scrie. Prin declararea variabilei se urmrete: - rezervarea de spaiu corespunztor de memorie pentru pstrarea variabilei,- specificarea dimensiunii variabilei (tipul variabilei determin implicit lungimea sa)- ataarea unui nume simbolic pentru adresa fizic a variabilei respectiveSintaxa directivei:
DB|DW|DD|DQ , [, ...]
unde:
- este un nume simbolic dat unei variabile
DB Data Byte directiv pentru declararea unei variabile de tip octet
DW Data Word - directiv pentru declararea unei variabile de tip cuvnt (2 octei)
DD Data Double - directiv pentru declararea unei variabile de tip dublu-cuvnt (4 octei)
DQ Data Quadruple - directiv pentru declararea unei variabile de tip cuadruplu-cuvnt (8 octei)
- o valoare constant sau o expresie evaluabil n timpul compilrii la o valoare constant este valoarea cu care se iniializeaz variabila
Semnificaia directivei: la adresa simbolizat de numele variabilei se rezerv un numr de locaii de memorie egal cu numrul specificat de valori. Dimensiunea unei locaii este indicat prin cuvntul cheie folosit.
La variantele mai noi de asambloare n locul cuvintelor cheie DB, DW, DD i DQ se pot utiliza formele mai explicite BYTE, WORD, DOUBLE i QUAD. Toate elementele limbajului de asamblare (inclusiv directivele) se pot scrie cu litere mari sau mici.
Exemple de utilizare:
var1db12h,5, 33, 10101111bxdw1234h, 0ff00h
literabyte'A'
text byte"TEXT"dubludd12345678hCorespunztor acestor declaraii, n memorie se vor regsi urmtoarele date:
O alt variant a acestor directive permite rezervarea unui bloc de memorie i iniializarea acestuia cu o valoare sau cu o secven de valori. DB|DW|DD|DQ DUP( [,..] |?)
unde: - indic numrul de locaii care se rezerv
- valorile de iniializare
? - zona care se rezerv nu seiniializeaz
Exemple:
blocdb 100 dup(0); se rezerv o zon de 100 de octei i se iniializeaz cu 0
xx dw20 dup(0ffffh); se rezerv o zon de 20 de cuvinte (40 octei) i
;se iniializeaz cu FFFFh bufferdd5 dup(?); se rezerv o zon de 5 dublucuvinte (20 octei) 8.2.2.2 Declararea constantelorScopul declarrii unei constante este de a utiliza un nume simbolic pentru o anumita valoare. O constant nu se modific n timpul execuiei programului i, n contrast cu o variabil, nu se rezerv spaiu de memorie pentru pstrarea ei. Declaraia de constant este similar cu o construc pentru pstrarea ei. Declaraia de constant este similar cu o construcie de tip "macrou". O valoare sau o expresie evaluabil la o valoare primete prin declarare un nume simbolic. Dac numele apare n cadrul programului atunci acesta se nlocuiete cu valoarea sau expresia din declaraie.
Sintaxa directivei:
EQU
unde: - numele constantei
EQU - mnemonica directivei (eng. "equals")
- o valoare constant sau o expresie evaluabil la o constant
Exemple:
unuequ1
trueequ0ffh
falseequ0
adr_ioequ300h
; adresa unui port de intrare/ieire
mascaequ00100000b; masca pentru selecia bitului D5
.....
tabloudb1,2,3,....
lung_tablouequ $-tablou; lung_tablou va simboliza lungimea tabloului
($ - este un contor care indic adresa locaiei care urmeaz)
Declararea de constante este util pentru a face programul mai inteligibil i pentru a permite parametrizarea unui program. De exemplu n loc s se foloseasc adresa fizic a unui port dintr-o interfa (ex: 3f8h), se definete un nume simbolic (ex: adr_port equ 3f8h) dup care n program se folosete acest nume. Dac adresa portului se schimb (ex: 2F8h) atunci se va modifica doar declaraia de constant i nu toate instruciunile n care apare adresa respectiv.
8.2.2.3 Directive de declarare a procedurilor
Procedurile sau rutinele sunt secvene de program care soluioneaz o anumit funcie i care pot fi apelate din alte secvene. Delimitarea procedurilor se face prin directivele PROC i respectiv ENDP. Aceast delimitare este util mai ales pentru programator, ea fiind de mai mic importan pentru procesorul care execut acea procedur. Mai mult, se pot defini proceduri care nu sunt delimitate prin cele dou directive; o simpl etichet poate fi folosit ca nume de procedur (punct de intrare n procedur). Procesorul va iei din procedur i va reveni la programul apelant doar dac ntlnete o instruciune RET sau IRET i nu ca efect al directivei ENDP. Acest lucru este evident dac inem cont de observaia c "directivele nu se execut". Descompunerea programelor n proceduri este cea mai bun cale de a reduce complexitatea unei aplicaii; se pot defini diferite nivele de abstractizare i diferitele funcii ale aplicaiei sunt ncapsulate In proceduri.
Sintaxa directivelor:
PROC
[[, , ....]]
nume_proc>
ENDP
unde: - este numele dat procedurii
- este o secven de instruciuni care compun procedura respectiv
PROC - directiva care indic nceputul procedurii
ENDP - directiva care indic sfritul procedurii
- parametrii care definesc tipul procedurii; ATENTIE!! nu sunt parametrii formali sau actuali ai procedurii; exemple de parametrii:
- far - arat c procedura este apelat din afara segmentului curent de cod
- near - arat c procedura este apelat numai din segmentul curent de cod
Exemple:
; declararea procedurii
adunare_32proc
; adun dou numere pe 32 bii; Intrri: SI - adresa primului operand
; DI - adresa celui de al doilea operand
;Ieiri: BX - adresa rezultatului
pushax
mov ax, [si]
addax, [di]
mov[bx], ax
movax, [si+2]
adcax, [di+2]
mov[bx+2], ax
popax
ret
adunare_32endp
; apelul procedurii
......
mov si, offset var1
mov di, offset var2
mov bx, offset rez
call adunare_32
......
Pentru claritatea programului este indicat ca la nceputul procedurii s se plaseze mai multe rnduri de comentariu n care s se specifice funcia ndeplinit de procedur, parametrii de intrare i parametrii de ieire.
n limbaj de asamblare nu exist un mecanism de transmitere a parametrilor. Este de datoria programatorului s defineasc o metod de transmitere a parametrilor de intrare i a celor de ieire. Se recomand utilizarea n acest scop a registrelor interne ale procesorului. De asemenea se recomand s se indice o eventual eroare produs n procedur (ex: depire de capacitate) printr-un indicator de condiie (ex: CF=0 rezultat corect, CF=1 rezultat eronat).8.2.2.4 Declararea segmentelor
La arhitectura ISA x86 instruciunile i datele (variabilele) unui program se pstreaz n segmente de memorie. Un program scris n limbaj de asamblare definete n mod uzual cel puin un segment de cod, un segment de stiv i un segment de date. Instruciunile se scriu n segmentul de cod, iar datele se definesc n segmentul de date. Segmentul de stiv se utilizeaz n mod implicit la instruciunile care efectueaz operaii cu stiva. Delimitarea unui segment se face cu directivele SEGMENT i respectiv ENDS.
Sintaxa directivelor:
SEGMENT[[,, ...]]
ENDS
unde: - numele dat segmentului
- secvene de instruciuni i directive care compun segmentul
SEGMENT - directiva de nceput de segment
ENDS - directiva de sfrit de segment
Declaraiile de segmente nu pot fi imbricate sau suprapuse. Definirea unui nou segment se face numai dup ncheierea segmentului anterior. Fizic ns, n urma compilrii i link-editrii mai multe segmente se pot suprapune parial (mai ales n modul real sau virtual). Exemple:
datasegment
var1db12h
falsequ1
....
dataends
codesegment
assume cs:code, ds:data
start: mov ax, data
mov ds, ax
....
code ends
8.2.2.5 Directiva ASSUME
Aceast directiv specific compilatorului coninutul registrelor segment. ATENIE: aceast directiv nu ncarc registrele segment cu constantele specificate, ci indic doar intenia programatorului de a utiliza anumite segmente. ncrcarea registrelor segment se va face n mod obligatoriu prin instruciuni i nu prin directive. Prezena acestei directive este strict necesar la nceputul unui segment de cod. De asemenea se recomand utilizarea directivei ori de cte ori are loc modificarea coninutului unui registru segment.
Informaia specificat de aceast directiv este utilizat de compilator pentru a detecta situaii de eroare n care o variabil sau o etichet nu se afl ntr-un segment indicat de unul din registrele segment; n acest caz variabila sau eticheta nu este accesibil pentru procesor. Sintaxa directivei:
ASSUMECS:[, DS:[,ES:..]unde: - numele unui segment declarat anterior
ASSUME - directiva de declarare a segmentelor folosite
CS, DS, ES, .. - registre segment
8.2.2.6 Directiva END
Aceast directiv marcheaz sfritul programului surs. Orice text care urmeaz acestei directive nu este luat n considerare de compilator. Orice fiier care conine un program n asamblare trebuie s se ncheie cu o astfel de directiv.
Sintaxa directivei:
END []
Eticheta indic punctul de lansare al programului. n lipsa etichetei nceputul programului se consider prima locaie din segmentul de cod. La lansarea programului, n registrul CS se ncarc adresa segmentului de cod care conine eticheta de start, iar n registrul IP (Instruction Pointer) adresa relativ (adresa de offset) a etichetei. 8.2.3 Prototip de program scris n limbaj de asamblare
n continuare se prezint structura tipic a unui program n limbaj de asamblare.
; declararea segmentului de date
datesegment
dateends
; declararea segmentului de cod
codsegment
assume cs:cod, ds:date; declararea modului de ncrcare a registrelor segment
start: mov ax, data
mov ds, ax
; iniializarea registrului segment de date
....
call rutina1
.......
call rutina2
......
mov ax, 4c00h; secven de revenire n sistemul de operare
int 21h
rutina1 proc
; rutina 1
rutina1 endp
rutina2proc
; rutina 2
rutina2 endp
......
cod ends
; sfritul segmentului de cod
end start
; sfritul programului8.3 Mersul lucrrii
1. Se analizeaz asemnrile i deosebirile dintre modul de elaborare a unui program n limbaj de asamblare i ntr-un limbaj de nivel nalt.
2. Se scrie un program simplu n limbaj de asamblare folosind prototipul de program indicat mai sus; programul se salveaz n fiierul "test.asm" 3. Se parcurg fazele de asamblare (compilare), editare de legturi i depanare. n acest scop se lanseaz succesiv un asamblor (MASA sau TASM), un editor de legturi (LINK sau TLINK) i apoi un depanator (Debug sau TD), dup cum urmeaz:
tasm test.asm
tlink test.obj
td test.exe
4. Se corecteaz eventualele erori, n programul surs, dup care se reiau paii anteriori.
5. n programul generat se identific elementele definite n programul surs: segmente, variabile, etichete, instruciuni. Se verific modul de iniializare a variabilelor n memorie.
6. Se implementeaz i se testeaz programele specificate n paragraful urmtor8.4 Exerciii i probleme
1. S se scrie un program care determin valoarea minim i maxim dintr-un ir de 5 valori exprimate pe cte un octet. Cu se modific programul pentru valori pe cuvnt.
2. S se scrie un program care determin numrul de bii de 1 dintr-o valoare reprezentat pe dublucuvant.
3. La introducerea datelor n calculator i respectiv la afiarea rezultatelor sunt necesare diverse conversii. S se scrie proceduri care implementeaz urmtoarele tipuri de conversii:
- conversia unei secvene de 4 cifre zecimale exprimate prin coduri ASCII, ntr-o valoare hexazecimal pe cuvnt- conversia unei secvene de 4 cifre hexazecimale exprimate prin coduri ASCII, ntr-o valoare hexazecimal pe cuvnt
- conversia unui numr hexazecimal reprezentat pe cuvnt ntr-o secven de coduri ASCII.
Procedurile vor fi apelate din programul principal. Iniial se va implementa o singur procedur.
4. S se scrie un program care testeaz funcionarea corect a unei zone de memorie de 16Ko. n acest scop n fiecare locaie se vor scrie succesiv valorile 00, ff, 55 i aa i se va verifica corectitudinea scrierii.
Program surs (.asm)
Modul obiect
(.obj)
TASM, MASM
Program executabil (.exe)
TLINK,
LINK
Modul obiect
Biblioteci
Prog. Pascal,
C, ...
Task
executabil
ncrctor, depanator
12 05 21 AF 34 12 00 ff 41 54 45 58 54 78 56 34 12
var1
x
litera
text
dublu