Programare În Limbaj de Asamblare

S-ar putea să vă placă și

Descărcați ca pdf sau txt
Descărcați ca pdf sau txt
Sunteți pe pagina 1din 39

Universitatea Lucian Blaga din Sibiu

Catedra de Calculatoare i Automatizri

Arpad GELLERT
Rodica BACIU

Programare n Limbaj de Asamblare

Aplicaii

Programare n limbaj de asamblare


Lucrarea nr. 1.
1. Tipuri de date
BYTE (1 octet)
Acest tip de date ocup 1 octet i poate fi reprezentat att n memoria intern, ct i ntr-un registru de 8
bii al procesorului. Interpretrile tipului byte pot fi:

ntreg pe 8 bii cu sau fr semn;


caracter ASCII.

Directiva pentru definirea datelor de acest tip este DB (Define Byte).

WORD (2 octei)
Acest tip de date ocup 2 octei i poate fi reprezentat att n memoria intern, ct i ntr-un registru de
16 bii al procesorului. Interpretrile tipului word pot fi:

ntreg pe 16 bii cu sau fr semn;


secven de dou caractere ASCII;
adres de memorie de 16 bii.

Directiva pentru definirea datelor de acest tip este DW (Define Word). Partea mai puin semnificativ este
memorat la adrese mici. De exemplu dac presupunem ntregul 1234H la adresa 1000H, atunci octetul
34H se va gsi la adresa 1000H, iar octetul 12H la adresa 1001H. Similar, se memoreaz i secvenele de
dou caractere ASCII.

DOUBLE-WORD (4 octei)
Acest tip de date ocup 4 octei i poate fi reprezentat att n memoria intern, ct i ntr-o pereche de
registre de 16 bii sau ntr-un registru de 32 de bii (la procesoarele de 32 de bii). Interpretrile tipului
dword pot fi:

ntreg pe 32 de bii cu sau fr semn;


numr real n simpl precizie;
adres de memorie de 32 de bii.

Directiva pentru definirea datelor de acest tip este DD (Define Double-Word). Valorile mai puin
semnificative se memoreaz la adrese mici. n cazul adreselor pe 32 de bii, adresa de segment este
memorat la adrese mari, iar deplasamentul (offset-ul), la adrese mici.

QUAD-WORD (8 octei)
Acest tip de date ocup 8 octei i poate fi reprezentat att n memoria intern ct i ntr-o pereche de
registre de 32 de bii (numai la procesoarele de 32 de bii). Interpretrile tipului qword pot fi:

ntreg pe 64 de bii cu sau fr semn;


numr real n dubl precizie;

Directiva pentru definirea datelor de acest tip este DQ (Define Quad-Word).

TEN-BYTES (10 octei)


Acest tip de date ocup 10 octei i poate fi reprezentat att n memoria intern, ct i ntr-unul din
registrele coprocesoarelor matematice. Interpretrile tipului tbyte pot fi:

numr ntreg reprezentat ca secven de cifre BCD (mpachetate), cu semn memorat explicit;
numr real n precizie extins.

Directiva pentru definirea datelor de acest tip este DT (Define Ten-Bytes).

2. Registrele procesorului 8086


Toate registrele procesorului 8086 sunt de 16 bii. O serie de registre (AX, BX, CX, DX) sunt
disponibile i la nivel de octet, prile mai semnificative fiind AH, BH, CH i DH, iar cele mai puin
semnificative, AL, BL, CL i DL. Denumirile registrelor sunt: AX-registru acumulator, BX-registru de baz
general, CX-registru contor, DX-registru de date, BP-registru de baz pentru stiv (base pointer), SPregistru indicator de stiv (stack pointer), SI-registru index surs, DI-registru index destinaie. Registrul
FLAGS cuprinde flagurile procesorului i ale bistabililor de condiie, iar registrul IP (instruction pointer)
este contorul program.
Denumirile registrelor de segment sunt: CS-registru de segment de cod (code segment), DS-registru de
segment de date (data segment), SS-registru de segment de stiv (stack segment), ES-registru de segment de
date suplimentar (extra segment). Perechea de registre (CS:IP) va indica adresa urmtoarei instruciuni, iar
perechea (SS:SP) indic adresa vrfului stivei. Registrele DS i ES sunt folosite pentru a accesa date.

3. Moduri de adresare
Modurile de adresare specific modul n care se calculeaz adresa fizic a operandului aflat n
memorie. Adresa fizic (AF) se calculeaz utiliznd:
adresa de segment (AS) adic adresa de nceput a segmentului n care se afl operandul;
adresa efectiv (AE) adica deplasamentul sau offset-ul operandului n cadrul segmentului.
Adresarea imediat
Operandul apare explicit n instruciune:
Ex.:
mov
ax, 1
; pune n AX valoarea 1
add
bx, 2
; adun la BX valoarea 2

Adresare direct
Adresa efectiv a operandului este furnizat printr-un deplasament. Se consider registru de segment
implicit registrul DS, n cazul n care nu se face o explicitare a registrului de segment.
Ex.:
.data
VAL
dw
1
.code
..
mov
bx, VAL
; pune n registrul bx valoarea 1
add
cx, [100]
; adun la registrul cx ceea ce se afl n memorie,
; n segmentul de date la offset-ul 100.
La asamblare, VAL se va nlocui cu deplasamentul n cadrul segmentului de date. Valoarea 100 este offset
explicit.

Adresare indirect (prin registre)


Adresa efectiv a operatorului este dat de coninutul registrelor BX, SI sau DI. Registrul de segment
implicit este DS.
3

Ex.:

mov
mov
add

ax, [bx]
[di], cx
byte ptr [si], 2

; pune n AX coninutul locaiei de memorie de la adresa dat de BX


; memoreaz coninutul lui CX la adresa dat de registrul DI
; adun valoarea 2 la octetul aflat la adresa dat de SI

La ultima instruciune, operatorul byte ptr este absolut necesar altfel nu s-ar cunoaste tipul operandului
(octet, cuvnt) la care se adun 2.

Adresare bazat sau indexat


Adresa efectiv a operandului din memorie se obine adunnd la unul din registrele de baz (BP sau
BX) sau la unul din regitrii index (SI sau DI) un deplasament constant de 8 sau 16 bii. Registrul de
segment implicit este DS (pentru BX, SI) i SS (pentru BP).
Ex.:
.data
VAL dw 10 dup (0)
.code
.
mov
bx, 5
mov
ax, VAL[bx]
mov
ax, bx[VAL]
mov
ax, [bx+VAL]
mov
ax, [bx].VAL
Instruciunile anterioare pun n registrul AX cuvntul din memorie aflat la offset-ul VAL+5.
Observaii:
mov
mov

ax, [bx]
ax, [bp]

; adresare indirect
; adresare bazat cu deplasament nul,
; deoarece registrul BP nu se folosete n adresarea indirect

Adresare bazat i indexat


Adresa efectiv este format prin adresarea unuia din registrele de baz (BX sau BP) cu unul din
registrele index (SI sau DI) i cu un deplasament de 8 sau 16 bii. Registrele de segment implicite sunt DS
pentru BX cu SI sau DI i SS pentru BP cu SI sau DI.
Ex.:
mov
ax, [bx][si]
mov
ax, [bx+si+7]
mov
ax, [bx+si].7
mov
ax, [bp][di][7]
Observaii: la toate modurile de adresare se poate utiliza un registru de segment explicit, n felul urmtor:
mov
bx, ds:[bp+7]
; adresare bazat
mov
ax, cs:[si][bx+3] ; adresare bazat i indexat
mov
ax, ss:[bx]
; adresare indirect.

4. Aplicaii
Se cere obinerea fiierului executabil pentru urmtoarea poriune de cod i rularea apoi pas cu pas.
.model small
.stack 100
.data
tabel
tabel1
tabel2
tabel3
tabel4
.code

db 1, 2, 3, 4, 5, 10 dup(?)
dw 1, 2, 3, 12H, 12
dd 1, 2, 1234H
dq 1, 2, 12345678H
dt 1, 2,, 1234567890H

start:

mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
int

ax, @data
ds, ax
ax, 14h
;adresare imediat
ax, 14
al, tabel
;adresare direct
al, tabel[1]
;adresare direct
ax, word ptr tabel
;adresare direct - operatorul ptr este necesar,
ax, word ptr tabel[2]
;tabel fiind definit cu directiva DB
bx, offset tabel
al, [bx+1]
;adresare indirect
al, [bx]
;adresare indirect
bx, 5
al, tabel[bx]
;adresare bazat
si, 1
al, [bx][si]
;adresare bazat i indexat
si, 6
byte ptr [bx][si],2
;adresare bazat i indexat
bp, offset tabel
al, [bp]
;adresare bazat cu deplasament nul
byte ptr ds:[bp][si][1], 7
word ptr ds:[bp][si][1], 19H ;adresare bazat i indexat
ah, 4ch
21h

end start
Indicaii
Pentru obinerea fiierului executabil se va utiliza mediul Borland C sau Borland Pascal de dezvoltare a
programelor. Fazele de obinere a programului executabil din fiierul ASCII salvat cu extensia *.asm sunt:
asamblarea: tasm *.asm/zi/la
- zi este folosit pentru includerea opiunilor de depanare;
- la este folosit pentru obinerea unui fiier listing util n depanare;
linkeditarea: tlink *.obj/v
- v este folosit pentru includerea opiunilor de depanare;
depanarea: td *.exe
Dup obinerea fiierului executabil acesta va fi executat pas cu pas n mediul de depanare. Se va
vizualiza coninutul memoriei (View/Dump) i al registrelor (View/Registers) nainte i dup executarea
fiecrei instruciuni. Se va verifica pentru fiecare dat definit numrul octeilor alocai n memorie i
respectarea conveniei Intel pentru memorarea acestora.

Probleme propuse spre rezolvare


1.
2.
3.
4.

5.
6.

7.

n aplicaia de mai sus, care sunt instruciunile care modific coninutul unei locaii de memorie?
n aplicaia de mai sus s se determine care este adresa la care se ncarc segmentul de date. Pentru
aceasta se vor executa primele dou instruciuni ale programului.
Pentru aplicaia de mai sus s se specifice pentru fiecare zon a programului (date, cod, stiv) care este
adresa de segment i care este adresa de offset la nceputul execuiei programului.
Pentru aplicaia de mai sus s se determine care este adresa fizic a locaiei de memorie la care se
memoreaz valoarea 5 din tabel. Fiecare student va determina aceast adres pentru contextul de pe
calculatorul pe care lucreaz.
Pentru aplicaia de mai sus s se determine ci octei s-au alocat pentru memorarea datelor. S se
verifice i numrnd octeii n fereastra Dump.
Specificai adresa efectiv i adresa fizic a locaiei de memorie modificat de instruciunile:
mov
byte ptr [bx][si], 2
mov
byte ptr ds:[bp][si][1], 7
mov
word ptr ds:[bp][si][1], 19H
Motivai apariia valorii 00H (n loc de 01H) n registrul AL, n urma execuiei instruciunii:
mov
al, [bp].
5

Programare n limbaj de asamblare


Lucrarea nr. 2.
1. Definirea i iniializarea datelor
Constante
O constant este un simplu nume asociat unui numr i nu are caracteristici distinctive.
Tip
binare
octale
zecimale
hexazecimale
ASCII

Reguli
secvene de 0, 1 urmate de B sau b
secvene de 07 urmate de O sau Q
secvene de 09 opional urmate de D sau d
secvene de 09 i AF urmate de H sau h
ir de caractere

Exemple
11B, 1011b
777Q, 567O
3309, 1309D
55H, 0FEh
BC

Constantele pot apare explicit n program:


mov
ah, 5
mov
ax, 256
sau ca valori asignate unor simboluri (constante simbolice):
five
equ 5
mov
ah, five

Variabile
Variabilele identific datele manipulate, formnd operanzi pentru instruciuni. Se definesc utiliznd
directivele DB, DW, DD, DQ, DT. Aceste directive aloc i iniializeaz memoria n uniti de octei,
cuvinte, dublu cuvinte, etc.
nume

directiv

lista_de_valori

Numelui variabilei i se asociaz urmtoarele atribute:


segment: variabil asociat cu segmentul curent
offset: variabil asignat offset-ului curent fa de nceputul segmentului
tip: 1 octet pentru DB, 2 octei pentru DW, etc.
Lista de valori poate cuprinde:
expresie constant
caracterul ? pentru iniializri nedeterminate
expresie de tip adres
un ir ASCII cu mai mult de dou caractere (numai cu directiva DB)
expresie DUP (expresie1 [, expresie2, ])

Etichete
Etichetele identific cod executabil, formnd operanzi pentru CALL, JMP sau salturi condiionate. O
etichet poate fi definit:
prin numele etichetei urmat de caracterul : - se definete astfel o etichet de tip near
nume_etichet:
Ex.:
eticheta: mov ax, bx
prin directiva LABEL, cu forma general
nume label tip
Dac ceea ce urmeaz reprezint instruciuni (cod), tipul etichetei va fi NEAR sau FAR i eticheta va fi
folosit ca punct int n instruciuni de tip JMP/CALL. Daca ceea ce urmeaz reprezint definiii de
date, tipul etichetei va fi BYTE, WORD, DWORD, etc.

De exemplu, n urma definiiei:


alfab label byte
alfaw dw 1234H
o instruciune de forma mov al, alfab va pune n AL octetul mai puin semnificativ al cuvntului (34H).

prin directiva PROC, numele procedurii fiind interpretat ca o etichet cu tipul derivat din tipul
procedurii (NEAR sau FAR). Forma general a unei proceduri este:
nume_proc proc tip

nume_proc endp

2. Instruciuni de transfer

instruciuni de transfer generale: MOV, XCHG, PUSH, POP


instruciuni de transfer specifice acumulatorului: IN, OUT, XLAT
instruciuni de transfer specifice adreselor: LEA, LDS, LES
instruciuni de transfer specifice indicatorilor de condiii: LAHF, SAHF, PUSHF, POPF

2.1. Instruciuni de transfer generale


Instruciunea MOV (Move Data - Transfer date)
Forma general este:
mov dest, sursa

; dest src

Urmtoarele operaii sunt ilegale:


sursa i destinaia nu pot fi ambele operanzi n memorie;
nu pot fi folosite registrele FLAGS i IP;
operanzii nu pot avea dimensiuni diferite;
registrul CS nu poate aprea ca destinaie;
nu pot fi transferate date imediate ntr-un registru de segment;
operanzii nu pot fi simultan registre de segment
Exemple:
mov
ax, bx
mov
al, ch
mov
val[bx][si], al
mov
byte ptr [bx+100], 5
O instruciune de forma:
.data
ALFA db 1
.code
mov al, ALFA
ncarc n AL coninutul locaiei de memorie ALFA. Dac se dorete ncrcarea adresei efective a variabilei
ALFA, se poate folosi operatorul OFFSET:
mov
bx, offset ALFA

Instruciunea XCHG (Exchange Data - Interschimb date)


Forma general este:
XCHG dest, sursa
Restricii:

; sursa dest

cel puin un operand trebuie s fie n registru;


registrele de segment nu pot fi operanzi.

Exemple:
xchg

ax, bx

Secven de instruciuni pentru schimbarea coninutului a dou locaii de memorie:


mov
ax, alfa1
xchg
ax, alfa2
mov
alfa1,ax

Instruciunea PUSH (Push Data - Salveaz date n stiv)


Forma general:
push sursa
SP SP-2
SS: [SP+1] high(sursa)
SS:[SP] low(sursa)
Sursa pote fi un operand pe 16 bii aflat n:
registru general de 16 bii
registru de segment
locaie de memorie
Exemple:
push
push
push
push

bx
beta
[bx]
[bp+5]

; SS:[SP] BX
; coninutul memoriei de la adresa beta se memoreaz n stiv
; SS:[SP] DS:[BX]
; SS:[SP] SS:[BP+5]

Instruciunea POP (Pop Data - Ref date din stiv)


Forma general:
pop dest
high(dest) SS: [SP+1]
low(sursa) SS:[SP]
SP SP+2
Destinaia pote fi un operand pe 16 bii aflat n:
registru general de 16 bii
registru de segment
locaie de memorie
Exemple:
pop
pop
pop

cx
es:[di]
[bp+5]

; CX SS:[SP]
; ES:DI SS:[SP]
; SS:[BP+5] SS:[SP]

Accesul la informaiile memorate n stiv se poate face fr descrcarea acesteia, utilizd adresarea bazat:
mov
bp, sp
; baza stivei
push
ax
; SP BP-2
push
bx
; SP BP-4
mov
ax, [bp-2]
mov
bx, [bp-4]

2.2. Instruciuni de transfer specifice acumulatorului


Instruciunea IN (Input Data - Citete date de la port de intrare)
Forma general este:
in dest, port
Instruciunea transfer un octet sau un cuvnt de la un port de intrare n acumulator (AL sau AX). Port
poate fi registrul DX, sau o constant n intervalul 0255.

Instruciunea OUT (Output Data - Scrie date la port de ieire)


Forma general este:
out port, sursa
Instruciunea transfer un octet sau un cuvnt din registrul AL sau AX la un port de ieire.
Exemple:
in
in

al, 0f8h
al, 0f9h

; citire stare de la un echipament


; citire date de la acelai echipament

Instruciunea XLAT (Translate - Translateaz)


Instruciunea nu are operanzi, iar semnificaia este:
AL DS:[BX+AL]
Adic aduce n AL coninutul octetului de la adresa efectiv [BX+AL].

2.3. Instruciuni de transfer specifice adreselor


Instruciunea LEA (Load Effective Address - ncarc adresa efectiv)
Forma general este:
LEA registru, sursa
ncarc adresa efectiv a operandului surs n registrul specificat. Sursa este un operand aflat n memorie.
Exemple:
lea
lea

bx, alfa
di, alfa[bx][si]

; echivalent cu instruciunea mov bx, offset alfa

Instruciunile LDS (Load Data Segment - ncarc DS) i LES (Load Extra Segment - ncarc ES)
Forma general este:
lds
reg, sursa
les
reg, sursa
n care reg este un registru general de 16 bii, iar sursa este un operand de tip double-word aflat n memorie,
care conine o adres complet de 32 de bii. Aceast adres se ncarc n perechea DS:reg, respectiv
ES:reg, astfel nct cuvntul mai puin semnificativ (adresa efectiv) va fi n registrul reg, iar cuvntul mai
semnificativ (adresa de segment) va fi n DS(ES).

Exemple:
.data
x db 10
y db 15
adr_x dd x
adr_y dd y

; adr_x este adresa valorii x (adresde tip pointer)


; adr_y este adresa valorii y (adresde tip pointer)

.code
...
lds si, adr_x
les di, adr_y
mov byte ptr [si], 20
; valoarea 20 se memoreaz n locul valorii 10
mov byte ptr es:[di], 30 ; valoarea 30 se memoreaz n locul valorii 15
2.4. Instruciuni de transfer specifice indicatorilor de condiie
Instruciunea LAHF (Load AH with FLAGS - ncarc AH cu FLAGS)
AH FLAGS0:7
Instruciunea SAHF (Store AH into FLAGS - Depune AH n FLAGS)
FLAGS0:7 AH
Instruciunea PUSHF (Push Flags - Salveaz FLAGS n stiv)
SP SP-2
SS: [SP+1] high(FLAGS)
SS:[SP] low(FLAGS)
Instruciunea POPF (Pop Flags - Reface FLAGS din stiv)
high(FLAGS) SS: [SP+1]
low(FLAGS) SS:[SP]
SP SP+2

3. Aplicaii
1. Se cere rularea pas cu pas a urmtorului program:
.model small
.stack 100
.data
tabc db '0123456789ABCDEF'
.code
start:

mov
mov
mov
repet: mov
push
xlat
call
pop
inc
cmp
jz
jmp
afisare proc
mov
mov
int
mov
mov
int

ax,@data
ds,ax
al,0
bx,offset tabc
ax
afisare
ax
al
al,10H
sfarsit
repet
dl,al
ah,2h
21h
dl,' '
ah,2h
21h

;iniializeaz AL
;pune n BX adresa efectiv tabc
;salveaz AL n stiv
;pune n AL octetul de la adresa efectiv [BX+AL]
;apelul procedurii afisare

;se verific dac s-au afiat toate caracterele

;pune n DL codul caracterului care trebuie afiat


;funcia DOS pentru afiarea caracterului din DL

10

ret
afisare endp
sfarsit: mov
int
end

ax,4c00h
21h
start

;funcia DOS de ieire n sistemul de operare

