dal 2015 - visita n. 1085
I/OdiTesto
I/OdiTesto

 

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.








Presentazione
Introduzione
Hello World
I/O di Testo
Command Line
Colori e Macro
Introduzione I/O
Porta Parallela


x86 Asm Progranmming
Linux ELF Howto
Linux Assembly Howto


AppuntiAsmx.html
AppuntiAsmx.pdf



La durata delle nostre passioni non dipende da noi, come non dipende da noi la durata della vita.
La Rochefoucauld

Valid CSS!
pagina generata in 0.001 secondi