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.
"Non si conoscono che le cose che si addomesticano", disse la volpe. "Gli uomini non hanno più tempo per conoscere nulla. Comprano dai mercanti le cose già fatte. Ma siccome non esistono mercanti di amici, gli uomini non hanno più amici. Se tu vuoi un amico addomesticami!"
"Che bisogna fare?" domandò il piccolo principe.
"Bisogna essere molto pazienti", rispose la volpe. "In principio tu ti siederai un pò lontano da me, così, nell'erba. Io ti guarderò con la coda dell'occhio e tu non dirai nulla. Le parole sono una fonte di malintesi. Ma ogni giorno tu potrai sederti un pò più vicino...".
Il piccolo principe ritornò l'indomani.
"Sarebbe stato meglio ritornare alla stessa ora", disse la volpe. "Se tu vieni, per esempio, tutti i pomeriggi alle 4, dalle 3 io comincerò ad essere felice. Col passare dell'ora aumenterà la mia felicità. Quando saranno le 4, incomincerò ad agitarmi e ad inquietarmi; scoprirò il prezzo della felicità! Ma se tu vieni non si sa quando, io non saprò mai a che ora prepararmi il cuore... Ci vogliono i riti".
Antoine De Saint-Exupéry - da "Il Piccolo Principe"