You are on page 1of 113

; pla51.

asm - media aritmetica a unor cuvinte (16 biti) cu semn


date segment word public 'data'
op dw 8000h, 8000h, 8000h, 8000h, 8000h
lung equ ($-op)/2
rezult dw 2 dup (0)
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
lea bx, op
mov cx, lung
call medie
mov rezult, dx
mov rezult[2], ax
mov ax,4C00h
int 21h
; procedura determina media unor cuvinte cu semn (cat si rest intregi)
;intrari: (BX) = offset primul operand
; (CX) = contorul numarului de cuvinte
;iesiri: (AX) = rezultatul (partea intreaga)
; (DX) = rezultat (restul)
medie proc near
jcxz gatam ; daca contorul este nul, s-a terminat
push bx ; salvare registre de lucru, adresa operand
sub ax, ax ; initializare cu 0 a sumei valorilor
sub dx, dx ; ce se va memora in (DX,AX)
push cx ; salvare contor
add_cuv:
cmp word ptr [bx], 0 ; ce tip de numar se aduna: pozitiv sau negativ
js adun_neg
add ax, [bx]
adc dx, 0 ; se aduna transportul la rangul urmator al sumei
jo depasire ; se pozitioneaza indicatorul de eroare CF
jmp cuv_urmator ; mai sunt cuvinte de adunat
adun_neg:
add ax, [bx]
adc dx, 0ffffh ; se aduna transportul la rangul urmator al sumei
jo depasire ; se pozitioneaza indicatorul de eroare CF
cuv_urmator:
add bx, 2 ; se trece la cuvantul urmator
loop add_cuv
pop cx ; refacerea registrelor utilizate
idiv cx ; se imparte suma la contor si se obtine media
pop bx ; refacerea registrului
clc ; CF=0, rezultat fara eroare
gatam: ret
depasire:
stc ; CF=1, eroare, depasire la adunare
add sp, 4; descarcare stiva/ refacere registre
ret
medie endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla52.asm - adunarea a doua numere intregi pe 32 de biti, cu semn,
; utilizand resurse de 16 biti (286)
date segment word public 'data'
op1 dw 8000h, 0ffffh
op2 dw 8000h, 0ffffh
rezult dw 2 dup (0)
mes_err db 'EROARE: depasire rezultat', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
mov bx, op1 ; (AX:BX) - primul operand
mov ax, op1[2]
mov dx, op2 ; (CX:DX) - al doilea operand
mov cx, op2[2]
call adds32
jc afis_err
mov rezult, dx
mov rezult[2], cx
jmp gatap
afis_err:
lea dx, mes_err
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h
; procedura determina suma a doua valori pe 32 de biti
;intrari: (AX:BX) = primul operand
; (CX:DX) = al doilea operand
;iesiri: (CX:DX) = rezultatul
; (CF) = 1, daca rezultatul este mai mare de 32 biti;
; (OF) = 1, daca rezultatul depaseste domeniul (in complement fata de 2)
; AX, BX - nemodificate

comp macro highreg, lowreg ; complementeaza fata de doi un registru: (high,low)reg


not lowreg ; se complementeaza partea 'low' a registrului
add lowreg, 1
not highreg ; se complementeaza partea 'high' a reg.
adc highreg, 0
endm

adds32 proc near


push ax ; se salveaza primul operand
push bx
; daca valorile sunt pozitive se aduna direct
push cx ; salveaza acest registru
or cx, ax ; testeaza daca ambele valori sunt pozitive
pop cx ; refacerea registrului
js negative ; salt daca sunt negative
add dx, bx ; se aduna ultimii 16 biti
adc cx, ax ; se aduna primii 16 de biti
jmp gata ; daca apare depasire OF=1
; daca ambii operanzi sunt negativi, se vor complementa, si apoi, se aduna negative:
negative:
test ax, cx ; test daca ambele sunt negative
jns opuse ; operanzi cu semne opuse
comp ax, bx ; complementez ambii operanzi
comp cx, dx
add dx, bx ; si ii adun
adc cx, ax
jo gata ; daca avem depasire vom pozitiona CF=1
jmp reface ; daca nu, se reface (complementeaza) rezultatul
; daca operanzii au semne opuse ii adunam direct (nu poate sa apara depasire)
opuse:
add dx, bx ; se aduna ultimii 16 biti
adc cx, ax ; se aduna primii 16 de biti
clc ; operanzii avand semne diferite, nu avem depasire, CF=0
jmp iesire ; iesire fara eroare de depasire
reface: comp cx, dx ; complementare rezultat (OF=0)
gata: stc ; setez CF=1, daca a aparut depasire
jo iesire ; daca OF=1, se iese cu CF=1
clc ; altfel se iese cu CF=1, nu a fost depasire
iesire: pop bx
pop ax
ret
adds32 endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla53a.asm - inmultire, fara semn, a doi operanzi, de 32 biti, cu rezultat pe 64 de biti
; Algoritmul este urmatorul:
; deinmultit: (DX, AX) *
; inmultitor: (CX, BX) =
; (BX * AX) +
; (BX * DX) +
; (CX * AX) +
; (CX * DX) =
; rezultat: (DX , CX , BX , AX)

dseg segment para public 'data'


deinmultit dd 123h
inmultitor dd 456h
produs dq ? ; rezultatul va fi: 0000 0000 0004 EDC2 H
dseg ends

cseg segment para public 'code'


assume cs:cseg, ds:dseg
start: mov ax, dseg ; initializare registru segment
mov ds, ax
; deinmultit -> (DX, AX)
mov ax, word ptr deinmultit
mov dx, word ptr deinmultit[2]
; inmultitor -> (CX, BX)
mov bx, word ptr inmultitor
mov cx, word ptr inmultitor[2]
call multfs32
mov word ptr produs, ax
mov word ptr produs[2], bx
mov word ptr produs[4], cx
mov word ptr produs[6], dx
mov ax, 4C00h
int 21h

;intrari: (DX, AX) = deinmultit


; (CX, BX) = inmultitor
;iesiri (DX, CX, BX, AX) = rezultatul inmultirii

rezultat dd 4 dup (?); aici se vor depune rezultatele partiale ale inmultirilor
; si calcula rezultatul final, care va fi returnat in registre

