Intreruperi
Ex.1. Sa se citeasca de la tastatura numele unui fisier. Sa se afiseze acest fisier pe ecran. assume cs:code, ds:data data segment msg db 'Numele fisierului: $' fileName db 12,?,13 dup (?) buffer db 21 dup (?) openErrorMsg db 'Fisierul nu exista.$' readErrorMsg db 'Nu se poate citii din fisier.$' handler dw 0 data ends code segment start: mov ax, data mov ds, ax ; afisam mesajul cu functia 09h, int 21h mov ah, 09h mov dx, offset msg int 21h ; citim de la tastatura numele fisierului cu ajutorul functiei 0ah, int 21h mov ah, 0ah mov dx, offset fileName int 21h ; în urma citirii la adresa fileName+2 se memoreaza numele fisierului citit ; la adresa fileName + 1 se memoreaza dimensiunea sirului de caractere care reprezinta numele fisierului ; transformam numele fisierului într-un sir ASCIIZ mov bl, fileName[1] mov bh, 0 add bx, offset fileName add bx, 2 mov byte ptr [bx], 0 ; deschidem fisierul cu functia 3dh, int 21h mov ah, 3dh mov al, 0 ; deschidem fisierul pentru citire mov dx, offset fileName+2 int 21h jc openError ; eroare la deschiderea fisierului daca CF e setat mov handler, ax ; salvam identificatorul (handler) fisierului in handler ; cât timp nu e sfârsit de fisier citim din fisier si afisam pe ecran goOn: mov ah, 3fh mov bx, handler mov dx, offset buffer ; citim in buffer mov cx, 20 ; citim maxim 20 de caractere int 21h jc readError ; în caz de succes functia 3dh întoarce în ax numarul de octeti cititi ; salvam numarul octetilor cititi si pregatim sirul pentru afisare mov si, ax mov buffer[si], '$' ; afisam ce am citit mov ah, 09h int 21h cmp si, 20 je goOn ; daca am citit 20 de octeti înseamna ca nu am terminat de citit jmp endPrg ; sarim peste tratarea eventualelor erori openError: mov ah, 09h mov dx, offset openErrorMsg int 21h jmp endPrg readError: mov ah, 09h mov dx, offset readErrorMsg int 21h endPrg: ; inchidem fisierul cu functia 3eh a intreruperii 21h mov ah, 3eh mov bx, handler int 21h mov ax,4c00h int 21h code ends end start Ex.2. Sa se scrie un program de asamblare care tipareste pe ecran, in baza 10, continutul registrilor AX si BX. Rezolvare: Deoarece nu exista nici o intrerupere, a carei rutina de tratare sa poata tipari (sau citi) un numar in baza 10, va trebui sa ne folosim de functia 02h a intreruperii 21h care stie sa afiseze un caracter sau de functia 09h a intreruperii 21h care afiseaza un sir de caractere. Pentru a ajunge de la un numar (ex. 2435 in baza 10) la un sir de caractere pe care sa-l putem afisa (ex. sirul '2','4','3','5') vom imparti succesiv numarul si caturile obtinute la 10 si vom retine resturile care reprezinta de fapt, cifrele numarului. assume cs:code, ds:data data segment LinieNoua db 10,13,'$' zece dw 10 data segment code segment AfisBaza10 PROC ; definim o procedura care afiseaza registrul ax in baza 10 cmp ax, 0 jge pozitiv ; altfel, numarul e negativ si afisam caracterul '-' cu ajutorul functiei 02h a int 21h push ax mov ah, 02h mov dl, '-' int 21h pop ax neg ax ; ax:= valoarea absoluta a lui ax pozitiv: ; pentru a nu avea depasiri, vom imparti totdeauna pe DX:AX la 10. Tot ; impartim la 10 si punem resturile obtinute (adica cifrele) pe stiva pentru ; a inversa, in final, ordinea lor. mov cx, 0 ; in cx, vom retine numarul de cifre puse pe stiva repeta: mov dx, 0 div zece push dx inc cx cmp ax, 0 ja repeta ; daca catul>0 jmp repeta ; acuma vom scoate fiecare cifra de pe stiva si o vom afisa cu ajutorul ; functiei 02h a int 21h scoate: pop dx ; restul, adica cifra, se afla in DL (deoarece este un numar intre 0 si 10) add dl, '0' ; obtinem caracterul corespunzator cifrei mov ah, 02 int 21h loop scoate ret ; revenirea din procedura AfisBaza10 ENDP start: mov ax, data mov ds, ax mov ax, 2435 ; afisam valoarea din ax apeland procedura AfisBaza10 call AfisBaza10 ; sarim la linie noua pe ecran mov ah, 09h lea dx, LinieNoua int 21h mov ax, bx ; afisam valoarea din ax apeland procedura AfisBaza10 call AfisBaza10 mov ax, 4c00h int 21h code ends end start
Programare multimodul
Directive utile:
PUBLIC simbol : exporta "simbol" care e definit in modulul curent spre a fi folosit in alte module
EXTRN simbol: tip : importa "simbol" definit intr-un modul extern spre a fi folosit in modulul curent; tip
poate fi: BYTE, WORD, DWORD, NEAR, FAR, PROC, ABS (constanta, equ).
GLOBAL simbol : face acelasi lucru ca si PUBLIC si EXTRN impreuna.
Ex.3. Scriem un program care concateneaza doua stringuri apeland pentru aceasta o procedura scrisa intr-un modul extern si apoi va afisa stringul rezultat. Modulul main.asm: assume cs:code, ds:data data segment s1 db 'Buna ', 0 s2 db 'dimineata!', 0 rezultat db 30 dup(?) data ends PUBLIC rezultat EXTRN Concat:PROC code segment start: mov ax, data mov ds, ax mov ax, offset s1 mov bx, offset s2 call Concat mov ah, 09h lea dx, rezultat int 21h mov ax, 4c00h int 21h code ends end start Modulul secundar.asm: assume cs:code, ds:data data segment data ends EXTRN rezultat:BYTE PUBLIC Concat code segment Concat PROC push ds pop es ; in AX avem offset s1 si in BX avem offset s2 mov di, offset rezultat mov si, ax repeta: lodsb cmp al, 0 je cont stosb jmp repeta cont: mov si, bx repeta1: lodsb cmp al, 0 je dupa stosb jmp repeta1 dupa: mov al, '$' stosb ret Concat ENDP code ends end Obtinerea executabilului: TASM main.asm TASM secundar.asm TLINK main+secundar