Sunteți pe pagina 1din 14

Programarea în limbaj

de asamblare
Funcţii DOS
Sistemul de operare DOS (Disk Operating System) pune la dispoziţia aplicaţiilor un set de rutine
(funcţii) pentru gestionarea resurselor sistemului.
Utilizarea acestor rutine uşurează munca programatorului permiţându-i o viziune de nivel înalt
asupra aplicaţiei dezvoltate.
Mecanismul prin care o aplicaţie poate utiliza un servicu pus la dispoziţie de sistemul de operare
este cel al întreruperilor software.
Funcţiile DOS pot fi apelate prin INT 21H atât din limbaj d e asamblare cât şi din limbaje de nivel
înalt, aşa cum este C.
Pentru apelul funcţiilor DOS este rezervată întreruperea 21H.
Numărul funcţiei DOS apelate este transmis ca parametru în registrul AH. Parametrii de intrare şi
ieşire ai funcţiilor DOS sunt transmişi prin registre.
Funcţii DOS
Pentru a apela o funcţie DOS, programul trebuie să realizeze următoarele acţiuni:
• încarcă în registrele corespunzătoare funcţiei parametrii de intrare;
• încarcă în registrul AL codul subfuncţiei (dacă este necesar);
• încarcă în registrul AH codul funcţiei;
• lansează instrucţiunea INT 21H.
La terminarea procedurii, programul trebuie să preia eventualii parametrii de ieşire din
registrele corespunzătoare funcţiei.
Lista principalelor funcţii DOS
Funcţie DOS Denumire Funcţie DOS Denumire

01H Character input with echo 3CH Create file (CREAT)


02H Output character 3DH Open file (OPEN)
08H Character input without echo 3EH Close file (CLOSE)
09H Output character string 3FH Read file (READ)
25H Set interrupt vector 40H Write file (WRITE)
2AH Get system date 41H Delete file (UNLINK)
2BH Set system date 43H Get/set file attributes
2CH Get system time 4BH Load or execute program (EXEC)
2DH Set system time 4CH Process terminate (EXIT)
31H Terminate and stay resident 4DH Get return code of a subprocess
35H Get interrupt vector 56H Rename file
39H Create subdirectory (MKDIR) 57H Get/set file date and time
3AH Remove directory entry (RMDIR) 62H Get program segment prefix (PSP)
address
3BH Set directory (CHDIR)
Exemplul 1: Preluare caracter de la tastatură, cu ecou/scriere
caracter pe ecran
Acest exemplu prezintă un program în limbaj de asamblare care citeşte de la tastatură un număr de două cifre, cu ecou. Cele
două cifre sunt interpretate ca fiind un număr reprezentat în baza 10. Pe o linie nouă, se va afişa restul împărţirii cu 9 a
numărului introdus.
Pseudocodul algoritmului implementat de program este următorul:
- preia primul caracter, cu ecou, prin utilizarea funcţiei DOS 01H (character input with echo);
- converteşte primul caracter la valoarea numerică prin scăderea codului ASCII al caracterului ’0’;
- preia al doilea caracter, cu ecou;
- converteşte al doilea caracter la valoarea numerică;
- compune numărul introdus (prima cifră × 10 + a doua cifră);
- împarte numărul la 9 şi păstrează restul;
- converteşte numărul la codul ASCII al caracterului corespunzător prin adunarea codului ASCII al caracterului ’0’;
- poziţionează cursorul la începutul liniei următoare;
- afişează caracterul prin utilizarea funcţiei DOS 02H (character output);
- termină programul prin utilizarea funcţiei DOS 4CH (process terminate).
Programul face apel la trei funcţii DOS:

Funcţie DOS 01H (character input with echo)


