; 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
medie prog stiva stiva end start
add sp, 4; descarcare stiva/ refacere registre ret endp ends segment stack 'stack' dw 100 dup(?) ends
; 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 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 op eranzilor 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 r egistrului (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 pentr u (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 cel mai semnificativ se depune la cat[6] cat[6] mov ax, word ptr deimpartit[4] div divizor ; continua impartirea: (DX=rest anterior,AX=cifra urmatoare) mov word ptr cat[4], cat[4], ax ; si se depune urmatorul cat, 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 op1 op2 rezult date prog
segment word public 'data' dw 0808h ; numarul zecimal 88 dw 0507h ; numarul zecimal 57 dw 2 dup (0) ; rezultatul va fi: 5016 ends segment word public 'code' assume cs: prog, ds: 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 stiva stiva end start
ends segment stack dw 100 dup(?) ends
'stack'
; pla61c.asm - impartirea a doua numere zecimal neimpachetate, de cate doua cifre (16 biti) date deimp imp cat rest mes_err date prog
segment word public 'data' dd 01090500h ; numarul zecimal 1950 (deimpartitul) dw 0809h ; se imparte la numarul zecimal 89 (impartitorul) dw ? ; rezultatul va fi: 21-cat, 81-rest dw ? db 'EROARE la impartire - depasire format', 0Ah, 0Dh, '$' ends 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 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
; salvare registre afectate ; conversie zecimal neimpachetat -> binar (zeci, unitati) ; salvare rezultat (zeci + unitati) ; conversie zecimal neimpachtat -> binar (mii, sute) ; deimpartit maxim = 9999 ; se actualizeaza valoarea pentru cifrele mii, sute ; deimpartitul este in binar (CX) ; conversia divizorului ; divizorul < 99 ; deimpartitul binar este in (AX) ; impartirea propriu-zisa (AH-restul, Al-catul) ; este catul > 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 prog ends stiva segment stack dw 100 dup(?) stiva ends end start
; sau restul > 99
; daca nu, salvez catul in (BL) ; conversie rest la formatul neimpachetat (ASCII) ; se depune restul zecimal neimpachtat in (DX) ; conversie cat la formatul ASCII (neimpachetat) ; iesire normala, CF=0 ; refacerea registrelor
'stack'
Conversie din binar (16 biti) in zecimal neimpachetat/impachetat (binzn/binbcd)
binzn
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 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 va lori de 32 biti, fara ‘carry’ (rol32/ror32) rol32
rotire:
gata: rol32 ror32
rotire:
proc near cmp cl, 0 je gata push cx sub ch, ch sal dx, 1 pushf rcl ax, 1 adc dx, 0 popf loop rotire pop cx ret endp proc near cmp cl, 0 je gata push cx sub ch, ch shr ax, 1 pushf rcr dx, 1 jnc refa_cf or ax, 8000h
refa_cf:
gata: ror32
popf loop rotire pop cx ret endp
. Rotire la stanga(dreapta) pt valori de 32 biti, cu ‘carry’ (rol32/ror32) rcl32
cont:
rot:
rcl32 rcr32
cont:
rot:
rcr32
proc near pushf cmp cl, 0 jne cont popf ret popf push cx mov ch, 0 rcl ax, 1 rcl dx, 1 loop rot pop cx ret endp proc near pushf cmp cl, 0 jne cont popf ret popf push cx mov ch, 0 rcr dx, 1 rcr ax, 1 loop rot pop cx ret 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 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 off1 concat
dw ? dw ? proc near jcxz iesire
; salvare dimensiune initiala cel de-al doilea sir (CX) ; salvare offset initial primul sir (DI) ; daca unul din siruri este vid se termina procedura
cmp bx, 0 je iesire mov dim2, cx mov off1, di add di, bx cmp si, di je gata conc: cld rep movsb sub di, dim2 mov si, di add bx, dim2 gata: mov di, off1 mov cx, dim2 iesire: ret concat endp prog ends stiva segment stack dw 100 dup(?) stiva ends end start
; salvare dimensiune sir 2 ; salvare offset sir 1 ; adresa de concatenare a celui de-al doilea sir ; test daca cel de-al doilea sir se afla deja aici ; adrese diferite -> nu este -> se concateneaza ; concatenarea celui de-al doilea sir ; adresa de inceput a sirului concatenat ; se returneaza in (SI) ; actualizarea adresei celui de-al doilea sir ; refacerea registrelor modificate
'stack'
; 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 offset sir in care care se cauta, (BX) = lungime sir sir ; (SI) = offset subsir cautat, (CX) = lungime subsir ;iesiri: (ZF) = 0, subsir 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 aici salv_si salv_cx cautsub
caut:
dw ? ; locatie oprire cautare dw ? ; locatia curenta de cautare dw ? ; salvare (SI) initial dw ? ; salvare (CX) initial 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 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 s-a gasit, se continua cautarea cautarea cu urmatoarea 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 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 stiva stiva end start
ends segment stack dw 100 dup(?) ends
'stack'
; 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 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
gatap:
inc di loop tip_sir lea dx, CRLF mov ah, 9 int 21h mov ax,4C00h int 21h
;intrari: (DI) = offset, (BX) = lungime sir ; (SI) = offset, (CX) = lungime subsir ;iesiri: (ZF) = 0 operatie efectuata, efectuata, (BX) = lungimea lungimea curenta 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 ? sterge_sub proc jcxz gata cmp bx, 0 je gata cmp cx, bx ja pune_zf cmp si, di jb pune_zf mov sf_sir, di add sf_sir, bx cmp si, sf_sir jb sterge pune_zf: cmp cx, cx jmp gata sterge:
; offset sfarsit sir + 1 ; subsir vid ; sir vid ; se compara cele doua dimensiuni ( subsir / sir ) ; subsirul este mai mare decat sirul ; este subsirul in afara limitelor sirului ; daca da se termina proc. si seteaza (ZF) ; salvarea offsetului sirului ; s-a determinat adresa de sfarsit + 1, a sirului ; depaseste subsirul limita sirului ? ; daca nu se efecueaza stergerea ; (ZF) = 1 ; eliminarea subsirului se face prin mutarea, din sirul dat, ; subsirul de la adresa (SI) + (CX) la adresa (SI) ; salvarea registrelor de lucru
push di 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 gata: ret sterge_sub endp
prog stiva stiva end start
ends segment stack dw 100 dup(?) ends
; actualizare lungime sir, dupa stergerea subsirului, (ZF)=0
'stack'
Inserarea unui sir într-un alt sir
;intrari: (DI)=offset, (BX)=lungime sir, in care 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 ? dim2 dw ? insert_sir proc jcxz gata cmp bx, 0 je gata mov dim2, cx mov off1, di add di, bx cmp si, di ja insert push si add si,cx cmp si, off1 pop si jbe insert sub di, di jz iesire insert: std push si dec di mov si,di add di,cx rep movsb cld pop si mov cx, dim2 mov di, bp rep movsb mov si,bp add bx, dim2 iesire: mov di,off1 mov cx,dim2 gata: ret insert_sir endp
;spatiu intre offset sir si ;dimensiune subsir de inserat ;sirul de inserat este vid ;sirul in care se insereaza este vid
;offsetul de sfarsit (+1) al primului sir ;este al 2-;ea sir deja inserat? (adr. Inceput sir1 > sf. Sir2) ;nu, se face inserarea ;offsetul de sfarsit (+1) al celui de-al 2 lea sir ;se testeaza daca adresa de inceput a sirului 2 este in primul ;daca nu, se face inserarea ;daca da, nu se mai insereaza si (ZF) =1
;directie de parcurgere este de la sfarsit la inceput, pt ;a nu se scrie peste urmatorii octeti ;initializare adrese pentru a crea spatiu pt sirul inserat ;adresa de sfarsit a subsirului transferat ;transfera restul din primul sir la sfarsit ;se va insera sirul de la inceputul zonei eliberate ;refacerea adresei de inceput a sirului de inserat ;contor numar de octeti transferati ;offsetul destinatie al transferului ;inserarea propriu-zisa ;noul offset al sirului inserat ;actualizare lungime sir 1 ;refacere (DI) ;si (CX)
; 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 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
gatap:
mov ah, 9 int 21h mov ax,4C00h int 21h
;intrari: (DI) = offset, offset, (BX) = lungime 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 dw 100 dup(?) ends
stiva end start
'stack'
; 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 s-a determinat maximul maximul (minimul), returnat in (AX) ; (ZF) = 0, sir vid cuv_det_maxim proc cmp cx, 0 jnz maxim cmp cx, 1 ret maxim: push bx push si lodsw mov bx, ax jcxz gata caut_max: lodsw cmp ax, bx jbe next
next: gata:
mov bx, ax loop caut_max mov ax, bx cmp ax, ax pop si
; sir vid ? ; nu, se determina maximul ; (ZF) = 0, sir vid, se termina procedura
; prima valoare din sir ; initializeaza maximul din sir ; s-a terminat sirul (a avut o singura valoare) ; citeste urmatoarea valoare din sir ; compar cu maximul {pentru minim in loc de 'jbe'->'jae'} ; daca este <= maxim se trece la urmatorul (pentru valorile ; cu semn atunci in loc de 'jbe' se pune 'jle' {minim 'jge'}) ; daca este > se inlocuieste maximul anterior cu cel nou gasit ; se continua pana (CX) = 0 ; returnez maximul in (AX) ; (ZF) = 1 semnaleaza ca procedura returneaza maximul
pop bx ret cuv_det_maxim endp prog ends stiva stiva end start
segment stack dw 100 dup(?) ends
'stack'
; 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 mov [si], ax inc cx pop si ret cuv_adaug_sir endp prog ends stiva stiva end start
segment stack dw 100 dup(?) ends
; adresa unde trebuie adaugat cuvantul ; actualizare contor sir
'stack'
Stergerea unui octet dintr-un sir, de octeti, neordonat
;intrari ;iesiri
oct_sterg proc push cx add cx, si cmp di, cx jae afara cmp di,si jae sterg afara: stc pop cx ret push si sub cx,di dec cx mov si, di inc si cld rep movsb pop cx dec cx pop si ret oct_sterg endp
(SI), (CX) = offsetul si lungimea sirului in care se cauta (SI) = offsetul elementului de sters (CF) = 1, nu s-a sters val -> (SI)=offsetul ei in afara sirului (sau sir vid) (CF) = 0, (CX) <- (CX) – 1
;adresa ultimului element din sir (+1) ;compar offset elem de sters cu ultimul din sir ;daca este in afara sirului se termina proc ;compar cu primul element din sir ;este dupa primul, deci se poate sterge ;nu este in sir si deci se term proc ;stergerea se face prin deplasarea elementelor urmatoare celui ;de sters cu o pozitie la stanga
sterg:
;se determina nr de elemente de deplasat ;sursa este dest +1
;deplasarea sirului cu un octet, peste cel de sters ;actualizare contor sir
Ordonarea crescatoare a unui sir de cuvinte (octeti) -folosind metoda bulelor (inversiunilor)
;intrari
inv dw ? ord_bule proc jcxz revin cmp cx,1 jz revin push cx dec cx cld reia_ord: push si push cx mov inv, 0 cont_ord: lodsw cmp ax, [si] jbe next xchg ax,[si] mov [si-2],ax mov inv,1 next: loop cont_ord pop cx pop si cmp inv,1 jz reia_ord pop cx revin: ret ord_bule endp
(SI),(CX) = offsetul si lungimea sirului de ordonat Se considera cuvintele fara semn ;se memoreaza daca au avut loc inversiui
;daca sirul are un singur element se termina procedur ;intrucat nu avem ce ordona ;nr de comparatii este = lungime_sir – 1 ;diretie de parcurgere ;salvare adresa de inceput a sirului si ;contorul (nr) de comparatii ;initializare indicator de inversiuni ;citire cuvant in (AX); (SI) actualizat automat – va referi ;urmatorul element, apoi se compara (AX) cu acesta ;daca e ord. Trece la urm. (cu semn, in loc de „jb e”->”jle”) ;daca nu, se inverseaza cele 2 cuv si ; ;se memoreaza ca s-a facut cel putin o inversiune ;se continua parcurgerea sirului pana la sfarsit ;se reface contorul si adresa de inceput a sirului ;au fost inversiuni ;daca da, se reia odonarea de la inceput ;refacerea contorului initial
Ordonarea crescatoare a unui sir de octeti
.mode small .stack 100h .data Vector db nElem EQU
‚130874563108746510354’,13,10 ;Vectorul de sortat + CRLF $ - 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 sir lungs
segment word public 'data' db 12h, 34h, 56h, 65h, 78h, 7Ah, 98h, 0ABh, 0BCh, 0CDh ; sirul in care cautam 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 offsetul si lungimea sirului in care se se cauta, ; (AL) sau (AX) = valoarea de inserat ;iesiri: (ZF) = 1, valoarea este deja in sir -> (SI) (SI) = offsetul acesteia, 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 push ds pop es push di push si add di, cx inc di sub cx, si inc cx mov si, di dec si std rep movsb pop si mov [si], al pop di pop es pop cx inc cx cmp cx, cx gatai: ret oct_insert_bin endp
; salvare (ES) ; initializare (ES)=(DS) ; salvare offset de inceput ; si pointerul curent ; destinatia transferului: adr. sfarsit + 1 ; numarul de octeti de mutat ; adresa sursei ; transferul se face incepand de sfarsitul sirului ; transferul propriu-zis ; pozitia de inserare ; inserare ; refacere resurse ; refacere (ES) ; actualizare contor sir ; pozitionare (ZF) = 0, adica operatie efectuata
;intrari: (DI), (CX) = offsetul si lungimea sirului in care se 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 stiva stiva end start
ends segment stack dw 100 dup(?) ends
'stack'
. Stergerea unui octet (cuvant) dintr-un sir ordonat crescator ;intrari ;iesiri
(DI),(CX) = offsetul si lungimea sirului in care se cauta (AL) sau (AX) = valoare de eliminat (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 mov dl, 0ah mov ah, 2 int 21h mov dl, 0dh mov ah, 2 int 21h ret linie_noua endp start:
; trecere la o linie noua
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 mov cx, dim_cuvant mov di, 0
; salvare dimensiune maxima a listei ; numarul maxim de caractere ale unui cuvant
cit_cuv: mov ah, 1 int 21h cmp al, '#' jnz sf_cuv? pop cx call linie_noua jmp tiparire sf_cuv?: cmp al, 0dh
; citire caracter ; se termina cand se intalneste caracterul "#" ; este sfarsit de cuvant ? (marcat de tasta RETURN) ; s-a terminat lista de cuvinte, se descarca stiva ; se trece pe o linie noua si urmeaza ; tiparirea listei de cuvinte ; 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 ele mentului 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 or al,al jz iesire cmp al, ‘+’ je plus cmp al, ‘-‘ je minus cmp al, ‘*’ je inmultire sub al, ‘0’ xor ah,ah push ax jmp bucla
;ia un caracter din string ;e caracter terminator? ;daca da, iesire din program ;e plus?
;e minus?
;aici testam pt un operand ;il extindem pe 16 biti ;si il punem pe stiva
plus: pop bx pop ax add ax,bx push ax jmp bucla
;aduna
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 mov ax, 4c00h int 21h end
;extrage rezultat din stiva ;iesire in DOS
; pla62.asm - conversie din binar (16 biti) in zecimal neimpachetat / impachetat. date val valzec date
segment word public dw 23456 db 5 dup (?) ends
prog
segment word public 'code' assume cs: prog, ds: ds: date mov ax,date ; init. reg. segment ds mov ds,ax mov ax, VAL ; AX - valoarea de convertit push ds ; initializare ES:DI cu adresa rezultatul ui pop es lea di, valzec call binzn ; apel functie de conversie binar -> zecimal neimpachetat mov ax,4C00h int 21h
start:
'data' ; valoarea de convertit ; numarul zecimal neimpachetat (convertit)
;intrari: (AX) = valoarea de convertit, care este in intervalul 0÷65535 ;iesiri: (ES:DI) = segment:offset, unde unde se depun cifrele numarului zecimal neimpachetat neimpachetat ; (DI) = refera ultima cifra a numarului zecimal neimpachetat (5 cifre) binzn
proc push push push mov mov div push mov aam stosb mov stosb pop mov div push mov aam stosb mov stosb pop stosb pop pop
near bx dx di bx,100 dx,0 bx ax ax,dx
al,ah ax dx,0 bx ax ax,dx
al,ah ax di dx
; salvare resurse
; impartitor ; extensie semn deimpartit pozitiv ; (DX) = ultimele 2 cifre (zeci, unitati) ; salvare cat ; ultimele doua cifre, in format binar ; corectie zecimal neimpachetata ; depunem cifra unitatilor ; cifra zecilor ; se depune ; se continua algoritmul pentru celelalte 3 cifr e ; extensie semn deimpartit, pozitiv ; (DX) = cifrele: mii, sute; (AX) = zeci de mii
; corectie zecimala neimpachetata pentru cifrele: mii, sute ; depunere cifra zecilor ; cifra miilor ; se depune ; cifra zecilor de mii este i n (AL) si nu necesita corectie ; se depune in memorie
binzn prog stiva stiva end start
pop bx ret endp ends segment stack dw 100 dup(?) ends
'stack'
; pla63.asm - conversie zecimal impachetat, BCD, (16 biþi) -> binar (cuvant) date val valzec date
segment word public dw 3456h dw 1 dup (?) ends
prog
segment word public 'code' assume cs: prog, ds: ds: date 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
start:
'data' ; valoarea zecimal impachetata, de convertit ; numarul binar (convertit)
;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 dw 100 dup(?) stiva ends end start
'stack'
Conversie din binar in hexazecimal (ASCII) (binhex)
;intrari ;iesiri
(AL) – valoare intre 0-15 (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 ret litera: cmp al, 15 ja eroare add al,37h ret eroare: stc ret binhex endp
;codul ASCII pentru cifre
;daca este mai mare ->eroare ;codul ASCII pt litere A-F
;iesire cu eroare (CF = 1)
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 prog start:
conv:
ends segment word public ‘code’ assume cs:prog, ds:hexa 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, si, val_hexa 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 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 proc ;procedura tipareste in hexa valoarea din DL mov al, dl ;se transfera in AL
conv: prog stiva stiva
mov cl,4 shr al, cl lea bx,tab xlat tab mov [si],al inc si mov al, dl and al,0fh xlat tab mov [si], al inc si ret endp ends
;se vor deplasa (logic) primi patru biti ;pr ultimele 4 pozitii ;se face conversia acestei valori la codul ASCII ;se depune prima cifra ASCII la adresa val_hexa ;se incrementeaza adresa pt urmatoarea cifra ;se reface valoarea transmisa in DL ;si se vor retine din aceasta doar ultimii 4 biti ;se face conversia acestei tetrade in ASCII ;se depune codul in memorie la adresa urmatoare ;se actualizeaza adresa pt urmatoarele cifre ;revenire din procedura
segment word stack dw 100 dup(?) ends
‘stack’ ;rezervare memorie pt segm de stiva
. Conversie din binar in o ctal (ASCII)
date_oct segment word public val dw 12345q date_oct ends
‘data’
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 stiva end
segment word stack dw 100 dup(?) ends start
‘stack’
. 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) 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) (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 poziti p ozitiv v 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 de memorie alocat mov cx, lung_1 lea bp, primul cmp dx, cx ; verific presupunerea facuta jge num2_mai_mare num2 _mai_mare ; daca e respectata respecta ta se continua co ntinua xchg bx, bp ; daca nu se schimba intre ele continutul xchg cx, dx ; perechilor de registre, respective num2_mai_mare: push cx ; salvare salva re lungime lungi me numar mai scurt scur t 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 ini tiala pentru (di)=0 (d i)=0 mov di, 0ffffh ; altfel (di)=ffffh, (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: bucla_1 : mov ax, ds:[bp][si] 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: bucla_2 : adc word ptr [bx][si], [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
date prog start:
reia:
urm: gata:
prog stiva stiva end
segment word sir dw lung_sir equ rezult dw ends
public 'data' 0cde4h,0543ah,08765h,0efh,043h,100,1000 ($-sir)/2 2 dup (0)
segment word public 'code' assume cs: prog, ds: ds: date, ss: ss: stiva 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 numarul de elemente elemente din sir jcxz gat a ; test daca sirul este vid add ax, sir[si] ; se aduna elementul curent din sir jnc urm ; salt daca nu este es te transport tran sport inc bx ; daca da, se contorizeaza transporturile add si, type sir; se actualizeaza indexul pentru elementul urmator loop reia ; (cx)-1, daca cx<>0 salt 'reia' mov rezult, ax ; se depune rezultatul mov rezult[2], bx mov ax, 4c00h ; revenire in DOS int 21h ends segment word stack dw 100 dup (?) ends start
'stack'
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 inval id cld mov si,dx ;initializare (SI) cu offsetul sirului sub dx,dxnextcar: DX10;inmultire DX*10 jc invalid;daca inval id;daca rezultatul rezultat ul depaseste depa seste limita li mita (65535) ( 65535) lodsb;se citeste urmatoatea cifra din numar cmp al, '0' jb invalid inva lid cmp al,'9' ja inval id and ax,0fh;se pune pe zero prima tetrada din (AL) si(AH) add dx,ax;se aduna cifra curenta jc inval id loopnextcar mov ax, dx jmp gata gat a 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_ga sit add si, cx;offsetul ultimului element (+1) dec si cmp al, [si] je gata ja nu_gas it 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 urmat or shr cx,1 ;index/=2 add si, cx ;actual adr:in cea de-a 2-a jumatate jmp compare co mpare 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 (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 i nverseaza 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 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
af i s_car macr o 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(?) 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 inlocuiesc cu alta si sa afisez de cate ori am facut schimbarea 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 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 maski db 01010101b
; o masca pt pozitii pare ; 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, 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 dim_var .stack 100h .code compl2 proc
00A0Ah, 0FACh, 7ABCh equ
($ - variab)/2
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
; push si
comparat numarul cu complementul obtinut
push cx clc compl: mov ax, 0
; initializare initializare transport cu 0 ; echivalentul lui 2^n
sbb ax, [si]
; se efectueaza scaderea, cu propagarea imprumutului imprumutului
mov [si], ax inc si inc si
; se depune rezultatul ; actualizare actualizare index cuvant urmator
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 lung_var
nr_unitati
db
?
dup (0acfh)
.code assume cs: @code, ds: 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
mov cx, 16
; contorul de biþi pentru un cuvânt
mov ax, variabila[si]
; se citeºte cuvântul curent
bucla2:
bucla1: rcl ax, 1 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
; o rotaþie pentru a deplasa un bit
.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 mov ds,ax
;initializare segment date
mov dx,offset mesaj1 mov ah,09h int 21h
;scrie mesaj1
mov dx,offset mesaj2 mov ah,09h int 21h
;scrie mesaj2
mov dx,offset buf mov ah,0ah int 21h
;citeste sirul de char
mov cl,buf[1] xor ch,ch xor si,si dec si
;lungimea sirului citit ;initializare si <-0 indicele de deplasare prin sir
modify: inc si cmp si,cx jae gata ;daca s-a ajuns la sfarsitul sirului 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 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 rev_DOS prog ends .data date segment mes_err date ends end start end
db
'eroare:depasire 'eroare:de pasire dimensiune cuvant a rezultatului'
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ă, 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 ;transfe r 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 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 lds si, adr_sir
;bx = offset 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. 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 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 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 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 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 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 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 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 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 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 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 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). r egistre). .model small .data sir db 'alabalaportocala$', 'alabalaportocala$', 50 dup(?) lung_sir equ ($-sir)-50 subsir db 'lamaia' lung_subsir equ ($-subsir) sf_linie db 0dh,0ah,'$' .code insereaza proc add di, dx push cx 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
;di adresa destinatiei, destinatiei, si adresa sursei ;ax pozitia in destinatie ;dx lungimea dest, cx lungimea sursei
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