2. De ce este necesar salvarea n stiv a registrului AX, iar apoi restaurarea ei?
3. Modificai programul de mai sus pentru determinarea ptratului unui numr din intervalul 0-15.
4. Se cere rularea pas cu pas a urmtorului program:
.model small
.stack 100
.data
adr1
dw 1234h
adr2
dw 5678h
adr3
dw 9012h
adr4
dw 3456h
tabela dd adr1, adr2, adr3, adr4
.code
start:
mov
ax, @data
mov
ds, ax
mov
cx, 1
mov
bx, cx
add
bx, bx
add
bx, bx
les
di, tabela[bx]
mov
ax, es:[di]
mov
ah, 4ch
int
21h
end
start
5. Modificai programul de mai sus astfel nct s fie pus n AX valoarea care se afl la adr4.
6. Care din instruciunile urmtoare sunt corecte?
mov
al, si
mov
ds, es
mov
ax, ip
mov
bl, al
mov
cs, 23H
7. Care este efectul urmtoarei secvene de instruciuni?
.data
alfa
db 14H
tabel
db 0A1H, 10, 0AFH, 23Q, 1111B, 0011B
.code

lea
bx, tabel
mov
si, 3
mov
al, [bx][si]
8. Care este coninutul locaiei alfa dup executarea urmoarei secvene de instruciuni?
.data
alfa
db 23h
beta
db 43h
.code

mov
al, alfa
xchg
al, beta
mov
alfa, al

11

Programare n limbaj de asamblare


Lucrarea nr. 3.

Instruciuni aritmetice i logice

1.

instruciuni specifice adunrii: ADD, ADC, INC, DAA, AAA


instruciuni specifice scderii: SUB, SBB, DEC, NEG, CMP, DAS, AAS
instruciuni specifice nmulirii: CBW, CWD, MUL, IMUL, AAM
instruciuni specifice mpririi: DIV, IDIV, AAD
instruciuni logice: NOT, AND, TEST, OR, XOR
instruciuni de deplasare: SHL, SAL, SHR, SAR
instruciuni de rotaie: ROL, RCL, ROR, RCR

Instruciuni specifice adunrii

Instruciunea ADD (Add - Adun)


ADD dest, sursa
dest dest + sursa
Instruciunea ADC (Add with Carry - Adun cu transport)
ADC dest, sursa
dest dest + sursa + CF
Instruciunea INC (Increment - Incrementeaz)
INC dest
dest dest + 1
Instruciunea DAA (Decimal Adjust for Addition - Corecie zecimal dup adunare)
Instruciunea nu are operanzi i efectueaz corecia zecimal a acumulatorului AL, dup o adunare cu
operanzi n format BCD mpachetat. S considerm, de exemplu, adunarea valorilor BCD 65 i 17. Aceste
valori se reprezint prin octeii 65H i 17H. n urma adunrii, se obine rezultatul 7CH, care este incorect ca
rezultat BCD. Operaia de corecie conduce la rezultatul 82H, ceea ce reprezint suma BCD a celor dou
valori.
Instruciunea AAA (ASCII Adjust for Addition - Corecie ASCII dup adunare)
Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup operaii de adunare cu
operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, adunarea valorilor
0309H i 0104H, care ar corespunde valorilor BCD despachetate 39 i 14. n urma adunrii, se obine
rezultatul 040DH. Instruciunea AAA corecteaz acest rezultat la 0503H care este suma BCD a celor dou
valori.

2.

Instruciuni specifice scderii

Instruciunea SUB (Substract - Scade)


SUB dest, sursa
dest dest - sursa
Instruciunea SBB (Substract with Borrow - Scade cu mprumut)
SBB dest, sursa
dest dest - sursa - CF
Instruciunea DEC (Decrement - Decrementeaz)
DEC dest
dest dest - 1

12

Instruciunea NEG (Negate - Schimb semnul)


NEG dest
dest 0 - dest
Instruciunea CMP (Compare - Compar)
CMP dest, sursa
Execut scderea temporar dest - sursa fr a modifica vreun operand, dar cu poziionarea bistabililor de
condiie (FLAGS)
Instruciunea DAS (Decimal Adjust for Substraction - Corecie zecimal dup scdere)
Instruciunea nu are operanzi i efectueaz corecia zecimal a acumulatorului AL, dup o scdere cu
operanzi n format BCD mpachetat. S considerm, de exemplu, scderea valorilor BCD 52 i 24. Operaia
de corecie conduce la rezultatul 28H (52-24=28).
Instruciunea AAS (ASCII Adjust for Substraction - Corecie ASCII dup scdere)
Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup operaii de scdere cu
operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, scderea valorilor
0502H i 0204H. Instruciunea AAS corecteaz rezultatul la 0208H.

3. Instruciuni specifice nmulirii


Instruciunea CBW (Convert Byte to Word - Convertete octet la cuvnt)
Extinde bitul de semn din AL la ntreg registrul AH, obinndu-se astfel o reprezentare a lui AL pe 2 octei.
Instruciunea CWD (Convert Word to DoubleWord - Convertete cuvnt la dublu-cuvnt)
Extinde bitul de semn din AX la ntreg registrul DX, obinndu-se astfel o reprezentare a lui AX pe 4 octei.
Instruciunea MUL (Multiply - nmulete fr semn)
MUL sursa
AH:AL AL * sursa
(dac sursa este pe octet)
DX:AX AX * sursa
(dac sursa este pe 2 octei)
Instruciunea IMUL (Integer Multiply - nmulete cu semn)
IMUL sursa
Este similar cu instruciunea MUL. Deosebirea este c operaia de nmulire se face considernd operanzii
numere cu semn.
Instruciunea AAM (ASCII Adjust for Multiply - Corecie ASCII dup nmulire)
Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup o nmulire pe 8 bii cu
operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, nmulirea valorilor 5 i
9. Instruciunea AAM corecteaz rezultatul 2DH la 0405H.

4.

Instruciuni specifice mpririi

Instruciunea DIV (Divide - mparte fr semn)


DIV sursa
Dac sursa este pe octet:
AL AX / sursa
AH AX mod sursa
Dac sursa este pe 2 octei:
AX DX:AX / sursa
DX DX:AX mod sursa
Instruciunea IDIV (Integer Divide - mparte cu semn)
IDIV sursa
Este similar cu instruciunea DIV. Deosebirea este c operaia de mprire se face considernd operanzii
numere cu semn.

13

Instruciunea AAD (ASCII Adjust for Division - Corecie ASCII nainte de mprire))
Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX. Operaia de corecie trebuie fcut
nainte de mprirea unui numr BCD pe 2 octei la un numr BCD pe un octet.

5.

Instruciuni logice

Instruciunea NOT (Not - Negare logic bit cu bit)


NOT dest
Instruciunea AND (And - i logic bit cu bit)
AND dest, sursa
Instruciunea TEST (Test - Testeaz)
TEST dest, sursa
Efectul este execuia unei operaii AND ntre cei doi operanzi, fr a se modifica destinaia, dar cu
poziionarea flagurilor la fel ca la instruciunea AND.
Instruciunea OR (Or - Sau logic bit cu bit)
OR dest, sursa
Instruciunea XOR (Exclusive Or - Sau-exclusiv bit cu bit)
XOR dest, sursa

6.

Instruciuni de deplasare

Instruciunea SHL/SAL (Shift Logic/Arithmetic Left - Deplaseaz logic/aritmetic la stnga)


SHL operand, contor
SAL operand, contor
Bitul cel mai semnificativ trece n CF, dup care toi biii se deplaseaz la stnga cu o poziie. Bitul cel mai
puin semnificativ devine 0. Numrul operaiilor este dat de contor.
Instruciunea SHR (Shift Logic Right - Deplaseaz logic la dreapta)
SHR operand, contor
Bitul cel mai puin semnificativ trece n CF, dup care toi biii se deplaseaz la dreapta cu o poziie. Bitul
cel mai semnificativ devine 0. Numrul operaiilor este dat de contor.
Instruciunea SAR (Shift Arithmetic Right - Deplaseaz aritmetic la dreapta)
SAR operand, contor
Singura diferen fa de instruciunea SHR, este c se conserv bitul de semn, mai precis, completarea
dinspre stnga se face cu bitul de semn.

7.

Instruciuni de rotire

Instruciunea ROL (Rotate Left - Rotete la stnga)


ROL operand, contor
Bitul cel mai semnificativ trece att n CF, ct i n bitul cel mai puin semnificativ, dup ce toi biii s-au
deplasat la stnga cu o poziie. Numrul operaiilor este dat de contor.
Instruciunea RCL (Rotate Left through Carry- Rotete la stnga prin carry)
RCL operand, contor
Bitul cel mai semnificativ trece n CF, toi biii se deplaseaz la stnga cu o poziie, iar CF original trece n
bitul cel mai puin semnificativ. Numrul operaiilor este dat de contor.
Instruciunea ROR (Rotate Right - Rotete la dreapta)
ROR operand, contor
Bitul cel mai puin semnificativ trece att n CF, ct i n bitul cel mai semnificativ, dup ce toi biii s-au
deplasat la dreapta cu o poziie. Numrul operaiilor este dat de contor.

14

Instruciunea RCR (Rotate Right through Carry- Rotete la dreapta prin carry)
RCR operand, contor
Bitul cel mai puin semnificativ trece n CF, toi biii se deplaseaz la dreapta cu o poziie, iar CF original
trece n bitul cel mai semnificativ. Numrul operaiilor este dat de contor.

Aplicaii
1.

2.

3.

4.

5.
6.
7.
8.

Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni:


mov
al, 10011110b
mov
cl, 3
rol
al, cl
Care va fi coninutul registrului CX dup executarea urmtoarei secvene de instruciuni:
mov
bx, sp
mov
cx, 2134H
push
cx
mov
byte ptr ss:[bx-2], 22H
pop
cx
Care este coninutul registrului AX dup executarea urmtoarei secvene de instruciuni:
mov
cl, 4
mov
ax, 0702H
shl
al, cl
shr
ax, cl
Care este coninutul registrului AX dup executarea urmtoarei secvene de instruciuni:
mov
cx, 1234H
push
cx
mov
bx, 2359H
push
bx
mov
ax, 4257H
mov
bp, sp
mov
byte ptr [bp], al
pop ax
S se scrie un program care adun numerele 145A789FH i 92457ABCH, afind rezultatul pe ecran.
S se scrie un program care adun dou numere n format BCD mpachetat. Fiecare din cele dou
numere are 4 cifre. Numerele sunt memorate n zona de date. Programul afieaz rezultatul adunrii.
S se scrie un program care adun dou numere n format BCD despachetat. Fiecare din cele dou
numere are 4 cifre. Numerele sunt memorate n zona de date. Programul afieaz rezultatul adunrii.
S se scrie un program care afieaz pe ecran ptratul unui numr. Se va folosi instruciunea XLAT.

