Professional Documents
Culture Documents
Assembly Problems PDF
Assembly Problems PDF
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
push bx
push cx
aad
mov cx, ax
mov ax, dx
aad
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)
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)
public divzn16
; (DX:AX) = deimpartit, (BX) = divizor
; (AX) = cat, (DX) = rest
; daca catul sau restul > 99 => CF = 1, altfel CF = 0
cmp cl, 0
je gata
push cx
sub ch, ch
rcr ax, 1
loop shift
pop cx
gata: ret
sar32 endp
Rotire la stanga (dreapta) pt valori de 32 biti, fara ‘carry’ (rol32/ror32)
;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
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
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
Inserarea unui sir într-un alt sir
prog ends
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
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
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
.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
prog ends
stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start
. Stergerea unui octet (cuvant) dintr-un sir ordonat crescator
.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
.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.
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 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
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
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 :
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
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
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
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:
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