HOME PAGE  |   CONTATTI |   COLLABORA |  ASP  |  PHP  |  HTML |  CSS |  PERL |  JAVA |  TCP/IP  |  RETI  |  LINUX |  MANUALI SPAZIO WEB
PROGRAMMAZIONE

Linguaggio C++

Linguaggio C

Assembler

Java

Perl

LINGUAGGI WEB

Html

Asp

Php

Css

Javascript

GUIDE DI BASE

Internet

Computer

Hardware

Linux




 

PROGRAMMARE IN ASSEMBLER SU PROCESSORI X86.

 

Prima parte

 

A cura di: Bartolomeo Davide Bertinetto

www.bertinettobartolomeodavide.it 



Dopo svariati anni di sperimentazione e apprendimento del linguaggio assembly ho finalmente deciso di pubblicare una pagina web su questo argomento. In modo che tutti gli appassionati e tutti i neofiti della programmazione possano trarne profitto.
Non vi serviranno grosse risorse hardware o software per addentrarvi nei meandri di questo linguaggio a basso livello per eccellenza. Sara sufficiente aprire un finestra dos da windows 9X, Me, NT, 2000 o XP ( Funziona tutto perfettamente anche su
window 3.x e su tutte le vecchie versioni del dos) e poi digitare un comando che ormai conoscono in pochi: il mitico DUBUG.EXE del dos e quindi premere ENTER.


Il gioco è fatto!


Analizziamo in prima istanza i comandi principali di DEBUG:
q : esce
h : somma e sottrae in esadecimale
r : visualizza i registri del processore: AX, BX, CX, DX, ecc...
r ax : modifica il registro ax
e : introduce una funzione od un valore in codice macchina ad un determinato indirizzo.
e 100 : modifica l'indirizzo esadecimale 100h.
t : esegue un istruzione singola. PS: assicurarsi che l'indirizzo IP sia sempre a 100h.
g : esegue più di un'istruzione alla volta e si ferma all'indirizzo specificato (di solito si parte da 100h).
g 102 : si ferma l'esecuzione all'indirizzo 102h.
u : lista un programma partendo da un determinato indirizzo per un determinato numero di linee.
u 100 : visualizza il codice dall'indirizzo 100h in poi.
a : permette di introdurre le funzioni in linguaggio assembler a partire da un determinato indirizzo.
a 100 : parte dall'indirizzo 100h la programmazione in assembler.
n : assegna un nome al file contenete il codice da salvare. (impostare su CX la lunghezza in byte del codice da salvare).
n nome.com : da al nostro codice il nominativo al file eseguibile nome.com (attenzione però non lo salva!!!).
w : salva il programma.
d : DUMP, stampa della memoria. Si deve specificare l'indirizzo da cui partire per la visualizzazione.
d 200 : visualizza la memoria del calcolatore a partire dall' indirizzo d 200h.


Con questo elenco dovreste avere un valido manuale di riferimento sui principali comandi di DEBUG.EXE.
avete capito come funziona? Spero di si!! Facciamo una prova.

Al prompt digitiamo:
C:\ > DEBUG.EXE ------------> premiamo il tasto 'enter'.
poi ....
appare:
- --------> trattino.
digitiamo ad esempio:
- h 3 2 -------> premiamo il tasto 'enter'.
e quindi ci compare su schermo:
0005 0001
questo è il risultato sia dell'addizione (5) e della sottrazione (1). 

 

PS: ricordatevi che
sono numeri esadecimali!!! I numeri trattati da debug sono esadecimali come dicevo. Nel caso di questo esempio
FFFFh è il max numero raggiungibile e corrisponde a -1 e non a 65536 in decimale.


tutto ok.


