Laborator 8 - Exemple

Apeluri de functii sistem

Atentie la utilizarea functiei scanf

Atentie la dimensiunea de reprezentare a variabilelor in functie de formatul dorit. Vezi tabel la sectiunea Functii standard din msvcrt din Teorie. Urmariti exemplul de mai jos care e GRESIT (greseala frecventa) si spuneti ce se intampla:
; Ne propunem ca programul de mai jos sa citeasca de la tastatura un numar si sa afiseze pe ecran valoarea numarului citit impreuna cu un mesaj.
bits 32
global start        

; declararea functiilor externe folosite de program
extern exit, printf, scanf  ; adaugam printf si scanf ca functii externe           
import exit msvcrt.dll     
import printf msvcrt.dll     ; indicam asamblorului ca functia printf se gaseste in libraria msvcrt.dll
import scanf msvcrt.dll      ; similar pentru scanf
                          
segment  data use32 class=data
	n db 0       ; in aceasta variabila se va stoca valoarea citita de la tastatura
	message  db "Numarul citit este n= %d", 0  
	format  db "%d", 0  ; %d <=> un numar decimal (baza 10)
    
segment  code use32 class=code
    start:
                                               
        ; vom apela scanf(format, n) => se va citi un numar in variabila n
        ; punem parametrii pe stiva de la dreapta la stanga
        push  dword n       ; ! adresa lui n, nu valoarea
        push  dword format
        call  [scanf]       ; apelam functia scanf pentru citire
        add  esp, 4 * 2     ; eliberam parametrii de pe stiva; 4 = dimensiunea unui dword; 2 = nr de parametri
        
        ;convertim n la dword pentru a pune valoarea pe stiva 
        mov  eax,0
        mov  al,[n]
        
        ;afisam mesajul si valoarea lui n
        push  eax
        push  dword message 
        call  [printf]
        add  esp,4*2 
        
        ; exit(0)
        push  dword 0     ; punem pe stiva parametrul pentru exit
        call  [exit]       ; apelam exit pentru a incheia programul
In exemplul de mai sus se suprascrie inceputul din mesaj si nu se mai afiseaza nimic pe ecran.

Afisarea unui mesaj

; Codul de mai jos va afisa mesajul "Ana are 17 mere"
bits 32
global start        

; declararea functiilor externe folosite de program
extern exit, printf         ; adaugam printf ca functie externa            
import exit msvcrt.dll    
import printf msvcrt.dll    ; indicam asamblorului ca functia printf se gaseste in libraria msvcrt.dll
                          
segment data use32 class=data
; sirurile de caractere sunt de tip byte
format db "Ana are %d mere", 0  ; %d va fi inlocuit cu un numar
				; sirurile de caractere pt functiile C trebuie terminate cu valoarea 0
segment  code use32 class=code
    start:
        mov eax, 17
        
        ; vom apela printf(format, 17) => se va afisa: „Ana are 17 mere”
        ; punem parametrii pe stiva de la dreapta la stanga
        push dword eax
        push dword format ; ! pe stiva se pune adresa string-ului, nu valoarea
        call [printf]      ; apelam functia printf pentru afisare
        add esp, 4 * 2     ; eliberam parametrii de pe stiva; 4 = dimensiunea unui dword; 2 = nr de parametri

        ; exit(0)
        push dword 0      ; punem pe stiva parametrul pentru exit
        call [exit]       ; apelam exit pentru a incheia programul

Afisarea unui quadword pe ecran

segment data use32 class=data
a dq  300765694775808
format db '%lld',0

segment code use32 class=code
start:

push dword [a+4]
push dword [a]
push dword format
call [printf]
add esp,4*3

push    dword 0      
call    [exit]
		

Citirea unui numar de la tastatura

; Codul de mai jos va afisa mesajul ”n=”, apoi va citi de la tastatura valoarea numarului n.
bits 32

global start        

; declararea functiilor externe folosite de program
extern exit, printf, scanf ; adaugam printf si scanf ca functii externa            
import exit msvcrt.dll    
import printf msvcrt.dll    ; indicam asamblorului ca functia printf se gaseste in libraria msvcrt.dll
import scanf msvcrt.dll     ; similar pentru scanf
                          
segment data use32 class=data
	n dd  0       ; in aceasta variabila se va stoca valoarea citita de la tastatura
    ; sirurile de caractere sunt de tip byte
	message  db "n=", 0  ; sirurile de caractere pentru functiile C trebuie sa se termine cu valoarea 0 (nu caracterul)
	format  db "%d", 0  ; %d <=> un numar decimal (baza 10)
    