15

Programare n limbaj de asamblare


Lucrarea nr. 4.

Instruciuni de apel de procedur i de salt


Forma general pentru definirea unei proceduri este:
nume_proc PROC [FAR | NEAR]

RET
nume_proc ENDP
unde nume_proc este numele procedurii, iar parametrii opionali FAR sau NEAR indic tipul procedurii.
Procedurile sunt de dou tipuri: FAR i NEAR. O procedur FAR poate fi apelat i din alte segmente de
cod dect cel n care este definit, pe cnd o procedur NEAR poate fi apelat numai din segmentul de cod
n care este definit. Dac se omit parametrii FAR sau NEAR, tipul procedurii este dedus din directivele
simplificate de definire a segmentelor (modelul de memorie folosit). De exemplu , modelul LARGE
presupune c toate procedurile sunt implicit de tip FAR.
n mod corespunztor, exist apeluri de tip FAR, respectiv NEAR, precum i instruciuni de
revenire de tip FAR, respectiv NEAR. Instruciunea RET (Return) provoac revenirea n programul apelant;
tipul instruciunii este dedus din tipul procedurii (NEAR sau FAR). Putem folosi o instruciune de revenire
explicit: RETN (Return Near) sau RETF (Return Far).

1.

Apelul procedurilor i revenirea din proceduri

Instruciunea CALL (Apel de procedur)


CALL nume_proc
CALL FAR PTR nume_proc
CALL NEAR PTR nume_proc
n primul caz, tipul apelului este dedus din tipul procedurii, iarn celelalte este specificat explicit (FAR sau
NEAR). Tipul apelului trebuie s coincid cu tipul procedurii i cu tipul instruciunilor Return din interiorul
procedurii, altfel se ajunge la funcionri defectuoase ale programului. n cazul unui apel de procedur de
tip NEAR, se salveaz n stiv coninutul registrului IP, care reprezint adresa de revenire, iar apoi n IP se
ncarc adresa primei instruciuni din procedur. n cazul unui apel de tip FAR, se salveaz n stiv CS:IP,
adresa complet de revenire (pe 32 de bii), iar apoi n CS:IP se ncarc adresa primei instruciuni din
procedur.
Instruciunea RET (Return - Revenire din procedur)
RET
RETF
RETN
n primul caz, tipul tipul instruciunii este dedus din tipul procedurii. n cazul unei reveniri de tip NEAR, se
reface registrul IP din stiv, astfel se transfer controlul la instruciunea care urmeaz instruciunii CALL
care a provocat apelul procedurii. n cazul unei reveniri de tip FAR, se reface din stiv perechea de registre
CS:IP.
Instruciunea JMP (Jump - Salt)
JMP
tinta
JMP
SHORT PTR
tinta
JMP
NEAR PTR
tinta
JMP
FAR PTR
tinta
n primul caz, tipul saltului este dedus din atributele expresiei care precizeaz inta. inta specific adresa
de salt i poate fi o etichet sau o expresie. Exist trei tipuri de instruciuni de salt:
SHORT - adresa int se afl la o adres n domeniul [-127, +127] fa de adresa instruciunii de salt;
NEAR - adresa int este n acelai segment de cod cu instruciunea de salt;
FAR - adresa int poate fi n alt segment de cod fa de instruciunea de salt.

16

2.

Tipuri de salt/apel

JMP/CALL direct
Operandul care se afl n formatul instruciunii este o etichet care identific adresa int. Poate fi de dou
tipuri:
salt/apel direct intrasegment (NEAR) - eticheta este n acelai segment de cod cu instruciunea
JMP/CALL;
salt/apel direct intersegment (FAR) - eticheta poate fi definit i n alt segment de cod dect cel care
conine instruciunea JMP/CALL.
JMP/CALL indirect
Operandul care apare n formatul instruciunii reprezint o adres de memorie. Poate fi de dou tipuri:
salt/apel indirect intrasegment (NEAR), cu forma general
JMP/CALL expr
n care expr precizeaz adresa efectiv a intei i poate fi un registru, o variabil de tip WORD, sau un
cuvnt din memorie;
salt/apel indirect intersegment (FAR), cu forma general
JMP/CALL expr
n care expr precizeaz adresa complet a intei i poate fi o variabil de tip DWORD, sau un dublucuvnt din memorie.

3.

Instruciuni de salt condiionat

Instruciunile din aceast categorie implementeaz salturi condiionate de valoarea unor bistabili (FLAGS).
Dac condiia nu este ndeplinit, saltul nu are loc, deci execuia continu cu instruciunea urmtoare. Toate
instruciunile de salt condiionat sunt de tip SHORT, ceea ce nseamn c adresa int trebuie s fie la o
distan cuprins ntre -127 i +127 de octei fa de instruciunea de salt. n tabelul urmtor se prezint
instruciunile de salt condiionat:
Instruciune
JE, JZ
JL, JNGE
JLE, JNG
JB, JNAE, JC
JBE, JNA
JP, JPE
JO
JS
JNE, JNZ
JNL, JGE
JNLE, JG
JNB, JAE, JNC
JNBE, JA
JNP, JPO
JNO
JNS

Condiie de salt
ZF = 1
SF OF
SF OF sau ZF = 1
CF = 1
CF = 1 sau ZF = 1
PF = 1
OF = 1
SF = 1
ZF = 0
SF = OF
SF = OF i ZF = 0
CF = 0
CF = 0 i ZF = 0
PF = 0
OF = 0
SF = 0

Interpretare
Zero, Equal
Less, Not Greater or Equal
Less or Equal, Not Greater
Below, Not Above or Equal, Carry
Below or Equal, Not Above
Parity, Parity Even
Overflow
Sign
Not Zero, Not Equal
Not Less, Greater or Equal
Not Less or Equal, Greater
Not Below, Above or Equal, Not Carry
Not Below or Equal, Above
Not Parity, Parity Odd
Not Overflow
Not Sign

La comparaiile cu semn folosim GREATER i LESS, iar la comparaiile fr semn folosim ABOVE i
BELOW.
Uneori este necesar s folosim instruciuni de salt condiionat la etichete care ies n afara
domeniului [-127, +127] fa de instruciunea curent. n aceast situaie nlocuim saltul pe o condiie
direct departe cu un salt pe condiia negat aproape i cu un salt necondiionat departe. n urmtorul
exemplu, eticheta et1 se afl n afara domeniului, astfel instruciunea:
JE et1
se nlocuiete cu:
JNE et2
JMP et1
et2:

17

4.

Instruciuni pentru controlul buclelor de program

Instruciunea JCXZ (Jump if CX is Zero - Salt dac CX este zero)


JCXZ eticheta
Eticheta trebuie s se afle n domeniul [-127, +127] fa de instruciunea curent. Se face salt la eticheta
specificat dac CX conine valoarea 0.
Instruciunea LOOP (Ciclare)
LOOP eticheta
Aceast instruciune este, de fapt, un salt condiionat de valoarea registrului CX. Cu alte cuvinte, se
decrementeaz CX i, dac acesta este diferit de zero, se sare la eticheta specificat. Eticheta trebuie s se
afle n domeniul [-127, +127] fa de instruciunea curent.
Instruciunea LOOPZ/LOOPE (Loop While Zero/Equal - Cicleaz ct timp este zero/egal)
LOOPZ eticheta
LOOPE eticheta
Se decrementeaz CX i, dac acesta este diferit de zero i ZF este 1 (rezultatul ultimei operaii a fost zero),
se sare la eticheta specificat.
Instruciunea LOOPNZ/LOOPNE (Loop While Not Zero/Equal - Cicleaz ct timp nu este zero/egal)
LOOPNZ eticheta
LOOPNE eticheta
Se decrementeaz CX i, dac acesta este diferit de zero i ZF este 0 (rezultatul ultimei operaii a fost zero),
se sare la eticheta specificat.

Aplicaii
1.

Rulai pas cu pas urmtorul program:


.model small
.stack 512
.data
tab_proc dw proc_1
dw proc_2
dw proc_3
tab_procf dd procf_1
dd procf_2
dd procf_3
intra
dw etich1
dw etich2
dw etich3
inter
dd etif1
dd etif2
.code
proc_1 proc
push dx
pop dx
ret
proc_1 endp
proc_2 proc
push dx
pop dx
ret
proc_2 endp
proc_3 proc
push dx
pop dx
ret
proc_3 endp
procf_1 proc far
push dx
pop dx
ret
procf_1 endp
procf_2 proc far
push dx
pop dx

18

ret
procf_2 endp
procf_3 proc far
push dx
pop dx
ret
procf_3 endp
start:
mov
ax, @data
mov
ds, ax
mov
si, 0
jmp
inter[si]
etif2
label
far
jmp
intra
proced: lea
bx, proc_1
call
bx
call
tab_proc
mov
si, 2
call
tab_proc[si]
lea
bx, tab_proc
call
word ptr [bx]
mov
si, 4
call
word ptr [bx][si]
call
tab_procf
mov
si, 4
call
tab_procf[si]
lea
bx, tab_procf
call
dword ptr [bx]
mov
si, 4
call
dword ptr [bx][si]
jmp
sfarsit
etich1:
mov
si, 2
jmp
intra[si]
etich3
label near
jmp
proced
etich2
label near
lea
bx, intra
jmp
word ptr [bx+4]
etif1
label far
lea
bx, inter
mov
si, 4
jmp
dword ptr [bx][si]
sfarsit:mov ah, 4ch
int
21h
end
start

2.
3.
4.

5.

S se scrie un program care s afieze rezultatul obinut n urma conversiei unui numr hexazecimal n
zecimal.
S se scrie un program care s calculeze factorialul unui numr i apoi s afieze rezultatul.
Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni:
mov
al, A
mov
bl, B
cmp
al, bl
jne
et1
et2:
mov
al, 1
jmp
sfarsit
et1:
mov
al, 0
jmp
sfarsit
Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni:
masca equ 01000000b
mov
al,
10110101b
test
al,
masca
jz
et1
et2:
mov
al,
1
jmp
sfarsit
et1:
mov
al,
0
jmp
sfarsit

