PDA

Visualizza versione completa : [TUTORIAL] nozioni base su assembler 8086



Knudson
04-08-2003, 19.00.58
Boh vediamo come me la cavo a scrivere tutorial (t'ho fregato foll, pensavi scherzassi :p ) (cazzo rido ? :notooth: )

DISCLAIMER : non so quanto tempo posso dedicarci, ne fino a dove le mie memorie scolastiche (non tocco assembler da 1 anno e mezzo in pratica) possano portarmi.

Innanzitutto:

Cos'e' l'assembler?

l'assembler e' il linguaggio piu' a basso livello dopo il linguaggio macchina (101001100...presente no?) : tramite assembler e' possibile fare praticamente tutto, ma dovete scordarvi tutte le comodita che i linguaggi ad alto livello ci hanno abituato : sara' gia' difficile visualizzare una stringa, quindi... ;)

Premesse:

In assembler sara' fondamentale conoscere la scrittura binaria e esadecimale : non tanto per la scrittura del programma in se, ma per il debug

Piccolo ripasso per chi non li conoscesse:

CODICE BINARIO:
2^ 2 2 2 2 <--- bit meno significativo
... D C B A

il valore in decimale e' -> A*2 + B*2 + Bn * 2^n

quindi il numero binario 100 diventa 0*2 + 0*2+1*2 -> 4

stessa cosa per l'esadecimale solo che

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 A B C D E F

abbastanza chiaro no? e poi tanto sono sicuro che lo conoscevate gia' :)

Innanzitutto (giusto per farvi mettere le manine pacioccose su un po' di codice), ecco come si presenta un ipotetico programma assembler 8086:

.MODEL SMALL
.STACK
.CODE

;cio' che segue un punto e virgola e' un commento
;gne
;gne
;gne
;

END

che cosa abbiamo qui?
innanzitutto con .MODEL diciamo al compilatore che tipo di modello di memoria vogliamo utilizzare (in questo caso usiamo SMALL, per applicazioni MOLTO complesse si arriva a usare il BIG o addirittura HUGE, ma penso che anoi SMALL basti :) )

.STACK invece dice al compilatore il tipo di stack da utilizzare (di default e' 100h)

ma cosa intendo per 100h? bhe ecco come vengono interpretati i numeri: 100b sarebbe 100 in BINARIO, con un 100h in HEX (esadecimale) ok?

Cos'e' lo stack a livello teorico? letteralmente pila, ovvero, il primo dato a entrare nella pila e' l'ultimo ad uscire (LIFO - Last in - first out) (in una coda sarebbe di tipo FIFO - first in - first out), ma di questo ne parliamo piu' avanti per la PUSH e la POP

tutto cio' che si trova tra .CODE e END e' il codice del programma

Dunque, in assembler potete pure scordarvi delle vostre belle variabili integer, float, char, ecc : qui le variabili le gestite voi tramite i registri : per semplicita', vediamoli pure come delle "scatole dove buttare i valori" (<-- premio per la peggior frase tecnica 2003)

ve ne sono diversi, vediamoli :

AX - (si divide in AH (high) e AL (low) - altresi' chiamato accumulatore, viene spesso utilizzato come destinazione dei calcoli matematici

BX - (BH,BL) - come sopra, viene spesso utilizzato anche come registro di offset

CX - (CH,CL) - viene spesso utilizzato come contatore (l'istruzione LOOP ad esempio, decrementa di default ilv alore di CX finche' non raggiunge zero)

DX - (DH,DL) - solitamente si usa come "contenitore per il resto delle divisioni" o come puntatore nelle operazioni di I/O

da notare che nulla vi vieta di usare ad esempio CX per operazioni matematiche : sta poi a voi gestire eventuali flag, resti ecc

BP - base pointer -> punta alla base dello stack
DS - data segment -> puntatore, punta alla base della zona di memoria destinata a contenere i nostri dati
SS - stack segment -> il mio preferito, punta alla zona di memoria dello stack - spippolare con questo e' bello soprattutto per fare danni :D
ES - extra segment -> la pattumiera, ci buttate quello che volete (almeno io l'ho sempre usato cosi')
IP - instruction pointer -> puntatore, punta alla prossima operazione da eseguire

Ora parliamo dei flag e del registro di flag:
un flag (bandiera) puo' essere o 0 o 1 (falso o vero) e rappresenta una determinata cosa:

il piu' importante e' il flag di carry (CF) :

Il carry (riporto) indica se durante l'ultima operazione e' avvenuto un riporto sul bit piu' significativo (nel qual caso viene settato a 1, altrimenti viene settato a 0).
Operazioni come ADD, SUB, CMP, ROL e ROR settano il flag di carry a 1, mentre operatori
logici quali AND , OR e XOR lo settano a 0.

Da notare che INC e DEC non modificano il carry :

;carry all'inizio = 1
mov ax,11111111b
add ax,1

In questo caso il carry viene portato a 1

;carry all'inizio = 0
mov ax,11111111b
inc ax

In questo caso il carry non viene toccato e quindi rimane a 0.
Analogamente, con SUB :

mov ax,0
sub ax,1

il carry viene portato a 1

mov ax,0
dec ax

il carry non viene toccato

per oggi basta che senza appunti davanti e' dura :D