segment code use32 class=code
    start:
       
        ; vom apela printf(message) => se va afisa "n="
        ; punem parametrii pe stiva
        push dword message ; ! pe stiva se pune adresa string-ului, nu valoarea
        call [printf]      ; apelam functia printf pentru afisare
        add esp, 4*1       ; eliberam parametrii de pe stiva ; 4 = dimensiunea unui dword; 1 = nr de parametri
                                                   
        ; vom apela scanf(format, n) => se va citi un numar in variabila n
        ; punem parametrii pe stiva de la dreapta la stanga
        push dword n       ; ! adresa lui n, nu valoarea
         push dword format
        call [scanf]       ; apelam functia scanf pentru citire
        add esp, 4 * 2     ; eliberam parametrii de pe stiva
                           ; 4 = dimensiunea unui dword; 2 = nr de parametri
        
        ; exit(0)
        push dword 0      ; punem pe stiva parametrul pentru exit
        call [exit]       ; apelam exit pentru a incheia programul

Salvarea valorilor din registrii inaintea apelurilor de functii sistem

; Codul de mai jos va calcula rezultatul unor operatii aritmetice in registrul EAX, va salva valoarea registrilor, apoi va afisa valoarea rezultatului si va restaura valoarea registrilor.
bits 32

global start        

; declararea functiilor externe folosite de program
extern exit, printf  ; adaugam printf ca functie externa            
import exit msvcrt.dll    
import printf msvcrt.dll    ; indicam asamblorului ca functia printf se gaseste in libraria msvcrt.dll
                          
segment data use32 class=data
	; sirurile de caractere sunt de tip byte
	format  db "%d", 0  ; %d <=> un numar decimal (baza 10)
	
segment code use32 class=code
	start:
		; vom calcula 20 + 123 + 7 in EAX
		mov eax, 20
		add eax, 123
		add eax, 7         ; eax = 150 (baza 10) sau 0x96 (baza 16)
		
		; salvam valoarea registrilor deoarece apelul functiei sistem printf va modifica valoarea acestora
		; folosim instructiunea PUSHAD care salveaza pe stiva valorile mai multor registrii, printre care EAX, ECX, EDX si EBX 
		; in acest exemplu este important sa salvam doar valoarea registrului EAX, dar instructiunea poate fi aplicata generic
		PUSHAD
	   
		; vom apela printf(format, eax) => vom afisa valoarea din eax
		; punem parametrii pe stiva de la dreapta la stanga
		push dword eax
		push dword format ; ! pe stiva se pune adresa string-ului, nu valoarea
		call [printf]      ; apelam functia printf pentru afisare
		add esp, 4*2       ; eliberam parametrii de pe stiva ; 4 = dimensiunea unui dword; 2 = nr de parametri
		
		; dupa apelul functiei printf registrul EAX are o valoare setata de aceasta functie (nu valoarea 150 pe care am calculat-o la inceputul programului)
		; restauram valoarea registrilor salvati pe stiva la apelul instructii PUSHAD folosind instructiunea POPAD
		; aceasta instructiune ia valori de pe stiva si le completeaza in mai multi registrii printre care EAX, ECX, EDX si EBX
		; este important ca inaintea unui apel al instructiunii POPAD sa ne asiguram ca exista suficiente valori 
		; pe stiva pentru a fi incarcate in registrii (de exemplu ca anterior a fost apelata instructiunea PUSHA)
		POPAD
		
		; acum valoarea registrului EAX a fost restaurata la valoarea de dinaintea apelului instructiunii PUSHAD (in acest caz valoarea 150)
		
		; exit(0)
		push dword 0      ; punem pe stiva parametrul pentru exit
		call [exit]       ; apelam exit pentru a incheia programul

Operatii cu fisiere text

Crearea unui fisier nou

Fisier asm: create_file.asm

Scrierea unui text intr-un fisier nou

Fisier asm: create_write_file.asm

Adaugarea unui text intr-un fisier

Fisier asm: create_append_file.asm

Citirea unui text scurt  (max 100 caractere) dintr-un fisier

Fisier asm: read_short_text_from_file_no_display.asm

Citirea unui text scurt  (max 100 caractere) dintr-un fisier – cu afisarea textului

Fisier asm: read_short_text_from_file_and_display.asm

Citirea intregului text dintr-un fisier (in etape)

Fisier asm: read_full_file.asm