Registre la intrare: AH: 1
Registre la ieşire: AL: caracter
Descriere: Aşteaptă introducerea unui caracter de la tastatură. În momentul introducerii unui
caracter, codul ASCII asociat acestuia este returnat în registrul AL iar simbolul caracterului este
afişat pe ecran la poziţia curentă a cursorului.
acă tastatura generează un cod ASCII extins (cazul apăsării unei taste funcţionale sau taste de
control), atunci funcţia returnează 0 în registrul AL. Invocarea ulterioară a funcţiei returnează
codul tastei (scan code) fără a mai aştepta apăsarea unei taste.
Funcţie DOS 02H (character output)
Registre la intrare: AH: 2
DL: cod ASCII de caracter
Registre la ieşire: nemodificate
Descriere: Conţinutul registrului DL este trimis spre dispozitivul standard de ieşire (ecran).
Simbolul asociat codului ASCII al caracterului este afişat la poziţia curentă a cursorului.

Funcţie DOS 4CH (process terminate)


Registre la intrare: AH: 4CH
AL: cod returnat
Registre la ieşire: nemodificate
Descriere: Termină programul care a apelat funcţia şi întoarce controlul programului părinte
(care a apelat programul) sau sistemului de operare.
Codul sursă sub al, ’0’ ; 3=‘3’-’0’
add al, bl ; ex 23
mov cl, 9
mov ah, 0
code segment div cl
assume cs:code, ds:code mov bl, ah ; restul este in BL
CR equ 0AH add bl, ’0’
call afisare ; afişare şir de caractere
LF equ 0DH mov ax, 4C00h ; terminare program (apel funcţie DOS
start: 4CH)
mov ax, code int 21h
mov ds, ax ; suprapune segmentul de date peste cel de cod afisare PROC ; afişare şir de caractere prin intrerupere
mov bh, 0 mov dl, CR
mov ah, 2
mov ah, 1 ; citire tastatură prin serviciu DOS 01H int 21h
int 21h mov dl, LF
sub al, ’0’ ; prima cifră în AL ; ex ‘2’-’0’=2 int 21h
mov cl, 10 mov dl, bl
mul cl ; AL <- AL * 10; ex 20 int 21h
ret
mov bl, al ; prima cifră in BL inmulţită cu 10 afisare ENDP
mov ah, 1 ; citire a doua cifră prin apel DOS code ENDS
int 21h END start
Exemplul 2: Citire caracter fără ecou

Acest exemplu prezintă un program care primeşte de la tastatură un şir de cuvinte pe care le
afişează pe ecran.
Toate cuvintele vor avea iniţiala majusculă, indiferent de modul în care a fost tastată (majusculă
sau minusculă).
Terminarea programului se va face la apăsarea tastei ESC.
Programul necesită prelucrarea fiecărui caracter primit de la tastatură înainte de a fi afişat pe
ecran.
Soluţia constă în preluarea caracterului cu funcţia DOS 8 (character input without echo),
analizarea şi eventuala prelucrare a acestuia şi, ulterior, afişarea caracterului cu funcţia DOS 2
(character output).
Codul sursă
code SEGMENT
assume cs:code, ds:code cmp al, ’z’
tasta_ESC equ 27 jg scrie_al ; sau mai mare decat ’z’ (in
start:
;afara domeniului minusculelor)
mov ax, cs
mov ds, ax sub al, 20H ; transformă minuscula in
mov bl, 1 ; indicator: BL=1 - converteşte caracterul in majusculă majusculă
; BL=0 - lasă caracterul neschimbat
jmp scrie_al
caracter_in:
mov ah, 8 schimb_maj:
int 21h ; apel funcţie DOS 8 (character input without echo) mov bl, 1
; returnează in AL codul tastei apăsate scrie_al: ; afişează caracterul
cmp al, tasta_ESC
jz final ; s-a tastat ESC mov ah, 2
cmp al, ’ ’ mov dl, al
jz schimb_maj ; s-a tastat ’ ’ (spaţiu=delimitator de cuvinte) int 21h
; următorul caracter este transformat in majusculă
jmp caracter_in
cmp bl, 0 ;
final:
jz scrie_al ; caracterul se lasă neschimbat
mov bl, 0 ; este o iniţială... mov ah, 4ch
cmp al, ’a’ int 21h
jl scrie_al ; cu cod ASCII mai mic decat ’a’... code ends
end start
Exemplul 3: Preluare dată sistem
Acest exemplu prezintă un program care afişează pe ecran data sistemului sub forma:
AALuna
unde:
AA este anul (ultimele două cifre);
Luna este denumirea lunii în limba română.

