10 septembrie 2010

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

Niciun comentariu: