10 septembrie 2010

Adunarea a *n* cuvinte

; 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

Afisare in binar continutul reg. BX

; Afisarea în binar a continutului 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 ; shift left 1 pozitie in BX

mov dl, '0'

jnc ezero

mov dl, '1'

ezero:

int 21h

loop bucla

mov ax, 4c00h

int 21h


end start

Registrele

Concatenarea a doua siruri (asm)

date segment word public 'data'
sir1 db 'Primul sir '
lung1 equ $-sir1
sir2 db 'cel de-al doilea sir'
lung2 equ $-sir2
loc_sir2 db 13,10,'$'
mesaj db 13,10,'Sirurile concatenate sunt ',13,10,'$'
date ends

prog segment word public 'code'
assume cs:prog, ds:date
start:
mov ax,date
mov ds,ax
lea dx, sir1
mov ah, 9 ; tiparire primul sir
int 21h
lea dx, sir2
mov ah,9 ; tiparire al doilea sir
int 21h
lea di, sir1 ; incepe proc de concatenare, initializare date
mov bx, lung1 ; sir1 intra in DI (destinatie), sir2 intra in SI (sursa)
lea si, sir2
mov cx, lung2
push ds
pop es ; es = ds
call concat
jz gata ; ZF = 1, terminare cu insucces
lea dx, mesaj ; altfel tiparire rezultat
mov ah, 9
int 21h
lea dx, sir1 ; tiparire sir1 care contine concatenare
mov ah, 9
int 21h
gata:
mov ax, 4c00h
int 21h ; terminare prog
; procedura de concatenare
; intrari: sir1 : (DI, BX)
; sir2 : (SI, CX)
; iesiri: succes: ZF = 0, SI = noul offset pt sir2, BX = lungime totala dupa concat
; insucces: ZF = 1, fie un sir este vid, fie deja a avut loc concatenarea
dim2 dw ?
off1 dw ?
concat proc near
jcxz iesire ; unul din siruri e vid => terminare
cmp bx, 0
je iesire

mov dim2, cx ; salvare dimensiune sir2
mov off1, di ; salvare offset sir1
add di, bx ; de unde va incepe al doilea
cmp si,di ; compara sa vada daca al doilea sir se afla deja aici
je gata ; daca da, se termina
conc:
cld ; curata flagul pt address
rep movsb ; muta din SI in DI, in mod repetat
sub di, dim2 ; adresa de inceput al celui de-al doilea sir
mov si, di ; se returneaza in SI
add bx, dim2 ; lungimea sirului total
gata:
mov di, off1
mov cx, dim2
iesire:
ret
concat endp
prog ends

stiva segment stack 'stack'
dw 100 dup(?)
stiva ends
end start

Aflare maxim dintr-un sir (asm)

; aflare maxim dintr-un sir / sau minim

date segment word public 'data'
sir dw 16, 41, 40, 3 ; sau val lor in hexa
lung equ $-sir
max dw ?
mesaj db 13,10,'sir vid de valori - nu exista maxim',13,10,'$'
date ends

prog segment word public 'code'
assume cs:prog, ds:date
start:
mov ax, date
mov ds, ax
lea si,sir ; aduce offsetul sirului
mov cx, lung
call afla_max
jz depune_max ; daca ZF = 1, terminare cu succes
lea dx, mesaj ; in caz contrar
mov ah, 9 ; afisare mesaj
int 21h
jmp gata
depune_max:
mov max, ax ; maximul va fi initial in ax
gata:
mov ax, 4c00h
int 21h ; terminare
; intrari: SI, CX = offset si lungime sir in care se cauta
; iesiri: ZF = 1 daca s-a aflat max, returnat in AX
; ZF = 0, sir vid
afla_max:
cmp cx, 0 ; test sir vid
jnz maxim ; nu e vid, se determina maximul
; in caz contrar
cmp cx, 1 ; ZF devine 0, sir vid , se termina
ret
maxim:
push bx
push si
lodsw ; preia prima val. din sir, intra in AX, implicit CX = CX - 1
mov bx, ax ; init maxim temporar, care va fi in BX
jcxz gata ; daca CX == 0, a fost o singura val si deci e maxim
caut_maxim:
lodsw ; urmatoarea val din sir, intra in AX
cmp ax, bx ; compar cu maximul temporar aflat in BX
; daca aveam de gasit minimul, scriem jae in loc de jbe
jbe next ; daca AX mai mic sau egal cu BX (maximul temporar) trec la next
mov bx, ax ; altfel se actualizeaza noul maxim temporar
next: loop caut_maxim
gata:
mov ax, bx ; maximul temporar se pune in AX
cmp ax, ax ; ZF = 1
; refacere registri
pop si
pop bx
afla_max endp
prog ends

stiva segment stack 'stack'
dw 100 dup(?)
stiva ends

end start

Cautare subsir intr-un sir (asm)

date segment word public 'data'
sir1 db 'superextraconopidaexpiralidolces'
lung1 equ $-sir1 ; afla lungimea primului
CRLF equ 13,10,'$' ; linie noua
sir2 db 'conopida'
lung2 equ $-sir2
mesaj1 db 13,10,'Subsirul gasit in primul sir este ',13,10,'$'
mesaj2 db 13,10,'Subsirul nu a fost gasit!',13,10,'$'
date ends