19

Programare n limbaj de asamblare


Lucrarea nr. 5.

Instruciuni pentru operaii cu iruri


Prin ir se nelege o secven de octei sau de cuvinte, aflate la adrese succesive de memorie. Setul de
instrucini cuprinde operaii primitive (la nivel de octet sau cuvnt) i prefixe de repetare, care pot realiza
repetarea operaiilor primitive de un numr fix de ori sau pn la ndeplinirea unei condiii de tip
comparaie. Denumirea instruciunilor fr operanzi la nivel de octet se termin cu litera B, iar a celor la
nivel de cuvnt cu litera W. Aceste instruciuni folosesc registrele DS:SI ca adres surs i ES:DI ca adres
destinaie. Exist i variantele cu operanzi ale acestor instruciuni, i ele se folosesc n situaia n care se
utilizeaz alt segment pentru irul surs, dect segmentul de date implicit (DS). Toate aceste instruciuni
incrementeaz (dac DF este 0) sau decrementeaz (dac DF este 1) n mod automat adresele (regitrii SI,
DI) cu 1 sau cu 2, dup cum operaia este la nivel de octet sau de cuvnt. Starea flagului DF poate fi
modificat prin instruciunile CLD (Clear Direction) i STD (Set Direction), care terg, respectiv seteaz
acest bistabil.

1. Operaii primitive
Instruciunile MOVSB, MOVSW (Move String - Copiaz ir)
MOVSB
MOVSW
ES:DI DS:SI
SI SI + delta
DI DI + delta
Instruciunile CMPSB, CMPSW (Compare String - Compar iruri)
CMPSB
CMPSW
DS:SI - ES:DI
SI SI + delta
DI DI + delta
Instruciunile LODSB, LODSW (Load String - ncarc ir)
LODSB
LODSW
acumulator DS:SI
SI SI + delta

(acumulator este AX sau AL n funcie de tipul operaiei)

Instruciunile STOSB, STOSW (Store String - Depune ir)


STOSB
STOSW
ES:DI acumulator
DI DI + delta

(acumulator este AX sau AL n funcie de tipul operaiei)

20

Instruciunile SCASB, SCASW (Scan String - Cutare n ir)


SCASB
SCASW
acumulator - ES:DI
DI DI + delta

(acumulator este AX sau AL n funcie de tipul operaiei)

2. Prefixe de repetare
Prefixele de repetare permit execuia repetat a unei operaii primitive cu iruri de octei sau de cuvinte,
funcie de un contor de operaii sau de un contor i o condiie logic. Aceste prefixe nu sunt instruciuni n
sine, ci particip la formarea unor instruciuni compuse, alturi de operaiile primitive descrise mai sus.
Prefixul de repetare REP (Repeat - Repet)
REP op_primitiva
Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero. De
obicei se folosete la primitivele de tip MOVS, LODS i STOS.

Prefixul de repetare REPE/REPZ (Repeat While Zero/Equal - Repet ct timp este zero/egal)
REPE/REPZ op_primitiva
Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero i
rezultatul operaiei primitive este 0. De obicei se folosete la primitivele de tip CMPS i SCAS.

Prefixul REPNE/REPNZ (Repeat While Not Zero/Equal - Repet ct timp nu este zero/egal)
REPNE/REPNZ op_primitiva
Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero i
rezultatul operaiei primitive este de asemenea diferit de 0. De obicei se folosete la primitivele de tip
CMPS i SCAS.

Observaie: Numrul elementelor unui ir se poate calcula folosind contorul de locaii. n exemplul
urmtor, expresia $-text reprezint numrul octeilor de la adresa text pn la adresa curent:
text db
'A B C D E F G H J K L M N O P Q R'
ltext equ $-text
De asemenea, operatorul LENGTH ntoarce numrul de elemente, iar operatorul SIZE ntoarce dimensiunea
n octei a unei variabile. Astfel pentru definiia:
tab dw 100 dup(?)
expresia length tab are valoarea 100. Pentru aceeai definiie, expresia size tab are valoarea 200.

3. Aplicaii
1.
2.
3.
4.
5.
6.

S se scrie un program care copiaz un ir ntr-un alt ir.


Cutarea unui anumit caracter ntr-un ir. Se va afia pe ecran poziia caracterului n ir.
S se scrie un program care d indicele caracterului ncepnd de la care dou iruri difer.
S se scrie un program care afieaz pe ecran numrul de apariii a unui ir ntr-un alt ir.
S se scrie un program care adun dou iruri de cifre zecimale aflate n zona de date. Rezultatul este
un ir care conine pe fiecare poziie suma cifrelor de pe poziiile corespunztoare din cele dou iruri.
Precizai care este efectul urmtoarei secvene de instruciuni:
mov
al, D
mov
cx, 12
rep
stosb
21

Programare n limbaj de asamblare


Lucrarea nr. 6.

1. Forma complet de definire a segmentelor


Se utilizeaz o declaraie de forma:
nume_seg SEGMENT [tip_aliniere][tip_combinare][clasa_seg]

nume_seg ENDS
Iniializarea unui registru de segment (DS, ES sau SS) cu un segment declarat trebuie facut de utilizator n
mod explicit n cadrul programului, utiliznd pentru aceasta numele segmentului respectiv:
mov
ax, nume_seg
mov
ds, ax
tip_aliniere - poate fi BYTE, WORD, PARA, PAGE (implicit este PARA), i arat c adresa de
nceput a zonei de memorie rezervat segmentului este divizibil cu 1/2/16/256.
tip_combinare - este o informaie pentru editorul de legturi care indic raportul dintre acest segment i
segmente definite n alte module obiect. Acest parametru poate fi:
PUBLIC - arat c acest segment va fi concatenat cu alte segmente cu acelai nume, din alte module
obiect, rezultnd un singur modul cu acest nume;
COMMON - precizeaz c acest segment i alte segmente cu acelai nume din alte module vor fi
suprapuse, deci vor ncepe de la aceeai adres. Lungimea unui astfel de segment va fi lungimea celui
mai mare segment dintre cele suprapuse;
AT <expresie> - segmentul va fi ncrcat n memorie la adresa fizic absolut de memorie reprezentat
de valoarea expresiei, care este o valoare de 16 bii;
MEMORY - segmentul curent de acest tip va fi aezat n memorie n spaiul rmas disponibil dup
aezarea celorlalte segmente;
STACK - va concatena toate segmentele cu acelai nume, pentru a forma un segment unic; referirea
acestui segment se va face prin SS:SP. Registrul SP va fi iniializat automat cu lungimea stivei.
clasa_seg - este un nume cuprins ntre apostrofuri. Rolul este de a permite stabilirea modului n care se
aeaz n memorie segmentele unui program. Dou segmente cu aceeai clas vor fi aezate n memorie
la adrese succesive.
Asocierea segmentelor cu registrele de segment se realizeaz cu pseudoinstruciunea ASSUME:
ASSUME reg_seg : nume_seg
Unde reg_seg poate fi unul dintre registrele CS, DS, ES sau SS, iar nume_seg este numele unui segment sau
al unui grup de segmente, care va fi adresat de registrul respectiv.
Definirea grupurilor de segmente se realizeaz cu directiva GROUP, care are urmtoarea form:
nume_grup GROUP lista_nume_segmente
unde nume_grup este numele grupului de segmente, ce va fi folosit pentru a determina adresa de segment
utilizat pentru referirea n cadrul grupului de segmente, iar lista_nume_segmente poate conine nume de
segmente sau expresii de forma:
SEG nume_variabila
SEG nume_eticheta
ntr-o astfel de list nu poate s apar numele unui alt grup.
Exemplu:
data1 segment
v1 db 5
data1 ends

22

data2 segment
v2 dw 25
data2 ends
data3 segment
v3 dw 100
data3 ends
dgrup group data1, data2
cod segment
assume cs:cod, ds:dgrup, es:data3
start: mov ax, dgrup
mov ds, ax
mov ax, data3
mov es, ax
;referiri la date
mov bx, v1
;se utilizeaz DS pentru ca a fost asociat cu dgrup
add v3, bx
;se utilizeaz ES pentru ca a fost asociat cu segmentul data3
cod ends
end start

2. Forma simplificat de definire a segmentelor


Aceast modalitate de definire a segmentelor respect acelai format ca i la programele dezvoltate n
limbaje de nivel nalt.
.MODEL tip_model
Prin aceast directiv se specific dimensiunea i modul de dispunere a segmentelor n memorie. Modelul
de memorie poate fi:
- tiny - toate segmentele (date, cod, stiv) formeaz un singur segment de cel mult 64KB. Apelurile de
procedur i salturile sunt de tip NEAR i se folosesc adrese efective (offset) pentru accesarea
datelor;
- small - datele i stiva formeaz un segment i codul un alt segment. Fiecare din acestea va avea
dimensiunea maxima de 64KB. Apelurile de procedur i salturile sunt de tip NEAR i se folosesc
adrese efective (offset) pentru accesarea datelor;
- medium - datele i stiva sunt grupate ntr-un singur segment (cel mult egal cu 64KB), dar codul poate
fi n mai multe segmente, deci poate depi 64KB. Apelurile de procedur i salturile sunt implicit de
tip FAR i se folosesc adrese efective (offset) pentru accesarea datelor;
- compact - codul generat ocup cel mult 64KB, dar datele i stiva pot fi n mai multe segmente (pot
depi 64KB). Apelurile de procedur i salturile sunt de tip NEAR i se folosesc adrese complete
(segment i offset) pentru accesarea datelor aflate n alte segmente;
- large - att datele ct i codul generat pot depi 64KB. Apelurile de procedur i salturile sunt
implicit de tip FAR i se folosesc adrese complete (segment i offset) pentru accesarea datelor aflate
n alte segmente;
- huge - este asemntor modelului large, dar structurile de date pot depi 64KB. La modelele
compact i large, o structur compact de date (de tip tablou) nu poate depi limitele unui segment
fizic (64KB); la modelul huge, aceast restricie dispare.
.STACK [dimensiune]
Aceast directiv aloc o zon de memorie de dimensiune specificat pentru segmentul de stiv. Dac nu se
specific parametrul dimensiune, aceasta va fi implicit de 1KB.
.CODE [nume]
Aceast directiv precede segmentul de cod. ncrcarea adresei acestui segment n registrul CS se face
automat de ctre sistemul de operare, la ncrcarea segmentului pentru execuie. Opional se pot asocia
nume (maxim 6 caractere) pentru segmentele de cod.
.DATA
Aceast directiv precede segmentul de date. Utilizatorul trebuie s iniializeze, n mod explicit, registrul de
segment DS, cu adresa segmentului de date. Simbolul @data primete adresa segmentului de date dup
linkeditare.