ora digitiamo il tasto 'q' per uscire da DEBUG.EXE:
-q --------> poi premiamo il tasto 'enter'.
ora siamo tornati al prompt dei comandi!!!
c:\>
tutto qui: siamo fuori da DEBUG.EXE.
----------------------------------------------------
Vi schematizzo velocemente la differenza tra byte(8 bit) e word(16 bit):
8 bit + 8 bit
11111111 11111111
byte byte
|------------------------|
word a 16 bit
In poche parole 8 bit fanno 1 byte e 2 byte fanno 1 word, che quindi è a 16 bit!
Come vedremo più avanti un registro è composto da una word perciò è a 16 bit.


FUNZIONI MATEMATICHE:
Proviamo ad impartire delle semplici operazioni matematiche al nostro processore di addizione, sottrazione, moltiplicazione e divisione. Ovviamente la prima è l'addizione: in linguaggio assembly il comando è ADD
(codice macchina 01h d8h)
Inseriamo con il comando 'r ax' il numero 4 ad esempio nel registro ax. Poi con il comando 'r bx' inseriamo il numero 5 ad esempio. Ora con il comando 'e 100' impartiamo il comando di addizione al calcolatore all'indirizzo 100h e ci verrà visualizzato un simile messaggio:


0f79:0100 00._ --------> inseriamo qui '01' e poi premiamo il tasto di 'spaziatura'
allora avremo:
0f79:0100 00.01 00._ ---------> inseriamo qui 'd8' e poi il tasto 'invio'


Così abbiamo impartito il comando di addizione al calcolatore.
Dobbiamo però farci dare il risultato a questo punto.
Perciò con il comando 't' eseguiamo questa singola istruzione (ammesso che il registro ip sia settato a 100h)


Avremo il numero 0009 come risultato nel registro ax.
Tutto questo procedimento equivale al comando in assembly : 'add ax,bx' (risultato in ax).
Vi ricordo che per continuare con gli esempi è necessario riportare ogni volta il registro ip a 100h in questo modo:


- r ip ---------> premino il tasto enter.
quindi inseriamo:
IP 0102
: 100 --------> premiamo il tasto enter.


quindi digitiamo 'r' e premiamo enter per verificare se il registro ip è a 100h, così
comparirà all'incirca questo:


AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=14A0 ES=14A0 SS=14A0 CS=14A0 IP=0100 NV UP EI PL NZ AC PE NC
14A0:0100 29D8 SUB AX,BX


Ora passiamo all' operazione di sottrazione (sub in assembly).
Vi dico subito che tutti i passaggi sono identici all' addizione tranne che per il codice macchina da inserire.


Il codice macchina da inserire per la sottrazione è : 29h d8h.
Corrispondente al comando assembly: sub ax,bx ( gli indirizzi coinvolti sono sempre ax e bx con risultato in ax).

Ora passiamo all' operazione di moltiplicazione (mul in assembly).
Vi dico subito che tutti i passaggi sono identici all' addizione tranne per il codice macchina da inserire.
Il codice macchina da inserire per la moltiplicazione è : f7h e3h.
Corrispondente al comando assembly: mul bx ( qui sono coinvolti il registro bx che è sempre moltiplicato per ax è il risultato è dato dalla composizione del registro dx con ax (valore a 32bit)).