prog segment word public 'code'
assume cs:prog, ds:date
start:
mov ax, date
mov ds, ax
; tiparire sir in care se cauta
lea dx, sir1
mov ah,9
int 21h
;tiparire subsir cautat
lea dx, sir2
mov ah,9
int 21h
; init date pt procedura de cautare a subsirului
; bx = lung1, di= sir1, cx = lung2, si = sir2
lea di, sir1
mov bx, lung1
lea si, sir2
mov cx, lung2
push ds
pop es ; ca es = ds
call cauta_subsir
; daca ZF = 1, nu a gasit
jnz afisare_subsir
lea dx, mesaj2
mov ah,9
int 21h
jmp gata
afisare_subsir:
push dx
lea dx, mesaj1
mov ah,9
int 21h
pop bx
gata:
mov ax, 4c00h
int 21h
tiparire_subsir: ; gasit
mov dl, [bx]
mov ah,2
int 21h
inc bx
loop tiparire_subsir
lea dx, CRLF
mov ah,9
int 21h
; programul propriu zis
; intrari: se cauta in (DI = offset, BX = lungime sir)
; se cauta sirul (SI, CX)
; iesiri: subsir gasit: ZF = 0, DX = offsetul sirului gasit
; subsir negasit: ZF = 1, DX = offset de inceput pt ultima cautare /sau DX = 0 daca subsir > sir
stop dw ? ; locatie oprire cautare
aici dw ? ; locatie inceput cautare
salv_si dw ?
salv_cx dw ?
cautSub proc
jcxz gata ; daca cx = 0, subsir vid
cmp bx,0
je gata ; daca bx = 0, sir vid
cmp cx, bx
jc caut ; daca cx mai mic decat bx, lungime subsir mai mica decat lungime sir
je caut ; la fel daca lungimile sunt egale
; altfel:
sub dx, dx ; facem DX = 0, ZF = 1
je gata
caut:
push bx
push di ; offsetul de unde incepe sirul
mov salv_si, si
mov salv_cx, cx ; salvez pt subsir
add bx, di ; locatia de terminare a cautarii in sir
sub bx, cx
inc bx ; locatia de inceput a ultimei cautari
mov stop, bx ; salvata la adresa stop
mov aici, di
cld
cautare:
repe cmpsb ; repeta cautarea cat timp sunt egale
je gasit ; daca ZF = 1 s-a gasit subsirul
inc aici ; altfel nu s-a gasit, se continua cu urm.locatie
mov di, aici
cmp di, stop ; s-a ajuns la sfarsit?
je ref_reg ; refacere registri
mov cx, salv_cx
mov si, salv_si
jmp cautare
gasit:
or cx, 1 ; s-a gasit, se pune ZF = 0
ref_reg:
mov dx, aici
pop di
pop bx
mov cx, salv_cx
mov si, salv_si
gata:
tip_sub
ret
cautaSub endp
prog ends

stiva segment stack 'stack'
dw 100 dup(?)
stiva ends

end start

Inmultirea a doua numere fara semn pe 32 biti, cu rezultat pe 64 biti

; inmultirea a 2 nr fara semn, pe 32 biti, cu rez. pe 64 biti
; algoritm
; (DX, AX)*
; (CX, BX) =
; (BX * AX) +
; (BX * DX) +
; (CX * AX) +
; (CX * DX) =
; (DX, CX, BX, AX)

dseg segment para public 'data'
deinmultit dd 123h
inmultitor dd 456h
produs dq ?
dseg ends

cseg segment para public 'code'
assume cs:scseg, ds:dseg
start:
mov ax, dseg
mov ds, ax
;creez registri in fct de deinmultit si inmultitor
mov dx, word ptr deinmultit[2]
mov ax, word ptr deinmultit
mov bx, word ptr inmultitor
mov cx, word ptr inmultitor[2]
call procedura
;refacere rezultat
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
public procedura
procedura proc
push dx
push ax
push dx
; (DX, AX) = AX * BX
mul bx
mov word ptr rezultat[0],ax
mov word ptr rezultat[2],dx
; (DX, AX) = BX * DX
pop ax ; ax = dx
mul bx
add word ptr rezultat[2], ax
adc word ptr rezultat[4], dx ; cu eventual transport
; (DX, AX) = CX * AX
pop ax ; ax = ax dinainte
mul cx
add word ptr rezultat[2], ax
adc word ptr rezultat[4], dx ; cu eventual transport
; (DX, AX) = CX * DX
pop ax ; ax = dx
mul cx
add word ptr rezultat[4], ax
adc word ptr rezultat[6], dx
; refacere registri
mov ax, word ptr rezultat[0]
mov bx, word ptr rezultat[2]
mov cx, word ptr rezultat[4]
mov dx, word ptr rezultat[6]
procedura ends
cseg ends

sseg segment para stack 'stack'
dw 128 dup(?)
sseg ends

end start