23

3. Definirea structurilor. Operaii specifice


Structurile reprezint colecii de date plasate succesiv n memorie, grupate sub un unic nume sintactic.
Dimensiunea unei structuri este suma dimensiunilor cmpurilor componente. Forma general este:
nume_structura STRUC
nume_membru definitie_date
nume_structura ENDS
Tipul structurii se definete fr a se rezerva spaiu de memorie. Numele membrilor structurii trebuie s fie
distincte, chiar dac aparin unor structuri distincte. Iat un exemplu de definiie a unei structuri:
alfa struc
a db
b dw
c dd
alfa ends

?
1111H
1234

O structur definit este interpretat ca un tip nou de date, care poate apoi participa la definiii concrete de
date, cu rezervare de spaiu de memorie. De exemplu, putem defini o structur de tipul alfa, cu numele x:
x alfa <, , 777>
n care alfa este tipul de date, x este numele variabilei, iar ntre paranteze unghiulare se trec valorile iniiale
ale cmpurilor structurii x. Prezena virgulelor din lista de valori iniiale precizeaz c primii doi membrii
sunt iniializai cu valorile implicite de la definiia tipului alfa , iar al treilea membru este iniializat cu
valoarea 777. Astfel, definiia variabilei x este echivalent cu secvena de definiii:
a db
b dw
c dd

?
1111H
777

Principalul avantaj al structurilor este accesul la membri ntr-o form asemntoare limbajelor de nivel
nalt. De exemplu, pentru a ncrca n SI cmpul b al structurii x, putem scrie:
mov si, x.b
Putem acum defini un tablou de 5 structuri de tip alfa:
tab alfa 5 dup (<, , 10>)
n care primii 2 membri sunt iniializai cu valorile de la definiia tipului structurii, iar al treilea cu valoarea
10. Avnd n vedere c o dat de tip alfa ocup 7 octei:
- tab[0].a se refer la cmpul a al primei structuri;
- tab[7].c se refer la cmpul c al celei de-a doua structuri;
- tab[14].a se refer la cmpul a al celei de-a treia structuri;
- tab[21].b se refer la cmpul b al celei de-a patra structuri.

4. Definirea nregistrrilor. Operaii specifice


nregistrrile corespund de fapt unor structuri mpachetate din limbajele de nivel nalt. Concret, o
nregistrare este o definiie de cmpuri de bii de lungime maxim 8 sau 16. Forma general este:
nume_inregistrare RECORD nume_camp:valoare [= expresie],
unde valoare reprezint numrul de bii pe care se memoreaz cmpul respectiv. Opional poate fi folosit o
expresie a crei valoare s fie asociat cmpului respectiv, pe numrul de bii precizat. La fel ca la structuri,
numele cmpurilor trebuie s fie distincte, chiar dac aparin unor nregistrri diferite.
S considerm un exemplu:
beta record x:7, y:4, z:5
24

prin care se definete un ablon de 16 bii, x pe primii 7 bii (mai semnificativi), y pe urmtorii 4 bii, i z pe
ultimii 5 bii (mai puin semnificativi). La fel ca la structuri, putem acum defini variabile de tipul
nregistrrii beta:
val beta <5, 2, 7>
n care valorile dintre parantezele unghiulare iniializeaz cele trei cmpuri de bii. Aceast definiie este
echivalent cu definiia explicit:
val dw 0000101001000111B
Operatorul MASK primete un nume de cmp i furnizeaz o masc cu biii 1 pe poziia cmpului respectiv
i 0 n rest. Astfel, expresia MASK y este echivalent cu constanta binar 0000000111100000B.
Operatorul WIDTH primete un nume de nregistrare sau un nume de cmp i ntoarce numrul de bii ai
nregistrrii sau ai cmpului respectiv. De exemplu, secvena:
mov al, width beta
mov bl, width y
va ncrca n AL 16 i n BL valoarea 4.

5. Macroinstruciuni
Macroinstruciunile permit programatorului s defineasc simbolic secvene de program (instruciuni,
definiii de date, directive, etc.), asociate cu un nume. Folosind numele macroinstruciunii n program, se va
genera ntreaga secven de program. n esen, este vorba de un proces de substituie (expandare) n textul
programului, care se petrece nainte de asamblarea programului. Spre deosebire de proceduri,
macroinstruciunile sunt expandate la fiecare utilizare. Forma general a unei macroinstruciuni este:
nume_macro MACRO [p1, p2, ,pn]

ENDM
Opional, macroinstruciunile pot avea parametri, n acest caz, p1, p2, , pn sunt identificatori care
specific parametrii formali. Apelul unei macroinstruciuni const n scrierea n program a numelui
macroinstruciunii. Dac macroinstruciunuea are parametri, apelul se face prin specificarea numelui,
urmat de o list de parametri actuali:
nume_macro x1, x2, , xn
La expandarea macroinstruciunii, pe lng expandarea propriu-zis, se va nlocui fiecare parametru formal
cu parametrul actual corespunztor.

6.

Aplicaii

1.

Se consider urmtoarea definiie de date:


alfa struc
a1 db ?
a2 db 21H
a3 dw 5176H
alfa ends
tab alfa 10 dup (<3H, ?, 2252H>)
Care va fi coninutul registrului AL dup executarea urmtoarelor instruciuni?
a) mov al, byte ptr tab[12].a2
b) mov al, byte ptr tab[11].a2

2.

S se defineasc o macroinstruciune care realizeaz adunarea a dou valori pe 32 de bii. S se scrie i


un exemplu de apelare al macroinstruciunii definite.
25

Programare n limbaj de asamblare


Lucrarea nr. 7.

1.

ntreruperi

Noiunea de ntrerupere presupune intreruperea programului n curs de execuie i transferul controlului


la o rutin de tratare. Mecanismul prin care se face acest transfer este, n esen, de tip apel de procedur,
ceea ce nseamn revenirea n programul ntrerupt, dup terminarea rutinei de tratare. Pe lng rutinele de
tratare ale sistemului de operare, pot fi folosite i propriile rutine. ntreruperile software apar ca urmare a
execuiei unor instruciuni, cum ar fi INT, INTO, DIV, IDIV. Intreruperile hardware externe sunt provocate
de semnale electrice care se aplic pe intrrile de ntreruperi ale procesorului, iar cele interne apar ca urmare
a unor condiii speciale de funcionare a procesorului (cum ar fi execuia pas cu pas a programelor).
ntr-un sistem cu procesor 8086, pot exista maxim 256 de ntreruperi. Fiecare nivel de ntrerupere poate
avea asociat o rutin de tratare (procedur de tip far). Adresele complete (4 octei) ale acestor rutine sunt
memorate n tabela vectorilor de intrerupere, pornind de la adresa fizic 0 pn la 1KB. Intrarea n tabel se
obine nmulind codul ntreruperii cu 4. Rutina de tratare a ntreruperii se termin obligatoriu cu
instruciunea IRET.

2. Redirectarea ntreruperii de pe nivelul 0


mprirea unui numr foarte mare la un numr mic, poate duce la apariia ntreruperii pe nivelul 0.
Pentru obinerea rezultatului corect, se redirecteaz ntreruperea de pe nivelul 0 spre o rutin care realizeaz
mprirea n situaia n care mpritorul este diferit de 0. Implementai programul de mai jos, i rulai-l pas
cu pas.
.model small
.stack 100
.data
demp dd 44444444h
imp dw 1111h
cat
dd ?
rest dw ?
.code
;procedura primeste deimpartitul in (DX, AX) si impartitorul in BX
;returneaza catul in (BX, AX) si restul in DX
divc

proc
cmp
jnz
int

bx, 0
divc1
0

push
push
push
mov
mov
push
push
mov
mov
div

es
di
cx
di, 0
es, di
es:[di]
es:[di+2]
word ptr es:[di], offset trat_0
es:[di+2],cs
bx

sub

bx, bx

;daca eroare adevarata


;apel tratare impartire cu 0

divc1:
;salvare registre modificate de procedura

;adresa pentru intrarea intrerupere nivel 0


;salvare adresa oficiala

;incarcare vector intrerupere


; pentru noua rutina de tratare
;incercare executie instructiune de impartire
;nu a aparut eroare
;daca impartirea s-a executat corect se pune 0
;in bx ca sa corespunda modului de transmitere al parametrilor stabilit
26

revenire:
pop
es:[di+2]
pop
es:[di]
pop
cx
pop
di
pop
es
ret
trat_0 proc far
push bp
mov bp, sp

mov
push
mov
sub

div
pop
push
mov

div
pop
pop
iret
trat_0 endp
divc endp
start: mov
mov
mov
mov
mov
call
mov
mov
mov
mov
int
end start

;salvare bp

;schimba adresa de revenire din rutina trat_0, adresa care se gaseste in stiva
;a fost pusa in stiva la apelare rutinei de intrerupere (IP-ul)
word ptr [bp+2], offset revenire
ax
;salvare ax, Y0
ax, dx
;primul deimpartit Y1
dx, dx
;executie impartire Y1 la X
;rezulta (AX) = Q1, (DX) = R1
bx
cx
;Y0
ax
;salvare Q1
ax, cx
;executie impartire (R1, AX) la X
;rezulta AX=Q0, DX=R0
bx
bx
;Q1
bp

ax, @data
ds, ax
ax, word ptr demp
dx, word ptr demp+2
bx, imp
divc
word ptr cat, ax
word ptr cat+2, bx
rest, dx
ah, 4ch
21h

27

Programare n limbaj de asamblare


Lucrarea nr. 8.

1.

Transferul parametrilor ctre proceduri

1.1. Tipuri de transfer (prin valoare sau prin referin)