public multfs32
multfs32 proc
push dx ; salvarea valorilor initiale ale operanzilor
push ax ; necesare in aceasta ordine pentru efectuarea inmultirilor
push dx ; conform algoritmului descris
mul bx ; efectuarea inmultirii: (AX)*(BX) -> (DX,AX)
mov word ptr rezultat[0], ax ; salvare rezultat partial
mov word ptr rezultat[2], dx
pop ax ; refacerea valorii initiale a registrului (DX)
mul bx ; efectuarea inmultirii: (BX)*(DX) -> (DX,AX)
add word ptr rezultat[2], ax ; actualizare rezultat partial
adc word ptr rezultat[4], dx ; cu propagarea eventualului transport
pop ax ; refacera valorii initiale pentru (AX)
mul cx ; efectuarea inmultirii: (CX)*(AX) -> (DX,AX)
add word ptr rezultat[2], ax ; actualizare rezultat partial
adc word ptr rezultat[4], dx ; cu propagarea transportului
pop ax ; refacera valorii initiale pentru (DX), in registrul (AX)
mul cx ; efectuarea inmultirii: (CX)*(DX) -> (DX,AX)
add word ptr rezultat[4], ax ; actualizare rezultat final (s-a efectuat ultima inmultire
adc word ptr rezultat[6], dx ; cu propagarea transportului
mov ax, word ptr rezultat[0] ; depunerea rezultatului in registrele specificate
mov bx, word ptr rezultat[2]
mov cx, word ptr rezultat[4]
mov dx, word ptr rezultat[6]
ret
multfs32 endp
cseg ends

sseg segment para stack 'stack'


dw 128 dup(?)
sseg ends
end start
dseg segment para public 'data'
deinmultit dd 012345555h
inmultitor dd 045655555h
produs dq ? ; rezultatul va fi: 0000 0000 0004 EDC2 H
mes_err db 'EROARE: depasire la inmultire', 0Dh, 0Ah, '$'
dseg ends

cseg segment para public 'code'


assume cs:cseg, ds:dseg
start: mov ax, dseg ; initializare registru segment
mov ds, ax
; deinmultit -> (DX, AX)
mov ax, word ptr deinmultit
mov dx, word ptr deinmultit[2]
; inmultitor -> (CX, BX)
mov bx, word ptr inmultitor
mov cx, word ptr inmultitor[2]
call mults32
jc afis_mes_err
mov word ptr produs, ax
mov word ptr produs[2], bx
mov word ptr produs[4], cx
mov word ptr produs[6], dx
jmp gatar
afis_mes_err:
lea dx, mes_err
mov ah, 9
int 21h
gatag: mov ax, 4C00h
int 21h

; procedura inmulteste doua numere de 32 biti, cu semn


;intrari: deinmultitul este in (DX:AX), iar inmultitorul este in (CX:BX)
;iesiri: rezultatul se va returna in registrele (DX,CX,BX,AX)
public mults32
extrn multus32: near
mults32 proc near
mov semn_rez, 0 ; se initializeaza semnul cu 0 (adica +)
cmp dx, 0 ; se testeaza semnul deinmultitului
jns test_op_doi ; daca este pozitiv se va testa al doilea operand
mov semn_rez,1 ; primul operand este negativ, si se complementeaza
neg ax ; incepand cu al doilea cuvant
jnc negdx ; daca acesta este 0, se va complementa primul cuvant
not dx ; altfel, se vor inversa toti bitii primului cuvant
jmp test_op_doi ; test cel de-al doilea operand
negdx: neg dx ; se complementeaza primul cuvant al operandului
jc depasire ; daca (CF)=1 => nu se poate complementa cel mai mic
; numar negativ, ce se poate reprezenta pe 32 biti
test_op_doi:
cmp cx, 0 ; se testeaza semnul celui de-al doilea operand, si daca
jns multiply ; este pozitiv, realizeaza inmultirea
xor cs:semn_rez, 1 ; semn_rez este complementat (0->1, 1->0)
compl2: neg bx ; si se complementeaza al 2-lea operand, la fel ca primul
jnc negcx
not cx
jmp multiply
negcx: neg cx
jc depasire
multiply:
call multus32
dec cs:semn_rez ; daca rezultatul este = 0, => numarul se complementeaza
jnz gata ; daca este <> 0, numarul obtinut este cel corect (rezultat pozitiv)
neg ax ; se incepe complementarea rezultatului cu ultimul cuvant
jc notbx ; daca (AX) <> 0 se vor nega celelalte registre
neg bx ; daca (AX)= 0, se va comlementa (BX)
jc notcx ; daca (BX) <> 0 se vor nega registrele ramase
neg cx ; daca (BX) = 0, se va complementa (CX)
jc notdx ; daca (CX) <> 0, se va nega registrul (DX), ultimul
neg dx ; se complementeaza (DX); nu putem avea depasire
jmp gata
notbx: not bx
notcx: not cx
notdx: not dx
gata: clc ; (CF) = 0, rezultat corect
depasire:
ret ; (CF) = 1, unul dintre operanzi nu poate fi complementat
semn_rez db 0
mults32 endp
cseg ends

sseg segment para stack 'stack'


dw 128 dup(?)
sseg ends
end start
. Împartirea fara semn a unui deimpartit de 32 biti la un impartitor de 16 biti
dseg segment para public 'data'
deimpartit dq 12345678FFFFFFFFh
divizor dw 16
cat dq 0
rest dw ? ; cat va fi: 0123 4567 8FFF FFFF H, restul 00 0F H
dseg ends

cseg segment para public 'code'


; impartirea unei valori de 64 de biti la una de 16 biti
assume cs:cseg, ds:dseg
div64 proc
mov ax, dseg ; initializare registru segment
mov ds, ax
mov ax, word ptr deimpartit[6]
sub dx, dx ; impartire (DX,AX)/divizor -> (DX,AX)=(rest, cat)
div divizor
mov word ptr cat[6], ax ; primul cat, cel mai semnificativ se depune la cat[6]
mov ax, word ptr deimpartit[4]
div divizor ; continua impartirea: (DX=rest anterior,AX=cifra urmatoare)
mov word ptr cat[4], ax ; si se depune urmatorul cat, la cat[4]
mov ax, word ptr deimpartit[2]
div divizor
mov word ptr cat[2], ax
mov ax, word ptr deimpartit
div divizor ; ultima impartire
mov word ptr cat, ax ; se depune ultimul cat
mov rest, dx ; si restul
mov ax, 4c00h
int 21h
div64 endp
cseg ends
sseg segment para stack 'stack'
dw 128 dup(?)
sseg ends
end div64
Împartirea a doua numere, zecimal neimpachetate pe 16 biti (divzn16)

divzn16 proc near

push bx

push cx

aad

mov cx, ax

mov ax, dx

aad

mov dl, 100

mul dl

add cx, ax

mov ax, bx

aad

mov bl, al

mov ax, cx

div bl

mov bl, 99

cmp bl, al

jc gata

cmp bl, ah

jc gata

mov bl, al

mov al, ah

aam

mov dx, ax

mov al, bl
aam

clc

gata: pop cx

pop bx

ret

divzn16 endp
; pla61b.asm - inmultirea a doua numere zecimal neimpachetate, de cate doua cifre (16 biti)

date segment word public 'data'


op1 dw 0808h ; numarul zecimal 88
op2 dw 0507h ; numarul zecimal 57
rezult dw 2 dup (0) ; rezultatul va fi: 5016
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
mov bx, op1 ; BX - primul operand
mov ax, op2 ; AX - al doilea operand
call multzn16
mov rezult, dx
mov rezult[2], ax
mov ax,4C00h
int 21h
; procedura determina produsul a doua valori zecimal neimpachetate (16 biti)
; (BX) = inmultitor zecimal neimpachetat (2 cifre)
; (AX) = deinmultit zecimal neimpachetat (2 cifre)
; (DX:AX) = rezultat zecimal neimpachetat (4 cifre: DH,DL,AH,AL =
; cifrele pentru: mii, sute, zeci, unitati
; (BX) = nemodificat

multzn16 proc near


push bx ; salvare registre de lucru
push cx
aad ; conversie zecimal nimpachetat (AX) - binar (AL)
mov ch, al ; salvare deinmultit binar
mov ax, bx ; conversie zecimal nimpachetat (BX) - binar (BL)
aad
mov bl, al ; salvare inmultitor
mov al, ch ; (AL) = deinmultit
mul bl ; dupa inmultire rezultatul este in (AX)
cwd ; extensie la produs de 32 biti (DX:AX)
mov cx, 1000 ; determinam cifra miilor,
div cx ; catul impartirii la 1000 in AX, restul in DX
xchg ax, dx ; restul il salvam in (AX)
mov dh, dl ; (DH) = cifra miilor
mov cl, 100 ; se determina cifra sutelor
div cl ; (AX) / 100 -> (rest=AH, cat=AL)
mov dl, al ; (DL) = cifra sutelor
mov al, ah ; (AL) = restul < 100
cbw ; extensie deimpartit la cuvant
mov cl, 10 ; se determina cifrele pentru zeci si unitati
div cl ; (AH) = restul (unitati), (AL) = catul (zeci)
xchg ah, al ; se pun cifrele, zeci si unitati, in ordinea specificata
pop cx ; refacerea registrelor de lucru
pop bx
ret
multzn16 endp

prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla61c.asm - impartirea a doua numere zecimal neimpachetate, de cate doua cifre (16 biti)

date segment word public 'data'


deimp dd 01090500h ; numarul zecimal 1950 (deimpartitul)
imp dw 0809h ; se imparte la numarul zecimal 89 (impartitorul)
cat dw ? ; rezultatul va fi: 21-cat, 81-rest
rest dw ?
mes_err db 'EROARE la impartire - depasire format', 0Ah, 0Dh, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
mov ax, word ptr deimp ; (DX:AX) - deimpartitul
mov dx, word ptr deimp[2]
mov bx, imp ; AX - impartitor
call divzn16
jc tip_mes_err
mov cat, ax
mov rest, dx
jmp gatap
tip_mes_err:
lea dx, mes_err
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

public divzn16
; (DX:AX) = deimpartit, (BX) = divizor
; (AX) = cat, (DX) = rest
; daca catul sau restul > 99 => CF = 1, altfel CF = 0

divzn16 proc near


push bx ; salvare registre afectate
push cx
aad ; conversie zecimal neimpachetat -> binar (zeci, unitati)
mov cx, ax ; salvare rezultat (zeci + unitati)
mov ax, dx ; conversie zecimal neimpachtat -> binar (mii, sute)
aad ; deimpartit maxim = 9999
mov dl, 100 ; se actualizeaza valoarea pentru cifrele mii, sute
mul dl
add cx, ax ; deimpartitul este in binar (CX)
mov ax, bx ; conversia divizorului
aad
mov bl, al ; divizorul < 99
mov ax, cx ; deimpartitul binar este in (AX)
div bl ; impartirea propriu-zisa (AH-restul, Al-catul)
mov bl, 99 ; este catul > 99
cmp bl, al
jc gata ; sau restul > 99
cmp bl, ah
jc gata
mov bl, al ; daca nu, salvez catul in (BL)
mov al, ah ; conversie rest la formatul neimpachetat (ASCII)
aam
mov dx, ax ; se depune restul zecimal neimpachtat in (DX)
mov al, bl ; conversie cat la formatul ASCII (neimpachetat)
aam
clc ; iesire normala, CF=0
gata: pop cx ; refacerea registrelor
pop bx
ret
divzn16 endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
Conversie din binar (16 biti) in zecimal neimpachetat/impachetat (binzn/binbcd)

binzn proc near


push bx
push dx
push di
mov bx, 100
mov dx, 0
div dx
push ax
mov ax, dx
aam
stosb
mov al, ah
stosb
pop ax
mov dx, 0
div bx
push ax
mov ax, dx
aam
stosb
pop al, ah
stosb
pop ax
stosb
pop di
pop dx
pop bx
ret
binzn endp
Conversie zecimal impachetat – binary (bcdbin)

bcdbin proc near


push cx
push dx
push di
push si
mov si, ax
sub ax, ax
call conv_bcd_bin
pop si
pop di
pop dx
pop cx
ret
bcdbin endp
conv_bcd_bin proc near
mov cx, 4
nextcif:push cx
mov cx, 4
mov di, 0
nextdig:shl si, 1
rcl di, 1
loop nextdig
mov cx, 10
mul cx
add ax, di
pop cx
loop nextcif
ret
conv_bcd_bin endp
Deplasare la stanga, pt un operand de 32 biti (sal32)

sal32 proc near


cmp cl, 0
je gata
push cx
push di
push si
sub di, di
sub ch, ch
shift: sal ax, 1
rcl dx, 1
jno cont
continua
mov di, 800h
cont: loop shift
pushf
pop si
or si, di
push si
popf
pop si
pop di
pop cx
gata: ret
sal32 endp
Deplasare aritmetica la dr, pt un operand de 32 biti (sar32)

sar32 proc near

cmp cl, 0

je gata

push cx

sub ch, ch

shift: sar dx, 1

rcr ax, 1

loop shift

pop cx

gata: ret

sar32 endp
Rotire la stanga (dreapta) pt valori de 32 biti, fara ‘carry’ (rol32/ror32)

rol32 proc near


cmp cl, 0
je gata
push cx
sub ch, ch
rotire: sal dx, 1
pushf
rcl ax, 1
adc dx, 0
popf
loop rotire
pop cx
gata: ret
rol32 endp

ror32 proc near


cmp cl, 0
je gata
push cx
sub ch, ch
rotire: shr ax, 1
pushf
rcr dx, 1
jnc refa_cf
or ax, 8000h
refa_cf:
popf
loop rotire
pop cx
gata: ret
ror32 endp
. Rotire la stanga(dreapta) pt valori de 32 biti, cu ‘carry’ (rol32/ror32)

rcl32 proc near


pushf
cmp cl, 0
jne cont
popf
ret
cont: popf
push cx
mov ch, 0
rot: rcl ax, 1
rcl dx, 1
loop rot
pop cx
ret
rcl32 endp

rcr32 proc near


pushf
cmp cl, 0
jne cont
popf
ret
cont: popf
push cx
mov ch, 0
rot: rcr dx, 1
rcr ax, 1
loop rot
pop cx
ret
rcr32 endp
; pla91.asm - concatenarea a doua siruri (concat)
date segment word public 'data'
sir2 db '-cel de-al doilea sir de concatenat'
lung2 equ $-sir2
db 0Dh, 0Ah, '$'
sir1 db 'Primul sir de concatenat'
lung1 equ $-sir1
loc_sir2 db 0Dh, 0Ah, '$'
db (lung2-3) dup(?), 0Dh, 0Ah, '$'
mesaj db 0Dh, 0Ah, 'Sirurile concatenate sunt:', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea dx, sir1 ; tiparire sir1
mov ah, 9
int 21h
lea dx, sir2 ; tiparire sir2
mov ah, 9
int 21h
lea di, sir1 ; initializare date pentru procedura de concatenare
mov bx, lung1
lea si, sir2
mov cx, lung2
push ds ; cele doua siruri sunt in acelasi segment
pop es ; registrul segment pentru destinatie ES=DS
call concat ; apelul procedurii de concatenare
jz gatap
lea dx, mesaj
mov ah, 9
int 21h
lea dx, sir1 ; tiparire sir concatenat
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

;intrari:(DI) = offset sir1, (BX) = lungimea sir1 (sirurile sunt in acelasi segment)
; (SI) = offset sir2, (CX) = lungimea sir2
;iesiri: (ZF) = 0, operatie efectuata, (SI) = noul offset al celui de-al doilea sir,
; (BX) = lungimea totala, dupa concatenare.
; (ZF) = 1 , operatie neefectuata, fie un sir este vid, fie al doilea este deja
; concatenat cu primul; registrele vor ramane nemodificate

dim2 dw ? ; salvare dimensiune initiala cel de-al doilea sir (CX)


off1 dw ? ; salvare offset initial primul sir (DI)
concat proc near
jcxz iesire ; daca unul din siruri este vid se termina procedura
cmp bx, 0
je iesire
mov dim2, cx ; salvare dimensiune sir 2
mov off1, di ; salvare offset sir 1
add di, bx ; adresa de concatenare a celui de-al doilea sir
cmp si, di ; test daca cel de-al doilea sir se afla deja aici
je gata ; adrese diferite -> nu este -> se concateneaza
conc: cld
rep movsb ; concatenarea celui de-al doilea sir
sub di, dim2 ; adresa de inceput a sirului concatenat
mov si, di ; se returneaza in (SI)
add bx, dim2 ; actualizarea adresei celui de-al doilea sir
gata: mov di, off1 ; refacerea registrelor modificate
mov cx, dim2
iesire: ret
concat endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla92a.asm - cautarea unui subsir intr-un sir
date segment word public 'data'
sir1 db 'Sirul in care se cauta ''subsirul cautat'' respectiv'
lung1 equ $-sir1
CRLF db 0Dh, 0Ah, '$'
sir2 db 'subsirul cautat'; subsirul cautat
lung2 equ $-sir2
db 0Dh, 0Ah, '$'
mesaj1 db 0Dh, 0Ah, 'Subsirul gasit in primul sir este:', 0Dh, 0Ah, '$'
mesaj2 db 0Dh, 0Ah, 'Subsirul nu a fost gasit!!!', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea dx, sir1 ; tiparire sir in care se cauta
mov ah, 9
int 21h
lea dx, sir2 ; tiparire subsir cautat
mov ah, 9
int 21h
lea di, sir1 ; initializare date pentru procedura de cautare subsir
mov bx, lung1
lea si, sir2
mov cx, lung2
push ds ; cele doua siruri sunt in acelasi segment
pop es ; registrul segment pentru destinatie ES=DS
call cautsub ; apelul procedurii de concatenare
jnz afis_subsir
lea dx, mesaj2
mov ah, 9
int 21h
jmp gatap
afis_subsir:
push dx ; se salveaza adresa subsirului gasit
lea dx, mesaj1
mov ah, 9
int 21h
pop bx
tip_sub:
mov dl, [bx] ; tiparire subsir gasit
mov ah, 2
int 21h
inc bx
loop tip_sub
lea dx, CRLF
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

;intrari: (DI) = offset sir in care se cauta, (BX) = lungime sir


; (SI) = offset subsir cautat, (CX) = lungime subsir
;iesiri: (ZF) = 0, subsir gasit, (DX) = offset-ul sirului gasit,
; (ZF)= 1, subsirul nu a fost gasit:(DX)=offsetul de inceput pentru
; ultima cautare, sau (DX) = 0 , daca subsir > sir

stop dw ? ; locatie oprire cautare


aici dw ? ; locatia curenta de cautare
salv_si dw ? ; salvare (SI) initial
salv_cx dw ? ; salvare (CX) initial
cautsub proc
jcxz gata; subsir vid
cmp bx, 0 ; test lungime sir
je gata ; sir vid
cmp cx, bx ; compar lungime subsir cu cea a sirului in care se cauta
jc caut ; daca lungime subsir < sir, se continua cutarea
je caut ; se cauta si daca cele doua lungimi sunt egale
sub dx, dx ; daca lungime subsir > sir -> DX=0, ZF=1
jz gata
caut: push bx
push di
mov salv_si, si
mov salv_cx, cx
add bx, di ; locatia de terminare a cautarii in sir
sub bx, cx ; loacatia de inceput a ultimei cautari : sf_sir - lung_sir + 1
inc bx
mov stop, bx ; salvata la adresa 'stop'
mov aici, di ; salvare adresa de inceput a cautarii
cld
cautare:
repe cmpsb ; repeta cautarea cat timp sunt egale
je gasit ; daca la terminarea repetarii (ZF) = 1 s-a gasit subsirul
inc aici ; altfel nu s-a gasit, se continua cautarea cu urmatoarea locatie
mov di, aici
cmp di, stop ; s-a ajuns la sfarsit ?
je ref_reg ; da si nu s-a gasit subsirul, se refac registrele
mov cx, salv_cx ; se reia cautarea
mov si, salv_si
jmp cautare
gasit: or cx, 1 ; s-a gasit , se pune (ZF) = 0
ref_reg: ; se refac registrele salvate
mov dx, aici ; adresa unde a ajuns ultima cautare
pop di
pop bx
mov cx, salv_cx
mov si, salv_si
gata: ret
cautsub endp

prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla92b.asm - stergerea unui subsir intr-un sir
date segment word public 'data'
sir db 'Sirul din care se sterge /'
subsir db 'subsirul de sters/ respectiv'
lung equ $-sir
CRLF db 0Dh, 0Ah, '$'
sbsir db 'subsirul de sters'; subsirul de sters
lungsb equ $-sbsir
db 0Dh, 0Ah, '$'
mesaj1 db 0Dh, 0Ah, 'Sirul ramas dupa stergere este:', 0Dh, 0Ah, '$'
mesaj2 db 0Dh, 0Ah, 'Subsirul nu a fost gasit!!!', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea dx, sir ; tiparire sir din care se sterge
mov ah, 9
int 21h
lea bx, subsir ; tiparire subsir de sters
mov cx, lungsb
tip_sbs:
mov dl, [bx]
mov ah, 2
int 21h
inc bx
loop tip_sbs
lea di, sir ; initializare date pentru procedura de stergere subsir
mov bx, lung
lea si, subsir
mov cx, lungsb
push ds ; cele doua siruri sunt in acelasi segment
pop es ; registrul segment pentru destinatie ES=DS
call sterge_sub ; apelul procedurii de stergere
jnz afis_sir
lea dx, mesaj2
mov ah, 9
int 21h
jmp gatap
afis_sir:
push bx ; se salveaza lungimea sirului, dupa stergere
lea dx, mesaj1
mov ah, 9
int 21h
pop cx
tip_sir:
mov dl, [di] ; tiparire sir ramas dupa stergere
mov ah, 2
int 21h
inc di
loop tip_sir
lea dx, CRLF
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

;intrari: (DI) = offset, (BX) = lungime sir


; (SI) = offset, (CX) = lungime subsir
;iesiri: (ZF) = 0 operatie efectuata, (BX) = lungimea curenta a sirului obtinut
; (ZF) = 1 nu s-a efectuat operatia de stergere ( subsir > sir, offset
; subsir in afara sirului, siruri vide ) si (BX) = nemodificat

sf_sir dw ? ; offset sfarsit sir + 1


sterge_sub proc
jcxz gata ; subsir vid
cmp bx, 0
je gata ; sir vid
cmp cx, bx ; se compara cele doua dimensiuni ( subsir / sir )
ja pune_zf ; subsirul este mai mare decat sirul
cmp si, di ; este subsirul in afara limitelor sirului
jb pune_zf ; daca da se termina proc. si seteaza (ZF)
mov sf_sir, di ; salvarea offsetului sirului
add sf_sir, bx ; s-a determinat adresa de sfarsit + 1, a sirului
cmp si, sf_sir ; depaseste subsirul limita sirului ?
jb sterge ; daca nu se efecueaza stergerea
pune_zf:
cmp cx, cx ; (ZF) = 1
jmp gata
sterge: ; eliminarea subsirului se face prin mutarea, din sirul dat,
; subsirul de la adresa (SI) + (CX) la adresa (SI)
push di ; salvarea registrelor de lucru
push si
push cx
cld ; directia de parcurgere
mov di, si ; se initializeaza destinatia
add si, cx ; si sursa transferului
sub sf_sir, si ; contor numar de octeti de transferat
mov cx, sf_sir
shr cx, 1 ; facem transeful pe cuvinte (mai rapid / sau pe dublu cuv.)
jnc transf_cuv ; avem un numar par de octeti
movsb ; se transfera un octet ( daca numarul lor este impar )
jcxz term_transf ; s-a terminat transferul (a fost un singur octet)
transf_cuv:
rep movsw ; se transfera subsirul, la nivel de cuvant
term_transf:
pop cx ; refacerea resurselor salvate
pop si
pop di
sub bx, cx ; actualizare lungime sir, dupa stergerea subsirului, (ZF)=0
gata: ret
sterge_sub endp

prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
Inserarea unui sir într-un alt sir

;intrari: (DI)=offset, (BX)=lungime sir, in care se insereaza


(SI)=offset, (CX)=lungime sir deinserat
(BP)=offsetul punctului de inserarea
;iesiri: (ZF) =0, oper efect, (BX) = lung totala a sirului obtinut
(SI) = noul offset al sirului inserat
(ZF) = 1nu s-a efectuat oper de ins (lungimi 0, al doilea sir era deja inserat, offs. de inserare este in
afara sirului)

off1 dw ? ;spatiu intre offset sir si


dim2 dw ? ;dimensiune subsir de inserat
insert_sir proc
jcxz gata ;sirul de inserat este vid
cmp bx, 0
je gata ;sirul in care se insereaza este vid
mov dim2, cx
mov off1, di
add di, bx ;offsetul de sfarsit (+1) al primului sir
cmp si, di ;este al 2-;ea sir deja inserat? (adr. Inceput sir1 > sf. Sir2)
ja insert ;nu, se face inserarea
push si
add si,cx ;offsetul de sfarsit (+1) al celui de-al 2 lea sir
cmp si, off1 ;se testeaza daca adresa de inceput a sirului 2 este in primul
pop si
jbe insert ;daca nu, se face inserarea
sub di, di ;daca da, nu se mai insereaza si (ZF) =1
jz iesire
insert:
std ;directie de parcurgere este de la sfarsit la inceput, pt
push si ;a nu se scrie peste urmatorii octeti
dec di ;initializare adrese pentru a crea spatiu pt sirul inserat
mov si,di
add di,cx ;adresa de sfarsit a subsirului transferat
rep movsb ;transfera restul din primul sir la sfarsit
cld ;se va insera sirul de la inceputul zonei eliberate
pop si ;refacerea adresei de inceput a sirului de inserat
mov cx, dim2 ;contor numar de octeti transferati
mov di, bp ;offsetul destinatie al transferului
rep movsb ;inserarea propriu-zisa
mov si,bp ;noul offset al sirului inserat
add bx, dim2 ;actualizare lungime sir 1
iesire: mov di,off1 ;refacere (DI)
mov cx,dim2 ;si (CX)
gata: ret
insert_sir endp
; pla92d.asm - copiere subsir intr-un sir
date segment word public 'data'
sir db 'Sirul in care se copiaza/'
poz_ins db '<-pozitie copiere /'
db ' (spatiu disponibil)'
lungs equ $-sir
CRLF db 0Dh, 0Ah, '$'
sbsir db 'subsirul de copiat' ; subsirul de copiat
lungsi equ $-sbsir
db 0Dh, 0Ah, '$'
mesaj1 db 0Dh, 0Ah, 'Sirul obtinut dupa copiere este:', 0Dh, 0Ah, '$'
mesaj2 db 0Dh, 0Ah, 'Subsirul nu a fost copiat!!!', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea dx, sir ; tiparire sir in care se copiaza
mov ah, 9
int 21h
lea dx, sbsir ; tiparire subsir de copiat
mov ah, 9
int 21h
lea di, sir ; initializare date pentru procedura de copiere subsir
mov bx, lungs
lea si, sbsir
mov cx, lungsi
lea bp, poz_ins ; offsetul pozitiei de copiere
push ds ; cele doua siruri sunt in acelasi segment
pop es ; registrul segment pentru destinatie ES=DS
call copiere_subsir ; apelul procedurii de copiere
jnz afis_sir
lea dx, mesaj2
mov ah, 9
int 21h
jmp gatap
afis_sir:
push bx ; se salveaza lungimea sirului, dupa copiere
lea dx, mesaj1
mov ah, 9
int 21h
pop cx
tip_sir:
mov dl, [di] ; tiparire sir obtinut dupa copiere
mov ah, 2
int 21h
inc di
loop tip_sir
lea dx, CRLF
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

;intrari: (DI) = offset, (BX) = lungime sir, in care se copiaza


; (SI) = offset, (CX) = lungime subsir, de copiat
; (BP) = offsetul de destinatie in sir, pentru copiere
;iesiri: (ZF) = 0 operatie efectuata, (BX) = lungimea este nemodificata
; (SI) = offsetul sirului copiat
; (BP) = offset subsir copiat
; (ZF) = 1 nu s-a copiat (siruri vide, subsirul este in sir sau subsirul > sir )

off1 dw ? ; salvare offset sir (DI)


dim2 dw ? ; salvare lungime subsir (CX)
; extrn mutabloc: near
copiere_subsir proc
jcxz gata ; sirul de copiat este vid
cmp bx, 0
je gata ; sirul in care se copiaza este vid
mov dim2, cx
mov off1, di
cmp cx, bx ; este subsirul mai mic decat sirul ?
jae err_cop ; nu -> nu se face copierea
add di, bx ; offsetul de sfarsit (+1) al sirului
cmp di, si ; este subsirul in sir ?
jae err_cop ; da -> nu se mai copiaza
cmp si, off1 ; este subsirul in sir ?
jb err_cop ; da -> nu se mai copiaza
add cx, si ; (CX) pozitionat la sfarsitul subsirului (+1)
cmp bp, di ; este destinatia <= sfarsit sir?
jae err_cop ; nu -> nu se mai copiaza
cmp bp, off1 ; este destinatia >= inceput sir?
jb err_cop ; nu -> nu se mai copiaza
mov ax, di ; test depasire spatiu rezervat sirului in care secopiaza
sub ax, bp ; octeti ramasi disponibili pentru copiere
cmp ax, dim2
jc err_cop ; daca nu, se termina
mov cx, dim2
mov di, bp
call mutabloc
mov si, bp ; noul offset subsir
gata: mov di, off1
mov cx, dim2
iesire: ret
err_cop:
sub di, di ; eroare -> (ZF) = 1
ret
copiere_subsir endp
; intrari : (SI) = adresa sursei
; (DI) = adresa destinatiei
; (CX) = contorul (numarul) de octeti de copiat
mutabloc proc near
push di ; salvarea registrelor afectate
push si
push cx
cmp di, si ; compara adresa sursei cu a destinatiei
jbe mai_mic ; daca este mai mica se muta sursa la destinatie
std ; daca este mai mare, atunci se parcurge invers, de la capat la inceput
add si, cx ; pozitionare la sfarsitul sursei
dec si ; pe ultimul octet
add di, cx ; pozitionare la sfarsitul destinatiei
dec di ; pe ultimul octet
jmp muta
mai_mic:
cld ; parcurgere directa
muta:
rep movsb ; muta octetii
pop cx ; refacerea registrelor de lucru
pop si
pop di
ret
mutabloc endp

prog ends

stiva segment stack 'stack'


dw 100 dup(?)
stiva ends
end start
; pla93.asm - determinarea maximului (minimului)
date segment word public 'data'
sir dw 7ABCh, 9865h, 0FDCEh, 1234h
lungs equ $-sir
max dw ? ; locatia unde se depune maximul
mesaj db 0Dh, 0Ah, 'Sirul vid de valori (maxim=?)', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea si, sir ; offset sir
mov cx, lungs ; lungime sir
call cuv_det_maxim ; apelul procedurii de determinare maxim
jz dep_max ; se depune maximul
lea dx, mesaj
mov ah, 9
int 21h
jmp gatap
dep_max:
mov max, ax
gatap: mov ax,4C00h
int 21h

;intrari: (SI), (CX) = offsetul si lungimea sirului in care se cauta,


;iesiri: (ZF) = 1, s-a determinat maximul (minimul), returnat in (AX)
; (ZF) = 0, sir vid

cuv_det_maxim proc
cmp cx, 0 ; sir vid ?
jnz maxim ; nu, se determina maximul
cmp cx, 1 ; (ZF) = 0, sir vid, se termina procedura
ret
maxim:
push bx
push si
lodsw ; prima valoare din sir
mov bx, ax ; initializeaza maximul din sir
jcxz gata ; s-a terminat sirul (a avut o singura valoare)
caut_max:
lodsw ; citeste urmatoarea valoare din sir
cmp ax, bx ; compar cu maximul {pentru minim in loc de 'jbe'->'jae'}
jbe next ; daca este <= maxim se trece la urmatorul (pentru valorile
; cu semn atunci in loc de 'jbe' se pune 'jle' {minim 'jge'})
mov bx, ax ; daca este > se inlocuieste maximul anterior cu cel nou gasit
next: loop caut_max ; se continua pana (CX) = 0
gata: mov ax, bx ; returnez maximul in (AX)
cmp ax, ax ; (ZF) = 1 semnaleaza ca procedura returneaza maximul
pop si
pop bx
ret
cuv_det_maxim endp
prog ends

stiva segment stack 'stack'


dw 100 dup(?)
stiva ends
end start
; pla94.asm - adaugarea unui cuvant (octet) la sfarsitul unui sir
date segment word public 'data'
sir dw 7ABCh, 9865h, 0FDCEh, 1234h
lungs equ $-sir
dw 2 dup (?) ; spatiu pentru adaugare
cuv dw 0F0Fh ; cuvantul de adaugat la sfarsitul sirului
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea si, sir ; offset sir
mov cx, lungs ; lungime sir
mov ax, cuv
call cuv_adaug_sir ; apelul procedurii de adaugare
mov ax,4C00h
int 21h

;intrari: (SI), (CX) = offsetul si lungimea sirului in care se adauga,


; (AX) = valoarea de adaugat la sfarsitul sirului
;iesiri: (CX) <- (CX) + 1

cuv_adaug_sir proc
push si
add si, cx ; adresa unde trebuie adaugat cuvantul
mov [si], ax
inc cx ; actualizare contor sir
pop si
ret
cuv_adaug_sir endp
prog ends

stiva segment stack 'stack'


dw 100 dup(?)
stiva ends
end start
Stergerea unui octet dintr-un sir, de octeti, neordonat

;intrari (SI), (CX) = offsetul si lungimea sirului in care se cauta


(SI) = offsetul elementului de sters
;iesiri (CF) = 1, nu s-a sters val -> (SI)=offsetul ei in afara sirului (sau sir vid)
(CF) = 0, (CX) <- (CX) – 1

oct_sterg proc
push cx
add cx, si ;adresa ultimului element din sir (+1)
cmp di, cx ;compar offset elem de sters cu ultimul din sir
jae afara ;daca este in afara sirului se termina proc
cmp di,si ;compar cu primul element din sir
jae sterg ;este dupa primul, deci se poate sterge
afara: stc ;nu este in sir si deci se term proc
pop cx
ret ;stergerea se face prin deplasarea elementelor urmatoare celui
;de sters cu o pozitie la stanga
sterg: push si
sub cx,di ;se determina nr de elemente de deplasat
dec cx
mov si, di ;sursa este dest +1
inc si
cld
rep movsb ;deplasarea sirului cu un octet, peste cel de sters
pop cx
dec cx ;actualizare contor sir
pop si
ret
oct_sterg endp
Ordonarea crescatoare a unui sir de cuvinte (octeti)
-folosind metoda bulelor (inversiunilor)
;intrari (SI),(CX) = offsetul si lungimea sirului de ordonat
Se considera cuvintele fara semn

inv dw ? ;se memoreaza daca au avut loc inversiui


ord_bule proc
jcxz revin
cmp cx,1 ;daca sirul are un singur element se termina procedur
jz revin ;intrucat nu avem ce ordona
push cx
dec cx ;nr de comparatii este = lungime_sir – 1
cld ;diretie de parcurgere
reia_ord:
push si ;salvare adresa de inceput a sirului si
push cx ;contorul (nr) de comparatii
mov inv, 0 ;initializare indicator de inversiuni
cont_ord:
lodsw ;citire cuvant in (AX); (SI) actualizat automat – va referi
cmp ax, [si] ;urmatorul element, apoi se compara (AX) cu acesta
jbe next ;daca e ord. Trece la urm. (cu semn, in loc de „jbe”->”jle”)
xchg ax,[si] ;daca nu, se inverseaza cele 2 cuv si
mov [si-2],ax ;
mov inv,1 ;se memoreaza ca s-a facut cel putin o inversiune
next: loop cont_ord ;se continua parcurgerea sirului pana la sfarsit
pop cx ;se reface contorul si adresa de inceput a sirului
pop si
cmp inv,1 ;au fost inversiuni
jz reia_ord ;daca da, se reia odonarea de la inceput
pop cx ;refacerea contorului initial
revin: ret
ord_bule endp
Ordonarea crescatoare a unui sir de octeti

.mode small
.stack 100h

.data
Vector db ‚130874563108746510354’,13,10 ;Vectorul de sortat + CRLF
nElem EQU $ - Vector – 2 ;nr de elemente de sortat

.code
start:
mov ax, @data ;setare segment de date
mov ds, ax
xor di,di ;di = primul index
cmp di, nElem ;verifica daca sunt elemente in vector
jge iesire ;daca nu, iesire prematura
for_i_start:
mov si,di ;si = al doilea index
inc si
cmp si, nElem
jge for_i_stop
for_i_start:
mov al,Vector[di]
cmp al,Vector[si] ;verifica ordinea
jbe for_i_stop
xchg al,Vector[si] ;inverseaza elementele
mov Vector[di], al
for_i_stop:
inc si
cmp si, nElem
jl for_i_start
for_i_stop:
inc si
cmp di, nElem
jl for_i_start
;afisare elemente sortate
mov ah, 40h ;scrie la handle
mov bx, 1 ;handle = ecran (stdout)
mov cx, nElem ;nr de caractere de scris
add cx,2 ;adauga linie noua (CRLF)
mov dx, offset Vector
int 21h ;scrie elementele
iesire:
mov ax, 4c00h ;iesire program
int 21h
end start
; pla97b.asm - inserarea unui octet (cuvant) intr-un sir ordonat crescator
; pozitia de inserare se determina folosind metoda de cautare binara

date segment word public 'data'


sir db 12h, 34h, 56h, 65h, 78h, 7Ah, 98h, 0ABh, 0BCh, 0CDh ; sirul in care cautam
lungs equ $-sir
db ? ; spatiu rezervat pentru inserare
valins db 068h ; valoarea de inserat
mesaj db 'Valoarea de inserat este deja in sir!!!', 0Dh, 0Ah, '$'
date ends
prog segment word public 'code'
assume cs: prog, ds: date
start: mov ax,date ; initializare DS
mov ds,ax
lea di, sir ; offset sir
mov cx, lungs ; lungime sir
mov al, valins ; valoarea de cautat
call oct_insert_bin ; apelul procedurii de inserare
jnz gatap
lea dx, mesaj
mov ah, 9
int 21h
gatap: mov ax,4C00h
int 21h

;intrari: (DI), (CX) = offsetul si lungimea sirului in care se cauta,


; (AL) sau (AX) = valoarea de inserat
;iesiri: (ZF) = 1, valoarea este deja in sir -> (SI) = offsetul acesteia,
; (ZF) = 0, s-a inserat valoarea, (SI) = offsetul acesteia, (CX) <- (CX)+1
; (DI) si (AL) sau (AX) nu vor fi modificate

; extrn caut_binar: near


public oct_insert_bin
oct_insert_bin proc
cmp cx, 0 ; este sirul vid ?
jnz caut ; daca nu, se cauta pozitia de inserare
mov [di], al ; se memoreaza octetul la prima adresa (sirul era vid)
jz gatai
caut: push cx
call caut_binar ; apel procedura de cautare binara
jnz compara ; testez (ZF), daca (ZF) = 1 valoarea exista
pop cx ; si nu mai trebuie sa o inseram
ret
;nu s-a gasit, determinam daca se insereaza chiar prima sau dupa ultima valoare din sir
compara:
cmp al, [si] ; este octetul curent > valoarea de inserat ?
jb face_loc ; nu ->trebuie pus pe prima pozitie -> se face loc
inc si ; da -> muta elementul cautat
;se face loc pentru noul octet si se insereaza
face_loc:
push es ; salvare (ES)
push ds
pop es ; initializare (ES)=(DS)
push di ; salvare offset de inceput
push si ; si pointerul curent
add di, cx ; destinatia transferului: adr. sfarsit + 1
inc di
sub cx, si ; numarul de octeti de mutat
inc cx
mov si, di ; adresa sursei
dec si
std ; transferul se face incepand de sfarsitul sirului
rep movsb ; transferul propriu-zis
pop si ; pozitia de inserare
mov [si], al ; inserare
pop di ; refacere resurse
pop es ; refacere (ES)
pop cx
inc cx ; actualizare contor sir
cmp cx, cx ; pozitionare (ZF) = 0, adica operatie efectuata
gatai: ret
oct_insert_bin endp

;intrari: (DI), (CX) = offsetul si lungimea sirului in care se cauta,


; (AL) sau (AX) = valoarea cautata
;iesiri: (ZF) = 1, s-a gasit valoarea cautata -> (SI) = offsetul acesteia,
; (ZF) = 0, nu s-a gasit valoarea, (SI) = offsetul ultimului element din sir

contor dw ? ; salvare contor sir


caut_binar proc
mov si, di ; copie offset
mov contor, cx ; salvare contor sir
jcxz nu_gasit ; sir vid -> termin cautarea
cmp al, [di] ; (AL) <= primul element
je gata
jb nu_gasit ; este mai mica decat prima valoare din sir (cea mai mica)
add si, cx ; offsetul ultimului element (+1)
dec si
cmp al, [si] ; se compara cu ultimul element din sir
je gata ; este chiar ultimul
ja nu_gasit ; este > cel mai mare element din sir
;aici incepe cautarea propriu-zisa
mov si, di ; se compara cu elementul din mijlocul sirului
shr cx, 1 ; index/2, cautarea ia sfarsit cand gaseste sau cand index = 0
add si, cx ; offsetul elementului din mijloc
compar:
jcxz nu_gasit ; index = 0 se termina cautarea
cmp al, [si] ; este valoarea = elementul curent ?
je gata ; da, s-a gasit
ja urmator ; nu, se continua cautarea in jumatatea superioara
;valoarea cautata poate fi in prima jumatate (ramasa din sir prin injumatatiri succesive)
shr cx, 1 ; injumatatire index
sub si, cx ; modifica adresa de inceput a cautarii (este in 1-a jumatate)
jmp compar ; reia cautarea
urmator:
shr cx, 1 ; injumatatire index
add si, cx ; actualizare adresa de cautare (este in cea de-a 2-a jumatate)
jmp compar ; reia cautarea
nu_gasit:
or cx, 1 ; nu s-a gasit, se pune (ZF)=0
gata:
mov cx, contor ; refacerea contorului
ret
caut_binar endp

prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
. Stergerea unui octet (cuvant) dintr-un sir ordonat crescator

;intrari (DI),(CX) = offsetul si lungimea sirului in care se cauta


(AL) sau (AX) = valoare de eliminat
;iesiri (ZF) = 0, valaorea nu este in sir
(ZF) = 1, s-a eliminat valoarea, (CX) <- (CX) -1
(DI) si (AL) sau (AX) nu vor fi modificate

extrn caut_binar: near


public oct_sterge_bin
oct_sterge_bin proc
push si
push cx
jcxz not_gasit ;sir vid
call caut_binar
jz sterge ;daca l-a gasit il sterg, (ZF)=1
not_gasit:
or cx,1 ;(ZF) =0, deci valoarea nu este in sir
pop cx ;daca nu l-a gasit se termina procedura
pop si
ret
;s-a gasit valoarea in sir si de sterge prin deplasarea elementelor din dreapta sa
sterge: push di
push es ;salvare (ES)
push ds
pop es ;initializare (ES)=(DS)
add cx,di ;se calculeaza nr de octeti de mutat
sub cx,di ;(DI)+(CX)-(SI)-1
dec cx ;contor numar de octeti de deplasat
mov di,si ;destinatia incepe de la pozitia celui sters
inc si ;sursa transferului incepe de la primul octet, dupa cel sters
cld
rep movsb ;deplasarea la stanga cu un octet
pop es
pop di
pop cx
dec cx ;actualizare contor, dupa stergere
cmp cx,cx ;pozitionare (ZF) =1, adica operatie realizata
pop si
ret
oct_sterge_bin endp
; pla98.asm - construirea unei liste inlantuite (de tip coada) de cuvinte
.model small
.data
dim_cuvant equ 15
lista_tip_coada struc
next dw 0
cuvant db dim_cuvant dup (0dh) ; dimensiune maxima cuvant
lista_tip_coada ends
lung_lista equ 80
lista lista_tip_coada lung_lista dup (<>)
mesprg db 'Programul construieste o coada de cuvinte introduse de la tastatura.', 0Dh, 0Ah
db 'Introducerea ia sfarsit cu caracterul ''#'' la inceput de linie!', 0Dh, 0Ah
db 'Introduceti cate un cuvant (max. 15 car.) pe linie (max. 100 cuv.)', 0Dh, 0Ah
db '$'
.stack 100h

.code
linie_noua proc ; trecere la o linie noua
mov dl, 0ah
mov ah, 2
int 21h
mov dl, 0dh
mov ah, 2
int 21h
ret
linie_noua endp

start: mov ax, @data ; initializari: adresa de segment


mov ds, ax
lea dx, mesprg ; mesaj pentru lansarea programului
mov ah, 9
int 21h
mov bx, offset lista ; offset inceput lista
mov si, size lista_tip_coada ; dimensiunea unei componente a listei
mov cx, lung_lista ; dimensiunea maxima a listei
iar:
push cx ; salvare dimensiune maxima a listei
mov cx, dim_cuvant ; numarul maxim de caractere ale unui cuvant
mov di, 0
cit_cuv:
mov ah, 1 ; citire caracter
int 21h
cmp al, '#' ; se termina cand se intalneste caracterul "#"
jnz sf_cuv? ; este sfarsit de cuvant ? (marcat de tasta RETURN)
pop cx ; s-a terminat lista de cuvinte, se descarca stiva
call linie_noua ; se trece pe o linie noua si urmeaza
jmp tiparire ; tiparirea listei de cuvinte
sf_cuv?:
cmp al, 0dh ; cuvintele se termina cind se apasa CR .
jz gata_cuv ; daca este sfarsit de cuvant s etrece pe o linie noua
mov [bx].cuvant[di], al ; daca nu, se depune caracterul in elementul curent
inc di ; actualizare index pentru urmatorul caracter
loop cit_cuv ; continua citirea cuvantului (maxim 'dim_cuvant' caractere)
call linie_noua
jmp next_cuv ; trece la cuvantul urmator
gata_cuv:
mov dl, 0ah ; trecem pe o linie noua, codul 0Dh a fost deja transmis
mov ah, 2
int 21h
next_cuv:
mov ax, bx ; calcul adresa urmatorului element din lista:
add ax, si ; offset curent(BX) + dimensiune element(SI)
mov [bx].next, ax ; actualizarea referintei elementului curent cu referinta la
; urmatorul
add bx, si ; adresa elementului urmator din lista
pop cx ; refacere contor numar maxim de elemente in coada
loop iar ; se reia ciclul daca nu s-a atins limita maxima 'lung_lista'
tiparire: ; altfel se termina introducerea si urmeaza
mov bx, offset lista ; offset de inceput lista
mov cx, lung_lista ; dimensiunea maxima a listei
reia1:
mov dl, 0ah ; linie noua
mov ah, 2
int 21h
mov di, 0 ; index caracter in cadrul cuvantului
push cx ; salvare contor maxim de cuvinte
mov cx, dim_cuvant ; dimensiune maxima cuvant
reia: cmp [bx].next, 0 ; este ultimul element din lista ?
jz gata_tip ; da, s-a terminat tiparirea
mov dl, [bx].cuvant[di] ; nu, se tipareste caracterul curent
mov ah, 2
int 21h
cmp [bx].cuvant[di], 0dh ; este sfarsit de cuvant ?
jz gata_tip_cuv ; da, se trece la cuvantul urmator
inc di ; nu, actualizare index caracter, in cadrul cuvantului
loop reia ; si se reia, daca nu s-a ajuns sfarsitul cuvantului
call linie_noua
gata_tip_cuv:
mov bx, [bx].next ; se trece la cuvantul urmator
pop cx ; test pentru numarul maxim de cuvinte, daca nu s-a
loop reia1 ; intalnit offsetul 0, pentru sfarsit de lista
gata_tip:
mov ax, 4c00h
int 21h
end start
. Evaluarea expresiilor in notatie postfixata

.model small
.stack 100h

.data
expresie db ‚1234+++4*9-9-9-9-9-1*8+’, 0

.code
mov ax, @data ;setare segment de date
mov ds,ax
mov si, offset expresie
bucla:
lodsb ;ia un caracter din string
or al,al ;e caracter terminator?
jz iesire ;daca da, iesire din program
cmp al, ‘+’ ;e plus?
je plus
cmp al, ‘-‘
je minus ;e minus?
cmp al, ‘*’
je inmultire
sub al, ‘0’ ;aici testam pt un operand
xor ah,ah ;il extindem pe 16 biti
push ax ;si il punem pe stiva
jmp bucla
plus:
pop bx ;aduna
pop ax
add ax,bx
push ax
jmp bucla
minus:
pop bx
pop ax
sub ax,bx
push ax
jmp bucla
inmultire:
pop bx
pop ax
imul bx
push ax
jmp bucla
iesire:
pop ax ;extrage rezultat din stiva
mov ax, 4c00h ;iesire in DOS
int 21h
end
; pla62.asm - conversie din binar (16 biti) in zecimal neimpachetat / impachetat.

date segment word public 'data'


val dw 23456 ; valoarea de convertit
valzec db 5 dup (?) ; numarul zecimal neimpachetat (convertit)
date ends

prog segment word public 'code'


assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
mov ax, VAL ; AX - valoarea de convertit
push ds ; initializare ES:DI cu adresa rezultatului
pop es
lea di, valzec
call binzn ; apel functie de conversie binar -> zecimal neimpachetat
mov ax,4C00h
int 21h

;intrari: (AX) = valoarea de convertit, care este in intervalul 0÷65535


;iesiri: (ES:DI) = segment:offset, unde se depun cifrele numarului zecimal neimpachetat
; (DI) = refera ultima cifra a numarului zecimal neimpachetat (5 cifre)

binzn proc near


push bx ; salvare resurse
push dx
push di
mov bx,100 ; impartitor
mov dx,0 ; extensie semn deimpartit pozitiv
div bx ; (DX) = ultimele 2 cifre (zeci, unitati)
push ax ; salvare cat
mov ax,dx ; ultimele doua cifre, in format binar
aam ; corectie zecimal neimpachetata
stosb ; depunem cifra unitatilor
mov al,ah ; cifra zecilor
stosb ; se depune
pop ax ; se continua algoritmul pentru celelalte 3 cifre
mov dx,0 ; extensie semn deimpartit, pozitiv
div bx ; (DX) = cifrele: mii, sute; (AX) = zeci de mii
push ax
mov ax,dx
aam ; corectie zecimala neimpachetata pentru cifrele: mii, sute
stosb ; depunere cifra zecilor
mov al,ah ; cifra miilor
stosb ; se depune
pop ax ; cifra zecilor de mii este in (AL) si nu necesita corectie
stosb ; se depune in memorie
pop di
pop dx
pop bx
ret
binzn endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
; pla63.asm - conversie zecimal impachetat, BCD, (16 biþi) -> binar (cuvant)

date segment word public 'data'


val dw 3456h ; valoarea zecimal impachetata, de convertit
valzec dw 1 dup (?) ; numarul binar (convertit)
date ends

prog segment word public 'code'


assume cs: prog, ds: date
start: mov ax,date ; init. reg. segment ds
mov ds,ax
mov ax, val ; AX - valoarea de convertit
call bcdbin ; apel functie de conversie BCD -> binar
mov ax,4C00h
int 21h

;intrari: (AX) = numarul BCD de convertit in binar, se copiaza si in (SI),


;iesiri: (AX) = valoarea convertita

bcdbin proc near


push cx ; se salveaza registele de lucru
push dx
push di
push si
mov si, ax ; salvare numar initial
sub ax, ax ; initializare rezultat cu 0
call conv_bcd_bin
pop si ; refacerea registrelor salvate
pop di
pop dx
pop cx
ret
bcdbin endp

conv_bcd_bin proc near


; procedura primeste in AX, zero, si va returna valoarea in binar
; primeste in SI valoarea BCD, de convertit
mov cx, 4 ; contor numar de cifre
nextcif:push cx ; salvare contor
mov cx, 4
mov di, 0
nextdig:shl si, 1 ; se deplaseaza cate o cifra
rcl di, 1 ; in registrul di
loop nextdig
mov cx, 10 ; baza in care este numarul
mul cx ; valoarea anterioara *10 + noua cifra
add ax, di
pop cx ; refacere contor
loop nextcif
ret
conv_bcd_bin endp
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
Conversie din binar in hexazecimal (ASCII) (binhex)

;intrari (AL) – valoare intre 0-15


;iesiri (AL) un caracter ASCII (‘0’-‘9’ sau ‘A’-‘F’)
daca valoarea este coreta (CF) = 0, (AL) = caract ASCII
daca valoarea este invalida (CF) = 1 si (AL) nemodificat

binhex proc
cmp al,9
ja litera
add al, 30h ;codul ASCII pentru cifre
ret
litera: cmp al, 15
ja eroare ;daca este mai mare ->eroare
add al,37h ;codul ASCII pt litere A-F
ret
eroare:
stc ;iesire cu eroare (CF = 1)
ret
binhex endp

Conversia se poate realiza utilizând si instructiunea de conversie de cod (XLAT), cu exemplul urmator, care
afiseaza, in hexazecimal, valoarea de la adresa ‘val’, din segm de dim ‘hexa’.

hexa segment word public ‘data’


val dw oabcdh; valoare de convertit si afizat in hexazecimal
val_hexa db 4dup (?),0dh,0ah,’$’; rezervare pt codurile ASCII
tab db ‘0123456789acdef’ ;tabela de conversie

hexa ends
prog segment word public ‘code’
assume cs:prog, ds:hexa
start: mov ax,hexa ;initializare registru segment DS
mov ds,ax ;cu adresa segmentului de date: hexa
mov dx,val ;valoarea de tiparit in hexazecimal
and dx, 0ff00h ;se retin doar primele doua cifre hexa
mov dl,dh ;deci primii 8 biti, se se transmit in DL
lea si, val_hexa ;adresa unde se depun codurile ASCII
call conv ;proc de conversie binar-hexa (ASCII)
mov dx, val ;se refacere valoarea initiala
and dx, 0ffh ;se retin ultimii 8 biti (ultimele 2 cifre hexa)
call conv ;conversia ultimelor doua cifre hexa
lea dx, val_hexa ;adresa codurilor ASCII ale cifrelor ASCII
mov ax, 9 ;apel functia 9, DOS, de tiparire mesaj
int 21h
mov ax, 4c00h ;revenire dos
int 21h
conv: proc ;procedura tipareste in hexa valoarea din DL
mov al, dl ;se transfera in AL
mov cl,4 ;se vor deplasa (logic) primi patru biti
shr al, cl ;pr ultimele 4 pozitii
lea bx,tab
xlat tab ;se face conversia acestei valori la codul ASCII
mov [si],al ;se depune prima cifra ASCII la adresa val_hexa
inc si ;se incrementeaza adresa pt urmatoarea cifra
mov al, dl ;se reface valoarea transmisa in DL
and al,0fh ;si se vor retine din aceasta doar ultimii 4 biti
xlat tab ;se face conversia acestei tetrade in ASCII
mov [si], al ;se depune codul in memorie la adresa urmatoare
inc si ;se actualizeaza adresa pt urmatoarele cifre
ret ;revenire din procedura
conv: endp
prog ends

stiva segment word stack ‘stack’


dw 100 dup(?) ;rezervare memorie pt segm de stiva
stiva ends
. Conversie din binar in octal (ASCII)

date_oct segment word public ‘data’


val dw 12345q
date_oct ends

prog segment word public ‘code’


assume cs:prog, ds: date_oct
start: mov ax, date_oct
mov ds, ax
mov dx, val
rol dx, 1
mov al, dl
and al, 1
add al, 30h
call tip_car
mov cx, 5
reia: push cx
mov cl, 3
rol dx, cl
mov al, dl
and al, 7
add al, 30h
call tip_car
pop cx
loop reia
mov ax, 4c00h
int 21h
tip_car proc near
push dx
mov dl, al
mov ah, 2
int 21h
pop dx
ret
tip_car endp
prog ends

stiva segment word stack ‘stack’


dw 100 dup(?)
stiva ends
end start
. Conversie din hexazecimal (ASCII) in binar (hexbin)

hexbin proc
cmp al, ‘0’
jc gata
cmp al, ‘9’
jbe cifra
cmp al, ‘A’
jc gata
cmp al, ‘F’
jbe litera
stc
ret
cifra: and al, 0fh
ret
litera: and al, 0fh
add al, 9
gata: ret
hexbin endp
Conversie nr binar, fara semn (16 biti), in zecimal-ASCII(ubin2ascii)

public ubin2ascii
ubin2ascii proc near
push bx
push dx
push ax
mov bx, 100
mov dx, 0
div bx
push ax
mov ax, dx
aam
add ax, 3030h
mov [di+4], al
mov [di+3], ah
pop ax
mov dx, 0
div bx
push ax
mov ax, dx
aam
add ax, 3030h
mov [di+2], al
mov [di+1], ah
pop ax
add al, 30h
mov [di], al
mov byte ptr [di+5], 0
pop ax
pop dx
pop bx
ret
ubin2ascii endp
Conversie numar binar, cu semn (16 biti), in zecimal-ASCII (sbin2ascii)

extrn ubin2ascii:near
sbin2ascii proc near
push di
push ax
mov byte ptr [di], ‘+’
cmp ax, 0
jge cont
mov byte ptr [di], ‘-‘
neg ax
cont: inc di
call ubin2ascii
pop ax
pop di
ret
sbin2ascii endp
.model small
.stack 100h
.data
primul dw 0fedch, 0abcdh, 03defh, 0h, 0h, 0h ; numar pozitiv
lung_1 dw ($ - primul)/2
al_doilea dw 0a8adh, 7fe2h, 0a876h, 08000h, 0ffffh ; numar negativ
lung_2 dw ($ - al_doilea)/2
; in aceasta reprezentare numarul al doilea este mai mic, intrucat are 5 cuvinte
; fata de primul care are 6 ("mai mare"= din punct de vedere al spatiului alocat)
.code
start: mov ax, @data ; initializare adresa segment date
mov ds, ax
; se determina cel mai mare numar, unde se va memora rezultatul
; vom considera ca (BX)= adresa numarului mai lung
; (DX)= dimensiunea numarului mai lung
; (BP)= adresa numarului mai scurt
; (CX)= dimensiunea acestuia
; (DI) = va contine extensia de semn a numarului mai scurt
; numarul de octeti ai numarului mai mic va controla bucla_1
; in care ambele numere au cuvinte ce trebuie adunate
; diferenta dimensiunilor celor doua numere va controla bucla_2
; necesara daca apare transport final, pentru propagarea acestuia
mov dx, lung_2 ; presupun, initial numarul al
lea bx, al_doilea ; doilea mai mare, ca spatiu de memorie alocat
mov cx, lung_1
lea bp, primul
cmp dx, cx ; verific presupunerea facuta
jge num2_mai_mare ; daca e respectata se continua
xchg bx, bp ; daca nu se schimba intre ele continutul
xchg cx, dx ; perechilor de registre, respective
num2_mai_mare:
push cx ; salvare lungime numar mai scurt
mov di, 0 ; extensie de semn pentru numar pozitiv
mov si, bp ; adresa de inceput a numarului mai scurt
shl cx, 1 ; lungimea * 2 = numar octeti ai numarului
add si, cx ; se pozitioneaza pe primul element
sub si, 2 ; care contine bitul de semn
mov ax, [si] ; si ii testam bitul de semn
cmp ax, 0 ; daca este pozitiv se continua cu valoarea
jge cont ; initiala pentru (di)=0
mov di, 0ffffh ; altfel (di)=ffffh, extensie semn -
cont: pop cx ; refacerea contorului
sub dx, cx ; determin diferenta dintre lungimile lor
clc ; (CF)=0
mov si, 0 ; se initializeaza indexul elementelor
bucla_1: mov ax, ds:[bp][si]
adc [bx][si], ax
inc si ; actualizare index
inc si
loop bucla_1 ; (CX)=contor pentru adunare
mov cx, dx ; contor pentru propagarea transportului
bucla_2: adc word ptr [bx][si], di ; si a semnului
inc si
inc si
loop bucla_2
; in acest punct se ajunge daca apare un transport, adica se depaseste dimensiunea initiala
; a numarului mai lung, in acest caz transportul trebuie memorat la adresa urmatoare
; daca s-a rezervat spatiu, sau semnalata aceasta depasire printr-un indicator, CF de exemplu,
; pentru numerele fara semn
; pentru numerele cu semn: se testeaza OF pentru a detecta o depasire
; a dimensiunii initiale a numarului mai lung
gata: mov ax,4c00h
int 21h
end start
- insumarea valorilor de tip cuvant dintr-un sir

date segment word public 'data'


sir dw 0cde4h,0543ah,08765h,0efh,043h,100,1000
lung_sir equ ($-sir)/2
rezult dw 2 dup (0)
date ends

prog segment word public 'code'


assume cs: prog, ds: date, ss: stiva
start: mov ax, date ; init. reg. segment ds
mov ds, ax
mov ax, 0 ; init. suma cu 0
mov bx, 0 ; suma se va pastra in registrele (BX:AX)
mov si, 0 ; index adresare elemente sir
mov cx,lung_sir ; contor = numarul de elemente din sir
jcxz gata ; test daca sirul este vid
reia: add ax, sir[si] ; se aduna elementul curent din sir
jnc urm ; salt daca nu este transport
inc bx ; daca da, se contorizeaza transporturile
urm: add si, type sir; se actualizeaza indexul pentru elementul urmator
loop reia ; (cx)-1, daca cx<>0 salt 'reia'
gata: mov rezult, ax ; se depune rezultatul
mov rezult[2], bx
mov ax, 4c00h ; revenire in DOS
int 21h
prog ends

stiva segment word stack 'stack'


dw 100 dup (?)
stiva ends
end start
conversia unui nr zecimal fara semn (ascii)in binar
DX10 macro
push ax
mov ax,dx
shl dx, 1 ;(DX)*2
shl dx, 1 ;(DX)*4
add dx,ax ;(DX)*5
shl dx, 1 ; (DX)*10
pop ax
endm
salvax dw ? ;locatie pentru salvarea valorii initiale pentru (AX)
adubin proc near
push cx
push dx
push si
mov salvax,ax
cmp cx,5 ;numarul de cifre este mai mare decat 5?
ja invalid
cld
mov si,dx ;initializare (SI) cu offsetul sirului
sub dx,dxnextcar:
DX10;inmultire DX*10
jc invalid;daca rezultatul depaseste limita (65535)
lodsb;se citeste urmatoatea cifra din numar
cmp al, '0'
jb invalid
cmp al,'9'
ja invalid
and ax,0fh;se pune pe zero prima tetrada din (AL) si(AH)
add dx,ax;se aduna cifra curenta
jc invalid
loopnextcar
mov ax, dx
jmp gata
invalid:
stc
mov ax,salvax
gata:pop si
pop dx
pop cx
ret
adubin
endp
Cautarea unui octet(cuv) intr-un sir ordonat cresc
;in (DI),(CX)=offsetul si lung sirului in care se cauta, (AL) sau (AX) = val cautata.
;out(ZF)=1(0) (nu)s-a gasit val cautata -> (SI)=offsetul acesteia(urm).
contor dw ?
caut_binar proc
mov si, di
mov contor, cx
jcxz nu_gasit
cmp al, [di];(AL)<=primul element
je gasit
jb nu_gasit
add si, cx;offsetul ultimului element (+1)
dec si
cmp al, [si]
je gata
ja nu_gasit
mov si, di ;se compara cu elem din mijl
shr cx, 1 ;index/2, cautarea end cand gasit sau index=0
add si, cx ;offsetul elem din mijl
compar:
jcxz nu_gasit
cmp al, [si]
je gasit
ja urmator
shr cx,1 ;index/=2
add si, cx ;actual adr:in cea de-a 2-a jumatate
jmp compare
nu_gasit:
or cx, 1
gata:
mov cx, contor
caut_binar endp
44Sa se caute o valoare intr-un sir(cu stiva)
Adresa sirului (offset+segment),dimesiune si valoare se transmit prin stiva. Daca elementul e gasit,
se intoarce offsetul in stiva.

afis_sir macro sir1


lea dx, sir1
mov ah, 09h
int 21h
endm
cauta proc
push bp
mov bp, sp
xor cx, cx
mov cx, [bp + 6]
xor ax, ax
mov al, [bp + 8]
xor bx, bx
mov bx, [bp + 4]
mov di, bx
repnz scasb
dec di
mov [bp + 4], di
pop bp
ret
endp cauta
start :
mov ax, @data
mov ds, ax
push ds
pop es
afis_sir mesaj1
afis_sir cr
lea dx, sir
mov ah, 0ah
int 21h
afis_sir cr
xor bx, bx
mov bl, sir[1]
mov lung, bl
mov sir[bx + 2], '$'/
afis_sir mesaj2
afis_sir cr
mov ah, 01h
int 21h
mov val, al
afis_sir cr
xor bx, bx
mov bl, val
push bx
xor bx, bx
mov bl, lung
push bx
lea dx, sir + 2
push dx
call cauta
pop dx
mov bx, dx
mov dl, [bx]
mov ah, 02h
int 21h
mov ah, 4ch
int 21h
end start
45Sa se citeasca un sir de la tast pana la apasarea tastei RETURN. Sa se afiseze
siru si inversul lui unul sub altul
afis_sir macro ssi
lea dx, ssi
mov ah, 09h
int 21h
endm
inverseaza proc
push bp
mov bp, sp
xor bx, bx
mov bx, [bp + 6]
mov sir2[1], bl
mov sir2[bx+1], '$'
mov si, bx
xor cx, cx
mov cl, bl
mov bx, [bp+4]
adauga :
xor ax, ax
mov al, [bx]
mov sir2[si],al
dec si
inc bx
loop adauga
pop bp
ret
endp inverseaza
start :
mov ax, @data
mov ds, ax
push ds
pop es
afis_sir mesaj1
afis_sir cr
lea dx, sir1
mov ah, 0ah
int 21h
xor bx, bx
mov bl, sir1[1]
mov lung, bl
mov sir1[bx + 2], '$'
afis_sir cr
afis_sir mesaj2
afis_sir cr
xor bx, bx
mov bl, lung
push bx
lea dx, sir1 + 2
push dx
call inverseaza
pop dx
lea dx, sir2 + 1
mov ah, 09h
int 21h
mov ah, 4ch
int 21h
end start
45Sa se citeasca un sir de la tast pana la apasarea tastei RETURN. Sa se afiseze siru si inversul lui unul
sub altul
afis_sir macro ssi
lea dx, ssi
mov ah, 09h
int 21h
endm
inverseaza proc
push bp
mov bp, sp
xor bx, bx
mov bx, [bp + 6]
mov sir2[1], bl
mov sir2[bx+1], '$'
mov si, bx
xor cx, cx
mov cl, bl
mov bx, [bp+4]
adauga :
xor ax, ax
mov al, [bx]
mov sir2[si],al
dec si
inc bx
loop adauga
pop bp
ret
endp inverseaza
start :
mov ax, @data
mov ds, ax
push ds
pop es
afis_sir mesaj1
afis_sir cr
lea dx, sir1
mov ah, 0ah
int 21h
xor bx, bx
mov bl, sir1[1]
mov lung, bl
mov sir1[bx + 2], '$'
afis_sir cr
afis_sir mesaj2
afis_sir cr
xor bx, bx
mov bl, lung
push bx
lea dx, sir1 + 2
push dx
call inverseaza
pop dx
lea dx, sir2 + 1
mov ah, 09h
int 21h
mov ah, 4ch
int 21h
end start
Fctie cu param transmisi prin stiva:segm sir,offset,nrcaract segme sir nr pare,offset sir nr pare si
msj daca obtin sir vid

afis_car macro car


mov dl, car
mov ah, 02h
int21h
endm
constructie proc
push bp
mov bp, sp
xor si, si
xor di, di
mov cx, [bp + 4]
mov ax, 0
repeta :
mov bx, [bp + 6]
mov dx, [bx + si]
clc
shr dx,1
jc continua
mov bx,[bp +6]
mov dx, [bx + si]
mov bx, [bp + 8]
mov [bx + di] , dx
inc di
inc di
inc ax
continua :
inc si
inc si
loop repeat
mov [bp + 4], ax
pop bp
ret
endp constructive
start :
mov ax, @data
mov ds, ax
push ds
pop es
lea dx,sir2
push dx
lea dx, sir1
push dx
xor ax, ax
mov al, lung1
push ax
call constructive
pop cx
mov si, 0
afisare :
mov di, cx
xor ax, ax
xor bx, bx
xor cx, cx
xor dx,dx
mov ax,sir2[si]
mov bx, 100
mov dx, 0
div bx
mov cx, dx
mov dx, 0
div bx
push dx
add al, 30h
afis_car al
pop ax
aam
add ax, 3030h
mov dx, ax
xchg dh, dl
afis_car dl
xchg dh, dl
afis_car dl
mov ax, cx
aam
add ax, 3030h
mov dx, ax
xchg dh, dl
afis_car dl
xchg dh, dl
afis_car dl
mov cx, di
inc si
inc si
loop afisare
mov ah, 4ch
int 21h
end start
numarare biti 1 dintr-o zona de mem si afisat in hexa

afis_sir macro sir


lea dx, sir
mov ah, 09h
int 21h
endm

afis_car macro c
push a
mov dl, c
mov ah, 02h
int 21h
pop a
endm

calc proc
push bp
mov bp, sp
mov cx, 4
mov si, 0
mov bx, [bp + 4]
xor dx, dx
repeta:
lea di, tab_inv
push cx
shl dx, 4
xor ax, ax
mov al, [bx + si]
mov cx, 16
repne scasb
add dx, cx
inc si
pop cx
loop repeat
mov [bp + 6], dx
pop bp
ret
endp calc

afisare_hexa proc
lea bx, tab_conv
mov dx, ax
and al, 0fh
xlat tab_conv
xor cx, cx
mov cl, al
push cx
mov ax, dx
shr al, 4
xlat tab_conv
xor cx, cx
mov cl, al
push cx
mov ax, dx
mov al, ah
and al, 0fh
xlat tab_con
xor cx, cx
mov cl, al
push cx
mov ax, dx
mov al, ah
shr al, 4
xlat tab_conv
afis_car al
xor ax, ax
pop ax
afis_car al
xor ax, ax
pop ax
afis_car al
xor ax, ax
pop ax
afis_car al
ret
afisare_hexa endp

start :
mov ax, @data
mov ds, ax
push ds
pop es
lea dx, adr
mov ah, 0ah
int 21h
afi_sir cr
lea dx, off
mov ah, 0ah
int 21h
afis_sir cr
mov dx, adrs
push dx
lea dx, adr + 2
push dx
call calc
pop dx
pop dx
mov adrs, dx
mov dx, adro
push dx
lea dx, off+2
push dx
call calc
pop dx
pop dx
mov adro, dx
les di,adresa
mov al,es:[di]
mov ah, 4ch
int 21h
end start
O procedura care spune daca un vector e ordonat sau nu. Parametrii si rezultatul se
transmit prin stiva

afis_sir macro s
lea dx, s
mov ah, 09h
int 21h
endm

verificare proc
push bp
mov bp, sp
mov cx, [bp + 4]
mov di, 0
mov si, 0
dec cx

verif :
xor ax, ax
xor bx, bx
mov bx, [bp + 6]
mov ax, [bx + si]
mov dx, [bx + si +1]
cmp dl, al
jna final
inc si
loop verif
mov di, 1
final :
mov [bp + 4], di
pop bp
ret
endp verificare

start :

mov ax, @data


mov ds, ax
push ds
pop es
lea dx, sir
push dx
xor ax, ax
mov al, lung
push ax
call verificare
pop ax
cmp ax, 0
jne da
jmp nu
da :
afis_sir mesaj1
jmp sfarsit
nu :
afis_sir mesaj2
sfarsit :
mov ah, 4ch
int 21h
end start
Suma elementelor dintr-un vector folosind stiva

afis_car macro c

mov dl, c
mov ah, 02h
int 21h
endm

adun proc
push bp
mov bp, sp
mov cx, [bp + 6]
mov bx, [bp + 4]
mov si, 0
repet :
mov ax, [bp + 8]
mov dx, [bx + si]
adc ax, dx
mov [bp + 8], ax
inc si
inc si
loop repet
pop bp
ret
endp adun

start :
mov ax, @data
mov ds, ax
push ds
pop es
mov suma, 0
push suma
mov ax, lung
push ax
lea dx, sir
push dx
call adu
pop dx
pop dx
pop dx
mov suma, dx
mov ax, suma
mov bx, 100
mov dx, 0
div bx
mov cx, dx
mov dx, 0
div bx
push dx
add al, 30h
afis_car al
pop ax
aam
add ax, 3030h
mov dx, ax
xchg dh, dl
afis_car dl
xchg dh, dl
afis_car dl
mov ax, cx
aam
add ax, 3030h
mov dx, ax
xchg dh, dl
afis_car dl
xchg dh, dl
afis_car dl
mov ah, 4ch
int21h
end
51Citeste doua siruri de la tastatura.afiseaza sirurile si numarul de aparitii a unui sir in
celalalt sir

Start:
mov ax,@data
mov ds,ax
mov es,ax
lea dx,sir1
mov cx,lungime1
mov bx,0
mov ah,3Fh
int 21h
lea dx,sir2
mov cx,lungime2
mov bx,0
mov ah,3Fh
int 21h
movcx,ax;
subcx,2;
lea dx,NewLine
movah,9
int21h
lea dx,sir1
mov ah,9
int 21h
lea dx,sir2
mov ah,9
int21h
movdi,0
movcx,0
Loopsir1:inc cx
inc di
mov si,1
mov al, sir1[di-1]
cmpal, sir2[si-1]
je Loopsir2
dec cx
cmp di,lungime1
je Loop0
jmp Loopsir1
Loopsir2:cmp di,lungime1
je Loop0
cmp si,lungime2
je Loop1
inc di
inc si
moval, sir1[di-1]
cmpal, sir2[si-1]
jeLoopsir2
jmpLoopsir1
deccx
Loop0:movax,cx
movdi,0
movcl,0Ah
Loop1:cmpal,0
jeEnd1
movah,0
divcl
addah,30h
movNumar[di],ah
incdi
jmpLoop1
End1:lea dx,NewLine
movah,9
int21h
movah,02h
Loop2:cmpdi,0
jeEnd2
decdi
movdl,Numar[di]
int21h
jmpLoop2
End2:movah,4ch
int21h
endStart
51Citeste doua siruri de la tastatura.afiseaza sirurile si numarul de aparitii a unui sir in
celalalt sir

Start:
mov ax,@data
mov ds,ax
mov es,ax
lea dx,sir1
mov cx,lungime1
mov bx,0
mov ah,3Fh
int 21h
lea dx,sir2
mov cx,lungime2
mov bx,0
mov ah,3Fh
int 21h
movcx,ax;
subcx,2;
lea dx,NewLine
movah,9
int21h
lea dx,sir1
mov ah,9
int 21h
lea dx,sir2
mov ah,9
int21h
movdi,0
movcx,0
Loopsir1:inc cx
inc di
mov si,1
mov al, sir1[di-1]
cmpal, sir2[si-1]
je Loopsir2
dec cx
cmp di,lungime1
je Loop0
jmp Loopsir1
Loopsir2:cmp di,lungime1
je Loop0
cmp si,lungime2
je Loop1
inc di
inc si
moval, sir1[di-1]
cmpal, sir2[si-1]
jeLoopsir2
jmpLoopsir1
deccx
Loop0:movax,cx
movdi,0
movcl,0Ah
Loop1:cmpal,0
jeEnd1
movah,0
divcl
addah,30h
movNumar[di],ah
incdi
jmpLoop1
End1:lea dx,NewLine
movah,9
int21h
movah,02h
Loop2:cmpdi,0
jeEnd2
decdi
movdl,Numar[di]
int21h
jmpLoop2
End2:movah,4ch
int21h
endStart
Citeste sirul si caracterul de la tastatura si afiseaza sirul si pozitia carcterului in sir
Start:
mov ax,@data
mov ds,ax
mov es,ax
lea dx,Sir1
mov cx,lungime
mov bx,0
mov ah,3Fh
int 21h
mov cx,ax;
sub cx,2;
mov ah,01h
int 21h
leadi,sir1
repne scasb
mov dx,OFFSET NewLine
mov ah,9
int21h
mov dx,OFFSET sir1
mov ah,9
int21h
mov ax,di
mov di,0
mov cl,0Ah
Loop1:cmp al,0
je End1
mov ah,0
div cl
add ah,30h
mov Numar[di],ah
inc di
jmp Loop1
End1:
lea dx,NewLine
mov ah,9
int21h
mov ah,02h
Loop2:
cmp di,0
je End2
dec di
mov dl,Numar[di]
int21h
jmp Loop2
End2:
Mov ah,4ch
int21h
endStart
Sa se scrie o macro. cu adunarea a 2 valori p 32 biti
aduna macro n1, n2, suma
push ax
push dx
mov dx, 0
mov ax, word ptr [n1]
add ax, word ptr [n2]
adc dx, word ptr [n1 + 2]
add dx, word ptr [n2 + 2]
mov word ptr [suma + 2], dx
mov word ptr [suma], ax
pop dx
pop ax
endm

start:
mov ax, @DATA
mov ds, ax
aduna nr1, nr2, s
mov ah, 4ch
int 21h
end start
eliminarea tuturor aparitiilor unui caracter dintr-un sir folosind stiva

.model small
.stack 100h
.data
sir db 0,1,2,3,2,4,5,3
lung dw $ - sir
val db 2
text db 'nu exista val cautata ',0dh,0ah,'$'
.code
assume cs : @code,ds:@data
elimina proc near
add si,bx
sub cx,bx
eli: inc si
mov al,[si]
mov [si-1],al
loop eli
ret
elimina endp
start: mov ax,@data
mov ds,ax
mov si,0
mov cx,lung
mov al,val
reia: cmp sir[si],al
jz elimin
inc si
loop reia
jmp short nu_exista
elimin: mov bx,si
mov cx,lung
mov si,offset sir
call elimina
jmp short gata
nu_exista: mov dx,offset text
mov ah,9
int 21h
gata: mov ax,4c00h
int 21h
end start
dintr-un sir extrage numere pare

.model small
.stack
.data
sir db 13,12,24
lung_sir db $-sir
sirpare db 20 dup(?)
zece dw 10
numar_zec db 5 dup(?)
.code
mov ax,@data
mov ds,ax

mov si,offset sir


mov di,offset sirpare
mov cx,word ptr lung_sir
parcurge_sir:
clc
mov al,[si]
push ax
shr al,1
jc lop
pop ax
mov [di],al
inc di
lop:
inc si
loop parcurge_sir

mov al,byte ptr parcurge_sir


cbw
mov bx,ax
call afis_nr
.exit

afis_nr proc near


mov ax,1000
xor cx,cx
bucla1:
xor dx,dx
mov cl,-1h
bucla2:
inc cl
sub bx,ax
jnc bucla2
add bx,ax
add cl,30h
push cx
mov cx,10
idiv cx
or ax,ax
jnz bucla1
mov cx,5
stocare:
pop ax
mov bx,offset numar_zec
add bx,cx
dec bx
mov byte ptr [bx],al
loop stocare

ret
afis_nr endp
caut o valoare intr-un sir si sa o inlocuiesc cu alta si sa afisez de cate ori am facut schimbarea

siruri segment
sir1 dw 00,23h,45,67h,-23,0ffh, 1234h
lung_sir dw ($-sir1)/2 ; lungimea primului sir care este = lungime sir2
sir2 dw 00,78h,45,23h,-23,0h, 1234h
rezultat dw ?
siruri ends
stiva segment stack 'stack'
dw 100h dup (?) ; rezervare de 256 octeti pentru stiva
stiva ends
compara segment
assume cs : compara ,ds :siruri ,es:siruri
start:
mov ax,siruri ; se initializeaza adresele
mov es,ax ; de segment pentru cele doua siruri
mov ds,ax
mov si,offset sir1 ; se initializeaza adresele relative
mov di,offset sir2 ; ale celeor doua siruri
mov cx, lung_sir ; se initializeza lungimea celor doua siruri
cld ; se stabileste directia de parcurgere a sirurilor
mov dx,0 ; contorul numarului de elemente egale din cele 2 siruri
reia_comp:
repne cmpsw

jcxz gata_comp
mov sir1[si],sir2[di]
inc dx
jmp reia_comp
gata_comp:
jne sfirsit inc dx
mov ax,4c00h
int 21h
compara ends
end start
sa se afle minimul dintr'un sir de valori cu semn.Sa se afiseze rezultatul in format hexazecimal.

cuv_det_minim proc
cmp cx, 0
jnz maxim
cmp cx, 1
ret
minim:
push bx
push si
lodsw
mov bx, ax
jcxz gata
caut_min:
lodsw
cmp ax,bx
jge next

mov bx, ax
next: loop caut_min
gata: mov ax, bx
cmp ax,ax
pop si
pop bx
ret
cuv_det_min endp
Sa se scrie o procedura si programul care o apeleaza in care sa se calculeze paritatea para
(suma modulo 2, sau xor)a unui tablou de cuvinte. Parametrii se transmit prin stiva, iar ;
rezultatul, trasmis tot ptin stiva, se afiseaza in hexazecimal. Definiti segmentul de date

masm
model small
.stack 100h
.data
tabel dw 4,5,0,3,9
.code

procc proc near


pop di
pop dx
mov si,0
xor ax,ax
ciclu:
mov bx,tabel[si]
adc ax,bx
aaa
cmp si,4
je ies
inc si
jmp ciclu
ies:
xor bx,bx
mov bx,2
div bx
push di
ret
procc endp

start:
mov ax,@data
mov ds,ax
;mov si,0
lea dx,tabel
push dx
xor ax,ax
call procc

exit:
mov ah,1
int 21h
mov ax,4C00h
int 21h
end start
Sa se scrie un program care calculeaza suma elementelor unui vector de tip octet. Sa se trateze cazul in care
apare depasire si sa se afiseze rezultatul in hexazecimal. Definiti segmentul de date.

model small
.stack 100h
.data
vec db 2,45,0ffh,30,77,0dch,0ffh
lung dw ($-vec)
mes db "S-a facut depasire !!!$"
nr dw 16
tabela db "0123456789ABCDEF"
.code

start:
mov ax,@data
mov ds,ax
mov si,0
xor ax,ax
repeta:
cmp si,lung
je afisare
xor dx,dx
mov dl,vec[si]
clc
adc ax,dx
jb mesaj
inc si
jmp repeta

afisare:
xor dx,dx
mov di,sp
do:
cmp ax,0
je pas1
div nr
push dx
xor dx,dx
jmp do
pas1:
lea bx,tabela
repeta2:
cmp di,sp
je exit
pop ax
xlat
mov dl,al
mov ah,02h
int 21h
jmp repeta2
mesaj:
xor dx,dx
lea dx,mes
mov ah,09h
int 21h
jmp exit
exit:
mov ah,4ch
int 21h
end start
interschimbare de biti

.model small
.data
maskp db 10101010b ; o masca pt pozitii pare
maski db 01010101b ; si o masca pt pozitii impare
; mastile folosesc pentru a extrage prin and
; bitii de pe pozitii pare si impare ca mai
; apoi sa ii schimb intre ei
nr db 170; pt test: 170 trece in 85
.code
start:
mov ax, @data
mov ds, ax

mov dl,nr ;tin doua copii ale lui nr


mov dh,nr ;in dl si dh
and dl,maskp ;aplic prima masca pe dl
and dh,maski ;si a doua masca pe cealalta copie
shr dl,1 ;pozitiile pare le mut in dreapta
shl dh,1 ;si pozitiile impare le mut in stanga
or dl,dh ;le suprapun si gata, aveti deja valoarea in al si
; daca vreti, puneti un mov ah,02h si la int 21h
; va afisa U, care e caracterul pt codul 85. atat.

mov ax, 4c00h


int 21h
end start

1
; pla73a.asm - programul complementeaza fata de 2 o variabila din memorie
.model small
.data
variab dw 00A0Ah, 0FACh, 7ABCh
dim_var equ ($ - variab)/2
.stack 100h

.code
compl2 proc near
;intrari: (SI) - adresa numarului (de tip cuvant) de complementat
; (CX) - dimensiune numar
;iesire: complementul se va fi peste numarul initial, iar (SI), (CX) - nemodificate
; daca se complementeaza valoarea minima negativa (8000 0000 ... 0000 H),
; rezultatul va acelasi, deci pentru a detecta aceasta situatie trebuie
; comparat numarul cu complementul obtinut
push si
push cx
clc ; initializare transport cu 0
compl: mov ax, 0 ; echivalentul lui 2^n
sbb ax, [si] ; se efectueaza scaderea, cu propagarea imprumutului
mov [si], ax ; se depune rezultatul
inc si ; actualizare index cuvant urmator
inc si
loop compl
pop cx
pop si
ret
compl2 endp

start:
mov ax, @data
mov ds, ax
lea si, variab
mov cx, dim_var
call compl2
mov ax, 4C00h
int 21h
end start
; pla74.asm - programul determina numarul de biti 1 dintr-o variabila
.model small
.stack 100h
.data
lung_var equ 8
variabila dw lung_var dup (0acfh)
nr_unitati db ?
.code
assume cs: @code, ds: @data
start: mov ax, @data
mov ds, ax
mov si, 0 ; indexul curent al cuvintelor din variabila
mov dl, lung_var ; contor numãr de cuvinte
mov bl, 0 ; contor numãr de unitãþi gãsite
bucla2:
mov cx, 16 ; contorul de biþi pentru un cuvânt
mov ax, variabila[si] ; se citeºte cuvântul curent
bucla1:
rcl ax, 1 ; o rotaþie pentru a deplasa un bit
adc bl, 0 ; se contorizeazã numãrul de unitãþi
loop bucla1 ; pentru un cuvânt
add si, type variabila ; se actualizeazã indexul
dec dl ; se testeazã dacã mai sunt cuvinte
jnz bucla2 ; dacã da se reia citirea cuvintelor
mov nr_unitati, bl ; dacã nu se depune rezultatul
mov ax, 4C00h ; revenire DOS
int 21h
end
.286
.model SMALL
.DATA
cr = 13
lf = 10
buf db 100,102 dup(?)
mesaj1 db "introduceti sir:$"
mesaj2 db cr,lf,"$"
mesaj3 db "sirul obtinut:$"
.STACK 64
.CODE
START:

mov ax,@data ;initializare segment date


mov ds,ax

mov dx,offset mesaj1 ;scrie mesaj1


mov ah,09h
int 21h

mov dx,offset mesaj2 ;scrie mesaj2


mov ah,09h
int 21h

mov dx,offset buf ;citeste sirul de char


mov ah,0ah
int 21h

mov cl,buf[1] ;lungimea sirului citit


xor ch,ch
xor si,si ;initializare si <-0 indicele de deplasare prin sir
dec si

modify:
inc si
cmp si,cx
jae gata ;daca s-a ajuns la sfarsitul sirului
mov al,buf[si + 2] ;sirul incepe de la pozitia 2 in buffer
xor ah,ah
cmp ax,65 ;caracterul ascii mai mic decat 65 ("A")
jb modify
cmp ax,90 ;mai mare decat 90 ("Z")
jbe modify1
cmp ax,122
ja modify
cmp ax,97
jae modify2

modify1:
add buf[si + 2],32
jmp modify
modify2:
sub buf[si + 2],32
jmp modify

gata:
mov si,cx
mov buf[si + 2],byte ptr '$'

lea dx,buf[2]
mov ah,09h
int 21h

mov ah,4ch
int 21h
END START
Interschimbarea a două locaţii succesive sau aleatoare de memorie

.model small
.code
start: mov ax,3000h
mov ds,ax
mov si,200h
mov al,[si]
inc si
xchg al,[si]
dec si
mov [si],al
mov ax,4c00h
int 21h
end start
end
Adunarea a două locaţii succesive sau aleatoare de memorie

.model small
.code
prog segment word public 'code'
assume cs:prog, ds:date
start: mov ax,3000h
mov ds,ax
mov si,200h
mov ax,[si]
add si,2
add ax,[si]
jc afis_mesaj
add si,2
mov [si],ax
rev_DOS:
mov ax,4c00h
int 21
afis_mesaj:
lea dx,mes_err
mov ah,9
int 21h
jmp rev_DOS
prog ends
.data
date segment
mes_err db 'eroare:depasire dimensiune cuvant a rezultatului'
date ends
end start
end
Se adună n cuvinte începând de la adresa 3000:200, cu rezultat de lungime tot
cuvânt (16 biţi), fără detectarea depăşirii.

.model small

.code
prog segment word public 'code'
assume cs:prog, ds:date
start: mov ax,date
mov ds,ax
lea si,sir
mov ax,0
mov cx,lung_sir
reia_add:
add ax,[si]
add si,2
loop reia_add
mov rezultat,ax
rev_DOS:
mov ax,4c00h
int 21
afis_mesaj:
mov ah,9
int 21
jmp rev_Dos

prog ends

.data
date segment
sir dw 0f54h,20000,0ff56h,8000
lung_sir equ ($-sir)/2
rezultat dw 2 dup(?)
date ends
end start
Afişarea codurilor ASCII ale tastelor (din curs), precum şi a codurilor de scanare,
utilizând funcţia 0, a întreruperii specifice tastaturii, int 16h, care returnează în
(AH, AL) codul de scanare şi codul ASCII (sau 0, dacă este o tastă specială-
funcţională, de deplasare, 'CTRL', 'insert', 'delete' etc.).
.model small
.data
tabela db '0123456789ABCDEF'
string db 'Codul de scanare: Codul ASCII: $'
.code
start:
mov ax, @data
mov ds, ax
mov ax, 0h
int 16h
mov cl, al
and al, 0fh
xlat [string] ;transfer din tabla de octeti
mov string[33], al
mov al, cl
shr al, 4
xlat [string]
mov string[32], al
mov al, ah
and al, 0fh
xlat [string]
mov string[18], al
mov al, ah
shr al, 4
xlat [string]
mov string[17], al
lea dx, string
mov ah, 9h
int 21h
mov ax, 4c00h
int 21h
.stack 10
end start
Exemple de iniţializare a registrelor generale (BX, SI şi DI) şi a celor segment,
utilizând instrucţiuni de transfer adrese.
.model small
.data
sir dw 20 dup (?)
adr_sir dd sir
adr_w dw 0123h, 4567h
ptr_1 dd 76543210h
.code
start:
mov ax, @data
mov ds, ax
lea bx, sir ;bx = offset sir
lds si, adr_sir ;ds = segment sir, si = offset sir
les di, dword ptr adr_w ;es = 4567h, di = 0123h
lds si, ptr_1 ;ds = 7654h, si = 3210h
mov ax, 4c00h
int 21h
Modificaţi programul pentru afişarea în zecimal a valorii din AX fără semn, pentru
a o afişa cu semn, şi apoi extindeţi programul pentru a afişa valoarea fără
zerourile nesemnificative.
.model small
.data
numar dw 0800h
.code
start:
mov ax, @data
mov ds, ax
mov ax, [numar]
cmp ax, 0
mov bx, ax
jns pozitiv
mov dl, '-'
mov ah, 2h
int 21h
neg bx
pozitiv:
mov ax, bx
mov cx, 100
mov dx, 0
div cx
push dx
mov dx, 0
div cx
push dx
mov dx, ax
cmp dl, 0
jz e0_1
add dl, 30h
mov ah, 2h
int 21h
pop ax
aam
mov dx, ax
jmp nue0_1
e0_1:
pop ax
aam
mov dx, ax
cmp dh, 0
jz e0_2
nue0_1:
xchg dh, dl
add dl, 30h
mov ah, 2h
int 21h
xchg dh, dl
jmp nue0_2
e0_2:
cmp dl, 0
jz e0_3
nue0_2:
add dl, 30h
mov ah, 2h
int 21h
pop ax
aam
mov dx, ax
jmp nue0_3
e0_3:
pop ax
aam
mov dx, ax
cmp dh, 0
jz e0_4
nue0_3:
xchg dh, dl
add dl, 30h
mov ah, 2h
int 21h
xchg dh, dl
e0_4:
add dl, 30h
mov ah, 2h
int 21h
mov ax, 4c00h
int 21h
.stack 10
end start
lab7p5b.asm
.model small
.data
numar dw 0ffffh
.code
start:
mov ax, @data
mov ds, ax
mov ax, [numar]
mov cx, 100
mov dx, 0
div cx
push dx
mov dx, 0
div cx
push dx
mov dx, ax
cmp dl, 0
jz e0_1
add dl, 30h
mov ah, 2h
int 21h
pop ax
aam
mov dx, ax
jmp nue0_1
e0_1:
pop ax
aam
mov dx, ax
cmp dh, 0
jz e0_2
nue0_1:
xchg dh, dl
add dl, 30h
mov ah, 2h
int 21h
xchg dh, dl
jmp nue0_2
e0_2:
cmp dl, 0
jz e0_3
nue0_2:
add dl, 30h
mov ah, 2h
int 21h
pop ax
aam
mov dx, ax
jmp nue0_3
e0_3:
pop ax
aam
mov dx, ax
cmp dh, 0
jz e0_4
nue0_3:
xchg dh, dl
add dl, 30h
mov ah, 2h
int 21h
xchg dh, dl
e0_4:
add dl, 30h
mov ah, 2h
int 21h
mov ax, 4c00h
int 21h
.stack 10
end start
Afişarea în octal a conţinutului perechii de registre DX:AX.
.model small
.stack 20h
.data
variabila dd 0f1234567h
.code
tip_octal proc
push ax
push bx
push cx
push dx
push si
mov bx, dx
mov si, ax
shr dx, 14
add dl, 30h
mov ah, 2h
int 21h
shl si, 1
rcl bx, 1
rol bx, 1
mov cx, 5
prim:
rol bx, 3
mov dl, bl
and dl, 07h
add dl, 30h
int 21h
loop prim
mov cx, 5
mov bx, si
doi:
rol bx, 3
mov dl, bl
and dl, 07h
add dl, 30h
int 21h
loop doi
pop si
pop dx
pop cx
pop bx
pop ax
ret
tip_octal endp
start:
mov ax, @data
mov ds, ax
mov ax, word ptr [variabila]
mov dx, word ptr [variabila+2]
call tip_octal
mov ax, 4c00h
int 21h
end start
Afişarea în binar a conţinutului registrului BX.
.model small
.data
continut dw 0f834h
.code
start:
mov ax, @data
mov ds, ax
mov bx, [continut]
mov cx, 16
mov ah, 2h
bucla:
shl bx, 1
mov dl, '0'
jnc ezero
mov dl, '1'
ezero:
int 21h
loop bucla
mov ax, 4c00h
int 21h
end start
Determinarea numărului de perechi de valori egale din două şiruri.
.model small
.data
sir1 dw 04235h,0fab3h,03ad3h,05434h
lung1 equ ($-sir1)/type sir1
sir2 dw 04235h,03754h,03ad3h
lung2 equ ($-sir2)/type sir2
.code
assume ds:_data, es:_data
start:
mov cx, lung1
cmp cx, lung2
jle ok
mov cx, lung2
ok:
mov ax, @data
mov ds, ax
mov es, ax
lea si, sir1
lea di, sir2
mov ax, 0
bucla:
cmps sir1, sir2
jnz diferite
inc ax
diferite:
loop bucla
mov ax, 4c00h
int 21h
end start
Determinarea primei şi ultimei apariţii a unei anumite valori într-un şir. Este vorba
de indexul din şir, care eventual poate fi tipărit în octal utilizând programul 2.
Dacă nu este găsită de loc se va tipări un mesaj corespunzător.
.model small
.stack 100h
.data
mesaj db 'Valoarea nu exista$'
sf_linie db 0dh,0ah,'$'
sir dw 04235h,0fab3h,03ad3h,05434h,04235h,03754h,03ad3h
lung equ ($-sir)/type sir
valoare dw 04235h
.code
tip_octal proc
push ax
push bx
push cx
push dx
shl ax, 1
mov bx, ax
rcl dx, 1
and dl, 01h
add dl, 30h
mov ah, 2h
int 21h
mov cx, 5
bucla:
rol bx, 3
mov dl, bl
and dl, 07h
add dl, 30h
int 21h
loop bucla
pop dx
pop cx
pop bx
pop ax
ret
tip_octal endp
start:
mov ax, @data
mov ds, ax
mov es, ax
mov ax, valoare
mov cx, lung
lea di, sir
mov si, di
cld
repnz scasw
cmp cx, 0
jz nuexista
sub di, si
shr di, 1
dec di
mov ax, di
call tip_octal
mov ah, 9h
lea dx, sf_linie
int 21h
mov ax, valoare
mov cx, lung
lea di, sir[(lung-1)*type sir]
lea si, sir
std
repnz scasw
add di, type sir
sub di, si
shr di, 1
mov ax, di
call tip_octal
mov ax, 4c00h
int 21h
nuexista:
lea dx, mesaj
mov ah, 9h
int 21h
mov ax, 4c00h
int 21h
end start
Definiţi proceduri şi programele ce le apelează, pentru inserarea/ eliminarea unui
subşir dintr-un şir dat (transferul parametrilor la proceduri se face prin registre).
.model small
.data
sir db 'alabalaportocala$', 50 dup(?)
lung_sir equ ($-sir)-50
subsir db 'lamaia'
lung_subsir equ ($-subsir)
sf_linie db 0dh,0ah,'$'
.code
insereaza proc ;di adresa destinatiei, si adresa sursei
add di, dx ;ax pozitia in destinatie
push cx ;dx lungimea dest, cx lungimea sursei
push si
dec di
mov si, di
add di, cx
mov cx, dx
sub cx, ax
std
rep movsb
pop si
pop cx
cld
inc di
sub di, cx
rep movsb
ret
insereaza endp
start:
mov ax, @data
mov ds, ax
mov es, ax
mov ah, 9h
lea dx, sir
int 21h
lea dx, sf_linie
int 21h
lea di, sir
lea si, subsir
mov ax, 7
mov dx, lung_sir
mov cx, lung_subsir
call insereaza
lea dx, sir
mov ah, 9h
int 21h
mov ax, 4c00h
int 21h
.stack 100h
end start

You might also like