Codul sursă al programului ce rezolvă problema enunţată este prezentat în continuare.


Programul face apel la două funcţii DOS:
Funcţie DOS 2AH (get system date)
Registre la intrare: AH: 2AH
Registre la ieşire: AL: ziua din săptămână
CX: anul
DH: luna
DL: ziua
Descriere: Se returnează ziua (DL), luna (DH) şi anul (CX) datei sistem. în registrul AL se returnează codul zilei
din săptămână: 0 = duminică, 1 = luni, 2 = marţi, etc.
Funcţie DOS 9 (output character string)
Registre la intrare: AH: 9
DX: offset adresă şir
DS: segment adresă şir
Registre la ieşire: nemodificate
Descriere: Se afişează pe ecran şirul de caractere care începe la adresa DS:DX. Terminatorul de şir, care nu se afişează, este caracterul
’$’ (cod ASCII 36, 24H). Prin această funcţie nu se poate afişa caracterul ’$’.

Denumirea în limba română a lunilor anului a fost specificată sub forma unei definiţii de date de tip byte. Şirul a fost conceput astfel
încât să se aloce fiecărei luni acelaşi număr de caractere (11).
Adresa care trebuie transmisă ca parametru funcţiei DOS 9 este calculată după formula:
Denumire luna + 11 × (luna curentă - 1).
Funcţia DOS 2AH (get system date) se apelează chiar la începutul programului.
Restul programului se ocupă cu prelucrarea şi afişarea parametrilor returnaţi de această funcţie. Anul este preluat în registrul CX şi
este prelucrat pentru a se obţine cele două caractere asociate cifrelor zecilor şi unităţilor. Apoi este afişat un caracter spaţiu. Pe baza
numărului lunii, returnat în registrul DH, se calculează adresa care trebuie transmisă funcţiei DOS 9 (output character string).
Cod sursa
code SEGMENT
mov dl, bh
assume cs:code, ds:code
add dl, ’0’
Denumire_luna db ’Ianuarie$ Februarie$ Martie$ Aprilie$ ’
mov ah, 2
db ’Mai$ Iunie$ Iulie$ August$ ’
int 21h ; scrie cifra unităţilor din reprezentarea anului
db ’Septembrie$ Octombrie$ Noiembrie$ Decembrie$ ’
mov dl, ’ ’
start:
mov ah, 2
mov ax, cs
int 21h ; scrie ’ ’
mov ds, ax
; DH=luna (parametru de ieşire din funcţia DOS 2AH)
mov ah, 2Ah ; preia data sistem, funcţie DOS 2AH
dec dh ; DH=index in tabelul Denumire_luna
int 21h
mov al, 11 ; numărul de octeti alocaţi in tabelul Denumire_luna
; preluare parametrii, prelucrare şi afişare
; pentru o intrare (o denumire de lună)
sub cx, 2000 ; CX=anul (parametru de ieşire din funcţia DOS 2AH)
mul dh ; AL x DH = (AH:AL), index sir
mov ah, 0
mov dx, offset Denumire_luna
mov al, cl
add dx, ax ; DX=pointer la denumirea lunii curente, şir terminat
mov bl, 10
; cu ’$’
div bl ; (AH:AX) / BL => AL=cat, AH = rest
mov ah, 9 ; afişează şir cu funcţia DOS 9
; AL=cifra zecilor, AH=cifra unităţilor (AN)
int 21h
mov bx, ax
mov ah, 4ch
mov dl, bl
int 21h
add dl, ’0’
code ends
mov ah, 2
end start
int 21h ; scrie cifra zecilor din reprezentarea anului

S-ar putea să vă placă și