O prim chestiune care trebuie decis n proiectarea unei proceduri este tipul de transfer al parametrilor. Se
pot utiliza dou tipuri de transfer:
transfer prin valoare, care implic transmiterea coninutului unei variabile; se utilizeaz atunci cnd
variabila care trebuie transmis nu este alocat n memorie, ci ntr-un registru;
transfer prin referin, care implic transmiterea adresei de memorie a unei variabile; se utilizeaz
atunci cnd trebuie transmise structuri de date de volum mare (tablouri, structuri, tablouri de
structuri, etc.). Se mai folosete atunci cnd procedura trebuie s modifice o variabil parametru
formal alocat n memorie.
S considerm o procedur aduna, de tip near, care adun dou numere pe 4 octei, ntorcnd rezultatul n
perechea de registre DX:AX:
.data
n1 dd 12345H
n2 dd 54321H
rez dd ?
.code
aduna proc near
add ax, bx
adc dx, cx
ret
aduna endp

mov ax, word ptr n1


mov dx, word ptr n1+2
mov bx, word ptr n2
mov cx, word ptr n2+2
call near ptr aduna
mov word ptr rez, ax
mov word ptr rez+2, dx
S considerm acum varianta transmiterii prin referin a parametrilor, n care se transmit ctre procedur
adresele de tip near ale variabilelor n1 i n1.
aduna proc near
mov ax, [si]
add ax, [di]
mov dx, [si+2]
adc dx, [di+2]
ret
aduna endp

lea si, n1
lea di, n2
call near ptr aduna
mov word ptr rez, ax
mov word ptr rez+2, dx

28

1.2. Transfer prin registre


Avantajul transferului prin registre const n faptul c, n procedur, parametrii actuali sunt disponibili
imediat. Principalul dezavantaj al acestei metode const n numrul limitat de registre. Pentru conservarea
registrelor se folosete urmtoarea secven de apel:
salvare n stiv a registrelor implicate n transfer;
ncrcare registre cu parametri actuali;
apel de procedur;
refacere registre din stiv.

1.3. Transfer prin zon de date


n aceast variant, se pregtete anterior o zon de date i se transmite ctre procedur adresa acestei zone
de date. n exemplul urmtor transferul parametrilor ctre procedura aduna se face printr-o zon de date:
.data
zona label dword
n1 dd 12345H
n2 dd 54321H
rez dd ?
.code
aduna proc near
mov ax, [bx]
add ax, [bx+4]
mov dx, [bx+2]
adc dx, [bx+6]
ret
aduna endp

lea bx, zona


call near ptr aduna
mov word ptr rez, ax
mov word ptr rez+2, dx

1.4. Transfer prin stiv


Transferul parametrilor prin stiv este cea mai utilizat modalitate de transfer. Avantajele acestei metode
sunt uniformitatea i compatibilitatea cu limbajele de nivel nalt. Tehnica de acces standard la parametrii
procedurii se bazeaz pe adresarea bazat prin registrul BP, care presupune registrul SS ca registru implicit
de segment. Accesul se realizeaz prin urmtoarele operaii, efectuate la intrarea n procedur:
se salveaz BP n stiv;
se copiaz SP n BP;
se salveaz n stiv registrele utilizate de procedur;
se acceseaz parametrii prin adresare indirect cu BP.
La ncheierea procedurii, se execut urmtoarele operaii:
se refac registrele salvate;
se reface BP;
se revine n programul apelant prin RET.
Calculul explicit al deplasamentelor parametrilor reprezint o surs potenial de greeli, de aceea se
utilizeaz un ablon care conine imaginea stivei, de la registrul BP n jos. S considerm procedura aduna
de tip near, care primete parametrii n1 i n2 prin stiv
.data
n1 dd 12345H
n2 dd 54321H
rez dd ?

29

sablon struc
_bp
_ip
n2_low
n2_high
n1_low
n1_high
sablon ends

dw ?
dw ?
dw ?
dw ?
dw ?
dw ?

.code
aduna proc near
push bp
mov bp, sp
mov ax, [bp].n1_low
add ax, [bp].n2_low
mov dx, [bp].n1_high
adc dx, [bp].n2_high
pop bp
ret
aduna endp

push word ptr n1+2


push word ptr n1
push word ptr n2+2
push word ptr n2
call near ptr aduna
add sp,8
mov word ptr rez, ax
mov word ptr rez+2, dx
n cazul n care procedura este de tip far, pentru adresa de revenire trebuie rezervate n ablon 4 octei
(adres complet):
sablon struc
_bp
_cs_ip
n2_low
n2_high
n1_low
n1_high
sablon ends

dw ?
dd ?
dw ?
dw ?
dw ?
dw ?

.code
aduna proc far
push bp
mov bp, sp
mov ax, [bp].n1_low
add ax, [bp].n2_low
mov dx, [bp].n1_high
adc dx, [bp].n2_high
pop bp
ret
aduna endp

push word ptr n1+2


push word ptr n1
push word ptr n2+2
push word ptr n2
call far ptr aduna
add sp,8
mov word ptr rez, ax
mov word ptr rez+2, dx

30

2. ntoarcerea datelor de ctre proceduri


Exist urmtoarele modaliti de a ntoarce datele de ctre proceduri:
n lista de parametri apar adresele rezultatelor sau adresa zonei de date care conine cmpuri pentru
rezultate;
rezultatele se ntorc prin registre;
rezultatele se ntorc n vrful stivei.
Prima tehnic a fost deja descris la transmiterea parametrilor prin zon de date. Practic, n interiorul
procedurii se depun explicit rezultatele la adresele coninute n parametrii formali respectivi. A doua
tehnic, transferul rezultatelor prin registre, se folosete cel mai frecvent. De obicei se folosete registrul
acumulator, eventual extins (AL, AX, respectiv DX:AX, dup cum rezultatul este pe 1, 2 sau 4 octei). A
treia tehnic, transferul rezultatelor prin stiv, se folosete destul de rar, fiind total nestandard.

3.
1.
2.
3.

Aplicaii
S se scrie un program care determin numrul biilor 1 dintr-un numr pe 32 de bii citit de la tastatur
(se vor folosi instruciunile SHL i ADC);
S se scrie o procedur care realizeaz adunarea a dou valori citite de la tastatur. Numerele sunt
formate din maxim 32 de cifre.
S se scrie un program care convertete un numr din format BCD mpachetat n format BCD
despachetat. Numrul este format din 10 cifre. Rezultatul va fi memorat n zona de date. Pentru
conversie se va utiliza o procedur care primete ca parametri adresa numrului BCD mpachetat i
adresa la care va memora numrul BCD despachetat. Cei doi parametri sunt transmii prin stiv.

Observaii:
citirea unui caracter de la tastatur se realizeaz folosind funcia 01H a ntreruperii 21H. Se ncarc
n registrul AH valoarea 01H, se apeleaz ntreruperea 21H, care va pune codul ASCII al
caracterului citit n AL;
afiarea unui caracter pe ecran se realizeaz folosind funcia 02H a ntreruperii 21H. Se ncarc n
registrul AH valoarea 02H. Se ncarc n DL codul ASCII al caracterului care trebuie afiat i apoi
se apeleaz ntreruperea 21H, care va afia caracterul pe ecran;
afiarea unui ir de caractere pe ecran (irul se termin cu caracterul $, care are codul ASCII 24H)
se realizeaz folosind funcia 09H a ntreruperii 21H. Se ncarc n registrul AH valoarea 09H. Se
ncarc n DS adresa de segment a irului care trebuie afiat, i n DX adresa efectiv (offsetul). Se
apeleaz ntreruperea 21H, care va afia irul pe ecran.
pentru trecerea la linie nou se afieaz irul de caractere:
nl db 13, 10, 24H
unde 13, 10 reprezint codul ENTER-ului.

31

Programare n limbaj de asamblare


Lucrarea nr. 9.

1. Proceduri recursive
Numim procedur recursiv o procedur care se autoapeleaz (direct sau indirect). Forma general a unei
funcii recursive este urmtoarea:
tip f(lista_parametri_formali){
if (!conditie_de_oprire){
...
... f(lista_parametri_reali)
...
}
}
Recursivitatea poate fi utilizat pentru a rezolva elegant multe probleme, dar procedurile recursive
sunt adesea mai lente dect corespondentele lor nerecursive:
la fiecare apel se depun n stiv valorile parametrilor (dac exist) i adresa de revenire
(vezi lucrarea de laborator nr. 6)
complexitatea algoritmilor recursivi este de obicei mai mare dect a celor iterativi.

Aplicaie
Enun :
S se realizeze o funcie recursiv ce calculeaz n!
Rezolvare :

Plecm de la formula recursiv de calcul

1, n = 0
n!=
cunoscut din liceu.
n (n 1)!, n > 0

Rescriind formula ntr-o variant mai apropiat de implementare, avem:

1, n = 0
fact (n) =
n * fact (n 1), n > 0
Pentru a nelege mai uor programul realizat n limbaj de asamblare, s urmrim pentru nceput programul
C, care declar o funcie recursiv fact, citete de la tastatur o valoare, i folosete funcia pentru a returna
factorialul acestei valori:

#include <stdio.h>
long fact(int n){
if(n==0) return 1;
return n*fact(n-1)
}
void main(){
int n;
scanf("%d",&n);
printf("%ld",fact(n));
}

//conditia de oprire
//apel recursiv: n!=n(n-1)!

//citire n
//afisare n!

32

Analiz:
La orice funcie recursiv trebuie precizat o condiie de ieire. n problema factorialului, condiia
de ieire este 0! care, prin definiie, este 1. Dac parametrul primit de fact este 0, atunci funcia returneaz
1, altfel returneaz rezultatul nmulirii dintre valoarea parametrului i factorialul apelat cu valoarea
parametrului minus 1.
Pentru fact(3) avem urmtoarea succesiune de operaii:
(1)
(2)
(3)
(4)
(5)
(6)
(7)

apeleaz recursiv fact(2);


apeleaz recursiv fact(1);
apeleaz recursiv fact(0);
returneaz 1 revenire din fact(0), calculeaz 1*fact(0);
returneaz 1 revenire din fact(1), calculeaz 2*fact(1);
returneaz 2 revenire din fact(2), calculeaz 3*fact(2);
returneaz 6 revenire din fact(3);

fact(3) {
if(n == 0) return 1;
return 3 * fact(3-1);
}

fact(2) {
if(n == 0) return 1;
return 2 * fact(2-1);
}

fact(1) {
if(n == 0) return 1;
return 1 * fact(1-1);
}
1

Implementarea programului n limbaj de asamblare este urmtoarea:


.model small
.stack
sablon struc
_bp dw ?
_cs_ip dw ?
_n dw ?
sablon ends
.data
n dw 7
rez dd ?
.code
fact proc near
push bp
mov bp, sp
pushf
push bx
mov bx, word ptr [bp]._n
cmp bx, 0
jne rec
mov ax, 1

