
Input/Output di testo
Nell'esempio seguente vogliamo coinvolgere alcune funzioni base necessarie in quasi tutti i programmi: l'input da tastiera, l'elaborazione, l'output su video e l'output di errori. Prenderemo in considerazione la trasformazione in maiuscolo di una stringa immessa da tastiera. Utilizzeremo solo syscall e pertanto potremo eseguire il link direttamente con ld. Creeremo le condizioni per generare un errore, nel caso di input nullo, in modo da utilizzare tre descrittori di file: STDIN per l'input, STDOUT per l'output normale, STDERR per l'output d'errore.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; upper_1.asm
; Converte in maiuscolo l'input dell'utente.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; compilare con nasm+ld
%define STDIN 0
%define STDOUT 1
%define STDERR 2
%define SYSCALL_EXIT 1
%define SYSCALL_READ 3
%define SYSCALL_WRITE 4
%define BUFLEN 256
section .data ; Sezione dati inizializzati
msg1: db "Digita una stringa: " ; prompt
MSG1: equ $-msg1 ; lunghezza di msg1
msg2: db "Originale: " ;
MSG2: equ $-msg2 ; lunghezza di msg2
msg3: db "Convertita: " ;
MSG3: equ $-msg3 ; lunghezza di msg3
msg4: db 10, "ERRORE: input nullo.", 10 ; messaggio d'errore
MSG4: equ $-msg4 ;lunghezza di msg4
section .bss ; Sezione dati non inizializzati
buf: resb BUFLEN ; buffer di input da tastiera
newstr: resb BUFLEN ; buffer di output conversione
rlen: resb 4 ; lunghezza stringa in input (incluso l'invio)
section .text ; Sezione codice
global _start ; let loader see entry point
_start:
;:::::::::::::::::::::::::::::::::::::::: Output Prompt
mov eax, SYSCALL_WRITE ; write function
mov ebx, STDOUT ; Arg1: file descriptor
mov ecx, msg1 ; Arg2: addr of message
mov edx, MSG1 ; Arg3: length of message
int 080h ; syscall kernel to write
;:::::::::::::::::::::::::::::::::::::::: Input da tastiera
mov eax, SYSCALL_READ ; read function
mov ebx, STDIN ; Arg 1: file descriptor
mov ecx, buf ; Arg 2: address of buffer
mov edx, BUFLEN ; Arg 3: buffer length
int 080h ; syscall kernel to read
;:::::::::::::::::::::::::::::::::::::::: Test Errore
mov [rlen], eax ; salva la lunghezza della stringa
dec eax ; decrementa per escludere l'invio
cmp eax, 0 ; Test su zero
jg read_OK ; Uscita read_OK se Test>0
;:::::::::::::::::::::::::::::::::::::::: Output messaggio d'errore
mov eax, SYSCALL_WRITE ; write function
mov ebx, STDERR ; Arg1: file descriptor
mov ecx, msg4 ; Arg2: addr of message
mov edx, MSG4 ; Arg3: length of message
int 080h ; syscall kernel to write
jmp exit1 ; salta all'uscita: errore =1
;:::::::::::::::::::::::::::::::::::::::: Conversione stringa
read_OK:
mov ecx, [rlen] ; inizializza il contatore
mov esi, buf ; puntatore al buffer di input
mov edi, newstr ; puntatore al buffer di conversione
nextch: mov al, [esi] ; legge un carattere
inc esi ; aggiorna il puntatore sorgente
cmp al, 'a' ; verifica che sia minuscolo
jb store ; Se NO: Salta la conversione
cmp al, 'z'
ja store ; Se NO: Salta la conversione
and al,0DFh ; Se SI: Converte in maiuscolo
store: mov [edi], al ; memorizza il carattere
inc edi ; aggiorna il puntatore destinazione
dec ecx ; aggiorna il contatore
jnz nextch ; ricicla
;:::::::::::::::::::::::::::::::::::::::: Output messaggio 2
mov eax, SYSCALL_WRITE ; write message
mov ebx, STDOUT
mov ecx, msg2
mov edx, MSG2
int 080h
;:::::::::::::::::::::::::::::::::::::::: Output stringa originale
mov eax, SYSCALL_WRITE ; write user input
mov ebx, STDOUT
mov ecx, buf
mov edx, [rlen]
int 080h
;:::::::::::::::::::::::::::::::::::::::: Output messaggio 3
mov EAX, SYSCALL_WRITE ; write message
mov EBX, STDOUT
mov ECX, msg3
mov EDX, MSG3
int 080h
;:::::::::::::::::::::::::::::::::::::::: Output stringa convertita
mov EAX, SYSCALL_WRITE ; write out string
mov EBX, STDOUT
mov ECX, newstr
mov EDX, [rlen]
int 080h
;:::::::::::::::::::::::::::::::::::::::: Uscita
mov EBX, 0 ; exit code, normal=0
jmp exit
exit1: mov EBX, 1 ; exit code, error=1
exit: mov EAX, SYSCALL_EXIT ; exit function
int 080h ; syscall kernel to take over
; EOF ::::::::::::::::::::::::::::::::::::::::::::::::::::::
Tra le cose da notare, l'inserimento della sezione .bss per la definizione di variabili non inizializzate (i buffer: buf e newstr), in contrapposizione alla sezione .data; ed ancora le pseudoistruzioni %define per introdurre delle costanti. Infine la funzione exit riporta in ebx un codice di uscita che vale "0" se tutto si è concluso regolarmente, oppure "1" in caso di uscita su STDERR.

Menù

La scarpa che va bene a una persona va stretta ad un'altra: non c'è una ricetta di vita che vada bene per tutti.
Carl Gustav Jung