Ora passiamo all' operazione di divisione (div in assembly).
Vi dico subito che tutti i passaggi sono identici all' addizione tranne per il codice macchina da inserire.
Il codice macchina da inserire per la divisione è : f7h f3h.
Corrispondente al comando assembly: div bx ( qui sono coinvolti il registro ax che è sempre diviso per bx, il risultato è nel registro ax con il resto inserito nel registro dx.


Esaminiamo i registri per capire come sono composti.
REGISTRI:
· ax (16 bit) = ah(la 'h' sta per high) a 8 bit + al (la 'l' sta per low) a 8 bit
· bx (16 bit) = bh(la 'h' sta per high) a 8 bit + bl (la 'l' sta per low) a 8 bit
· cx (16 bit) = ch(la 'h' sta per high) a 8 bit + cl (la 'l' sta per low) a 8 bit
· dx (16 bit) = dh(la 'h' sta per high) a 8 bit + dl (la 'l' sta per low) a 8 bit
· e così via ........


Questo schema sui registri servirà in seguito perché a volte sarà necessario manipolare solo una parte del registro.
Fino ad ora vi faccio notare che abbiamo operato in codice macchina che è ancora più a basso livello del linguaggio assembler!! Vediamo come possiamo fare, in pratica, per stampare su schermo un carattere usando sempre dei codici macchina inseriti nei registri del nostro processore.

Con il comando 'r ax' inseriamo 0200 che sarebbe 02h in ah. ---> diciamo al processore che c'è da stampare un carattere su schermo.
Poi in dl inseriamo 41 ad esempio(da 00h a ffh), che indica il carattere ascii 'A',
quindi in dx inseriamo 0041 --- > Con questo passaggio abbiamo scelto il carattere
'A'.


Fatto questo dobbiamo comunicare al nostro microprocessore che stiamo usando una routine legata insieme al sistema operativo e non del bios. Quindi con il comando 'e
100' inseriamo in codice 'cd' e '21'. Il che vale a dire in assembler a 'int 21'. -----> int
sta per interrupt.


Di seguito chiudiamo il programma inserendo il codice esadecimanle 'cd' seguito da '20' con il comando 'e 102'.
Ed eseguiamo il tutto con 'g 104'. (Si usa 104 e non 102 perchè si devono racchiudere tutte le istruzioni siccome la 102 viene ancora eseguita mentre la 104 è esclusa!).

Così viene visualizzata la 'A', subito l'interlinea sotto 'g 102' e poi lo stato dei registri.
PS: assicuriamoci sempre che l'indirizzo ip sia uguale a 100h.


BATTIAMO IL TUTTO IN DEBUG:
-r ax -----> premiamo il tasto 'invio'
AX 0000
:0200 -----> premiamo il tasto 'invio'
-r dx -----> premiamo il tasto 'invio'
DX 0000
:0041 -----> premiamo il tasto 'invio'
-e 100 -----> premiamo il tasto 'invio'
14A0:0100 15.cd 9C.21 -----> premiamo il tasto di 'spazio' dopo il primo numero
e poi 'invio'
-e 102 -----> premiamo il tasto 'invio'
14A0:0102 18.cd 00.20 -----> premiamo il tasto di 'spazio' dopo il primo numero
e poi 'invio'
-
-g 104 -----> premiamo il tasto 'invio'
A -----> questo è il risultato.


L'esecuzione del programma è terminata normalmente
-
Il gioco è fatto!! questa è la nostra prima semplice applicazione in codice macchina! Ora se vogliamo digitare un'equivalente listato in assembly e sufficiente digitare 'a 100' e premere il tasto 'invio'.
Puntualizzo subito il significato in un comando frequentissimo nell' assembler : 'mov
x, y' . Questo comando in poche parole assegna un valore a un registro (es: ax) e lo sposta in esso.

 



Seconda parte

 



Nuova pagina 1


 

CREARE UNA RETE

Rete Peer To Peer

Rete client/server

Connettere due Pc

Lista completa

GUIDE PRATICHE

Partizionare l'HD

Comprimere i file

Recupero file

Formattazione

Statistiche

News nel tuo sito

Notizie dal web

Lista completa

 

 

Abbiamo cambiato indirizzo, troverai il nuovo sito all'url

manuali.tutorialpc.it

 

HOME PAGE   -   CONTATTI   -   COLLABORA   -  PRIVACY  -   HOSTING   -   DOMINI

© Copyright 2002-2011. Tutto il materiale che potete visionare in questo sito è dei rispettivi proprietari.

  Tutorialpc non si assume responsabilità per eventuali errori degli autori. 

Risoluzione consigliata 800x600 pixel