dal 2015 - visita n. 1069
HelloWorld
HelloWorld

 

Quasi il classico "Hello world"


Il primo esempio leggerà il marchio di fabbrica della CPU e lo visualizzerà sul terminale. Il codice è scritto per macchine di classe Pentium e non esegue alcun controllo per i 486 o precedenti.

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
; hello_1.asm 
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; compilare con nasm+gcc

global 	main
extern 	printf

section .data
cls     db 1Bh,"[2J",0
msg 	db 0Dh,0Ah,"Marchio del produttore della CPU: "
idx 	dd 0,0,0
	db 0Dh,0Ah,0Ah,0

section .text
main: 	push 	dword cls	;Clear del terminale
    	call 	printf
	pop 	eax
	mov 	eax,0		;Identificazione CPU
      	cpuid
	mov	[idx],ebx	;Lettura prime 4 lettere
	mov	[idx+4],edx  	;Lettura 4 lettere centrali
	mov	[idx+8],ecx	;Lettura ultime 4 lettere
    	push 	dword msg	;Output Messaggio
    	call 	printf
    	pop 	eax
    	ret			;Uscita programma
; EOF ::::::::::::::::::::::::::::::::::::::::::::::::::::::



L'esempio appena illustrato esegue quattro operazioni: la pulizia del terminale, l'identificazione della CPU, l'emissione di un messaggio, l'uscita dal programma. L'uso della printf, appartenente alla libreria libc, semplifica le operazioni di output su terminale (clear e messaggio), si noti il passaggio del parametro (puntatore alla stringa) tramite una push con conseguente pop per ripristinare lo stato dello stack. Al posto della pop eax, che coinvolge l'uso di un registro, si potrebbe usare una add esp,4 che risolve il problema del riallineamento dello stack senza coinvolgere registri. L'uscita del programma realizzata con una semplicissima ret.

Ci proponiamo di risolvere lo stesso problema con l'uso di chiamate al kernel, ovvero con le cosiddette syscall. La soluzione è leggermente più complessa, ma è di particolare interesse il passaggio dei parametri tramite registri; si noti, in particolare, che il registro eax viene utilizzato per individuare il numero della syscall da usare, mentre i parametri (par1, par2, par3, ...) vengono passati ordinatamente tramite i registri ebx, ecx, edx, esi, edi, ebp, rispettivamente.
Il confronto con la soluzione precedente evidenzia alcune cose: l'assenza della dichiarazione extern, la mancanza del terminatore null alla fine delle stringhe, la presenza di una costante per l'individuazione della lunghezza delle stringhe.

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
; hello_2.asm 
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; compilare con nasm+ld

global 	main

section .data
cls	db 1Bh,"[2J"
CLS	equ	$-cls
msg 	db 0Dh,0Ah,"Marchio del produttore della CPU: "
idx 	dd 0,0,0
	db 0Dh,0Ah,0Ah
MSG	equ	$-msg	

section .text
main: 				;Clear del terminale
	mov     edx,CLS		;par3: lunghezza del messaggio
	mov     ecx,cls		;par2: indirizzo del messaggio
	mov     ebx,1       	;par1: descrittore del file (stdout)
	mov     eax,4       	;numero della syscall write
	int     80h        	;chiamata kernel syscall
	mov 	eax,0		;Identificazione CPU
      	cpuid
	mov	[idx],ebx	;Lettura prime 4 lettere
	mov	[idx+4],edx  	;Lettura 4 lettere centrali
	mov	[idx+8],ecx	;Lettura ultime 4 lettere
				;Output Messaggio
	mov     edx,MSG		;par3: lunghezza del messaggio
	mov     ecx,msg		;par2: indirizzo del messaggio
	mov     ebx,1       	;par1: descrittore del file (stdout)
	mov     eax,4       	;numero della syscall write
	int     80h        	;chiamata kernel syscall
				;Uscita programma
	mov     ebx,0       	;Par1: codice di ritorno
	mov     eax,1       	;numero della syscall exit
	int     80h        	;chiamata kernel syscall
; EOF ::::::::::::::::::::::::::::::::::::::::::::::::::::::



Se effettuiamo un confronto sulla lunghezza dei due eseguibili ottenuti, anche se i sorgenti non sono perfettamente identici, possiamo notare l'evidente maggior compattezza di hello_2 rispetto ad hello_1.

-rwxr-xr-x  1 byteman users 2972 nov  1 19:02 hello_1*
-rwxr-xr-x  1 byteman users  576 nov  1 19:04 hello_2*



Complementi

Per quanto riguarda l'identificazione della CPU, ecco quale stringa viene restituita a seconda dei principali produttori:

                        AMD      "AuthenticAMD"
                        Centaur  "CentaurHauls"
                        Cyrix    "CyrixInstead"
                        Intel    "GenuineIntel" 
                        NexGen   "NexGenDriven"
                        Rise     "RiseRiseRise"
                        UMC      "UMC UMC UMC "








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



Non aprire il tuo cuore ad ognuno se non vuoi perdere la tua felicità.
Proverbio

Valid CSS!
pagina generata in 0.001 secondi