;salvare bp
;initializare cu varful stivei
;salvare indicatori
;preluarea parametrului
;conditia de oprire
;0!=1
33

fact(0) {
if(n == 0)
return 1;
}

mov dx, 0
jmp stop
rec:dec bx
push bx
call near ptr fact
add sp, 2
mul word ptr [bp]._n
stop:pop bx
popf
pop bp
retn
fact endp
afis proc near
push ax
push bx
push cx
push dx
mov dx, word ptr rez+2
mov ax, word ptr rez
mov cx, 0
mov bx, 10
next:div bx
push dx
mov dx, 0
inc cx
cmp ax, 0
jne next
print:pop dx
add dl, 30h
mov ah, 02h
int 21h
loop print
pop dx
pop cx
pop bx
pop ax
retn
afis endp
start:
mov ax, @data
mov ds, ax
mov ax, n
push ax
call near ptr fact
add sp, 2
mov word ptr rez+2, dx
mov word ptr rez, ax
call near ptr afis
mov ah, 4ch
int 21h
end start

;termenul urmator
;transferul parametrului
;apel recursiv, cu rezultat in DX:AX

;refacerea registrului bx
;refacere indicatori

;salvarea registrelor

;preluare din rez


;initializarea contorului
;se obtine pe rand in dx fiecare cifra zecimala
;salvarea in stiva e necesara pentru afisarea in ordinea corecta

;preluare din stiva


;conversie la codul ASCII
;afisare
;refacerea registrelor

;initializare registru segment

;transferul parametrului prin stiva


;DX:AX<--rezultatul
;rezultatul se depune in rez
;afisarea rezultatului
;revenire DOS

Pentru preluarea parametrului din stiv, procedura fact folosete urmtoarea structur ablon:
sablon struc
_bp dw ?
_cs_ip dw ?
_n dw ?
sablon ends

34

Deoarece n problema factorialului, condiia de ieire este 0! care, prin definiie, este 1, dup preluarea
parametrului, valoarea acestuia se compar cu 0. n caz de egalitate, n DX:AX se depune valoarea 1 i se
face salt la eticheta stop (procedura ntoarce valoarea 1). Dac valoarea parametrului nu este 0, se
returneaz rezultatul nmulirii dintre valoarea parametrului i factorialul apelat cu valoarea parametrului
minus 1.
S urmrim din nou succesiunea de operaii pentru acelai exemplu (3!), apelm deci procedura fact cu
valoarea 3 trimis ca parametru:
(1)
(2)
(3)
(4)
(5)
(6)
(7)

apeleaz recursiv procedura fact, valoarea parametrului este 2;


apeleaz recursiv procedura fact, valoarea parametrului este 1;
apeleaz recursiv procedura fact, valoarea parametrului este 0;
returneaz 1 n DX:AX revenire din fact(0);
returneaz 1 n DX:AX revenire din fact(1);
returneaz 2 n DX:AX revenire din fact(2);
returneaz 6 n DX:AX revenire din fact(3);

Procedura afis preia rezultatul din rez (rezultatul se depune n rez nainte de a apela procedura
afis), convertete aceast valoare n zecimal i o afieaz.

2. Aplicaii
1. Modificai programul prezentat, nlocuind procedura nerecursiv afis cu o procedur recursiv
S se realizeze funcii care rezolv recursiv urmtoarele probleme:

2. Calculai

1, n = 0
2n =
n 1
2 2 , n > 0

0, n = 0

3. Calculai cel de-al n-lea numr Fibonacci fibo( n) = 1, n = 1


fibo(n 1) + fibo(n 2), n > 1

1, n = k

k
4. Calculai C n = 1, k = 0
k 1
k
C n 1 + C n 1 , in rest

35

Programare n limbaj de asamblare


Lucrarea nr. 10.
1.

Aplicaii mixte C-ASM

1.1. Transferul parametrilor


compilatorul de Borland C realizeaz tra nsferul parametrilor spre funcii prin stiv (n ordinea
dreapta-stnga), apelul unei funcii C din ASM presupune plasarea parametrilor n stiv i apoi
apelarea funciei C;
deoarece n C descrcarea stivei este fcut de modulul apelant, un program ASM trebuie s descarce
stiva dup apelarea unei funcii C.

1.2. ntoarcerea rezultatelor


Dup executarea unei funciiC, rezultatul se va ntoarce n funcie de dimensiunea zcestuia, n felul urmtor:
1 octet: n registrul AL (char);
2 octei: n registrul AX (int i short);
4 octei: n perechea de registre DX:AX (long i float);
float (4 octei), double (8 octei), long double (10 octei): ntr-o zon special a bibliotecii de
virgul mobil sau n vrful stivei coprocesorului matematic. O soluie pentru rezultatele de tip real
ar fi ca funcia s ntoarc pointeri la aceste valori.

1.3. Numele simbolurilor externe


n C numele simbolurilor externe (nume de variabile, nume de funcii) sunt generate implicit cu caracterul
_ precednd numele simbolului. Cu alte cuvinte, parametrii din C, utilizai i n modulul scris n limbaj de
asamblare, vor fi precedai de caracterul _. n modulul n care simbolurile sunt definite, ele se declar
PUBLIC, iar n modulele n care ele sunt referite se declar EXTRN. n unul din module (C sau ASM),
trebuie s existe funcia main, care n ASM se declar n felul urmtor:
public _main
_main proc
.
ret
_main endp
Urmtoarea aplicaie mixt calculeaz recursiv factorialul unui numr citit de la tastatur:
Modulul C:
#include <stdio.h>
#include <conio.h>
Modulul ASM:
.model tiny
extrn _clrscr:near, _scanf:near, _printf:near, _getch:near
public _main
.stack 1024
sablon struc
_bp dw ?
_ip dw ?
_n
dw ?
sablon ends
.data
n
dw ?
MesRd
db 'Introduceti un intreg: ',0
MesWr
db 'Factorialul este %d...',0
scan
db '%d',0
36

;_cs_ip dd ? - modificare I

.code
Factorial proc near
push bp
mov bp,sp

;Factorial proc far - modificare I

;+ push ds - modificare II
;+ push es - modificare II
push dx
push bx
mov bx,[bp]._n
cmp bx,1
jne et1
mov ax,1
jmp et2
et1: dec bx
push bx
call near ptr Factorial
add sp,2
mul [bp]._n
et2: pop bx
pop dx

; parametru salvat in stiva


; call far ptr Factorial - modificare I

; ax - contine rezultatul deci nu se restaureaza


;+ pop es - modificare II
;+ pop ds - modificare II
; ===> ax nu trebuie salvat in stiva la inceputul proc
;retf - modificare I

pop bp
retn
Factorial endp
_main proc near
call near ptr _clrscr

;_main proc far - modificare I


; call far ptr _clrscr - modificare I
;+ mov ax, seg MesRd - modificare II
;+ push ax - modificare II

lea ax, MesRd


push ax
call near ptr _printf
add sp,2

; call far ptr _printf - modificare I


; add sp, 4 - modificare II
;+ mov ax, seg n - modificare II
;+ push ax - modificare II

lea ax, n
push ax
;+ mov ax, seg scan - modificare II
;+ push ax - modificare II
lea ax, scan
push ax
call near ptr _scanf
add sp,4
mov ax,n
push ax
call near ptr Factorial
add sp,2
push ax

; call far ptr _scanf - modificare I


; add sp, 8 - modificare II

; call far ptr Factorial - modificare I

;+ mov ax, seg MesWr - modificare II


;+ push ax - modificare II
lea ax,MesWr
push ax
call near ptr _printf
add sp,4
call near ptr _getch
retn
_main endp

; call far ptr _printf - modificare I


; add sp, 6 - modificare II
; call far ptr _getch - modificare I
; retf - modificare I

end

37

Observaie: Modificrile I trebuie fcute n cazul utilizrii modelelor de memorie cu apel de procedur de
tip far, iar modificrile II trebuie fcute atunci cnd se folosesc modele de memorie cu adrese fizice
(complete). n cel de-al doilea caz, simbolul @data trebuie modificat cu simbolul DGROUP.

2.

Aplicaii

S se realizeze funcii care rezolv recursiv urmtoarele probleme:

0, n = 0
1. Calculai suma cifrelor unui numr sumac ( n) =
n%10 + sumac ( n / 10), n > 0

a , b = 0
2. Calculai cmmdc( a, b ) =
cmmdc(b, a %b), b > 0
3. Se d un ir ordonat cresctor. Realizai funcia ce implementeaz cutarea binar.
0, s > d

1, a[ m] = val , unde m = ( s + d ) / 2
cauta ( s , d , val ) =
cauta ( s, m 1, val ), a[ m] > val
cauta ( m + 1, d , val ), a[ m] < val
a[0], i = 0

4. Suma elementelor unui vector sumas (i ) =

a[i ] + sumas (i 1), i > 0

1, s >= d

5. Verificarea dac un vector e palindrom pali ( s , d ) = 0, a[ s ]!= a[ d ]


pali ( s + 1, d 1), in rest

1, n = 1

6. Descompunerea unui numr n factori primi desc ( n, d ) = scrie d , desc ( n / d , d ), daca d | n


desc ( n, d + 1), in rest

7.

Conversia unui numr din baza 10 n baza 2.

8.

Calculul coeficientului de grad n al polinomului Cebev de speta I.


1, n = 0

Tn ( x) = x, n =1
2T
n 2 ( x) Tn 1 ( x)

n + 1, m = 0

9. Calculai valoarea functiei Ackermann A(m, n) A(m 1,1), n = 0


A(m 1, A(m, n 1)), in rest

10. Cautarea minimului i maximului intr-un sir de n valori.


11. Determinarea numrului de apariii a unei valori ntr-un ir.

38

Bibliografie
[1]
[2]
[3]
[4]

G. Musc, Programare n limbaj de asamblare, Editura Teora, 1998.


V. Lungu, Procesoare INTEL - Programare n limbaj de asamblare, Editura Teora, 2001.
R. Baciu, Programarea n limbaje de asamblare, Editura ALMA MATER, Sibiu, 2003.
A. Florea, L. Vinan, Simularea i optimizarea arhitecturilor de calcul n aplicaii practice, Editura
MATRIX ROM, Bucureti, 2003.

39

S-ar putea să vă placă și