IL sistema binario

 

*** SISTEMA DECIMALE, BINARIO e ESADECIMALE ***

L'uomo e' abituato a ragionare in base 10, anche se poi e' andato ad inventare i secondi che sono 60 in un minuto che si ripete 60 volte in un ora... ecc... Il computer ragiona SOLO in base 2 (vi ricordate 1 e0...). Una via di mezzo tra uomo e macchina può essere il sistema esadecimale. Esso utilizza 16 simboli: 0 1 2 3 4 5 6 7 8 9 A B C D E F ed e' come vedremo molto più' compatto dei quello binario. Decimale. Base 10. 0 = 10^0*0 1 = 10^0*1 53 =10^1*5 + 10^0*3 106 = 10^2*1 + 10^1*0 + 10^0*6 Binario. Base 2. 0 = 2^0*0 = 0 1 = 2^0*1 = 1 53 =2^5*1 + 2^4*1 + 2^3*0 + 2^2*1 + 2^1*0 + 2^0*1 =110101 106 = 2^6*1 + 2^5*1 + 2^4*0 + 2^3*1 +2^2*0 + 2^1*1 + 2^0*1 = 1101010 Esadecimale .Base 16. 0 = 16^0*0 = 0 1 = 16^0*1 = 1 53 =16^1*3 + 16^0*5 = 35 106 = 16^1*6 + 16^0*A = 6A CONVERSIONE DI BASE Decimale --> binario, esadecimale Dividere il numero da convertire per la base in cui lo si vuole convertire. Moltiplicare il resto per la base, continuare fino ad arrivare allo 0. Es: Esadecimale 106/16 = 6,625 0.625*16 = A ( 10 = A in Hex) 6/16 = 0,375 0.375*16 = 6 107(dec) = 6B(hex) Binario 106/2 = 53 0 53/2 = 26.5 0.5*2 = 126/2 = 13 0 13/2 = 6.5 0.5*2 = 1 6/2 = 3 0 3/2 = 1.5 0.5*2 = 1 1/2 = 0.5 0.5*2 = 1 106(dec) = 1101010(bin) Esadecimale --> binario Spezzare il numero in parti da 4 bit. Convertire le parti secondo la seguente tabella: 0000 = 0 0100 = 4 1000 = 8 1100 = C 0001 = 1 0101 = 5 1001 = 9 1101 = D 0010 = 2 0110 = 6 1010 = A 1110 = E 0011 = 3 0111 = 7 1011 = B 1111 = F Es: 1000000000111101(bin) 1000 0000 0011 1101(bin) 8 0 3 D (hex) 803D(hex) *** BIT, BYTE, WORD e DWORD *** Un bit e' la più' piccola porzione di informazione che possiamo ottenere. Il bit puo' assumere valore 1 o 0. Per la CPU questi valori sono rappresentati da tensioni diverse: 0 = da 0 a 2.5V 1 = da 2.5 a 5V 8 bit formano un byte. Un byte puo' assumere fino a 2^8 = 256 valori diversi. 00000000 = 2^7*0 + 2^6*0 + 2^5*0 + 2^4*0 + 2^3*0 + 2^2*0 + 2^1*0 + 2^0*0 = 0 00100101 = 2^7*0 + 2^6*0 + 2^5*1 + 2^4*0 + 2^3*0 + 2^2*1 + 2^1*0 + 2^0*0 = 37 11111111 = 2^7*1 + 2^6*1 + 2^5*1 + 2^4*1 + 2^3*1 + 2^2*1 + 2^1*1 + 2^0*1 = 255 16 bit formano una word. Una word puo' assumere 2^16 =65.536 valori diversi. Le word di solito sono rappresentate da 4 cifre esadecimali. 0000 = 16^3*0 + 16^2*0 + 16^1*0 + 16^0*0 = 0 1A5D = 16^3*1 + 16^2*A + 16^1*5 + 16^0*D = 6.749 FFFF = 16^3*F + 16^2*F + 16^1*F + 16^0*F = 65.536 32 bit formano una dword. Una dword puo' assumere 2^32 = 4.294.967.296 valori. Le dword di solito sono rappresentate da 8 cifre esadecimali 00000000 = 16^7*0 + 16^6*0 + ... + 16^1*0 +16^0*0 = 0 FFFFFFFF = 16^7*F + 16^6*F + ... + 16^1*F + 16^0*F = 4.294.967.296

*** THE INTEL PROCESSOR ***

Tutta la famiglia dei processori Intel (x86) si basa ed e' compatibile con il primo processore di questo tipo: l'8086. L'8086 e' un processore a 16 bit quindi i suoi registri potranno contenere al massimo 16 bit di informazione. I processore più' moderni quali 80486, Pentium e Pentium II sono processori a 32 bit. Intel rilascerà' a meta del 2000 anche il Merced a 64 bit, ma fino allora tratteremo solo fino a registri a 32 bit. Quindi per poter conoscere come funziona un processore Pentium e' necessario partire dal suo bis-bis-nonno: 8086. La struttura interna dell'8086 si presenta grossomodo cosi: PROCESSOR RAM

------------------------------- ------------------------------- | | | | | |

------- ---------- | | Segmento | Segmento | | | | | Banco | | |

| | | | ALU | <---- | dei | | | Istruzioni | Dati | | | | ----> |

Registri | | | | | | ------- ---------- | -------------------------------

| ^| ^| | |^ |^ | || || | || || |

-|-----------------|-------------------|----------------|--> |

<----------------------------------------------------------- | | BUS

------------------------------- Il banco dei registri e' cosi'

suddiviso: ----------------- ------------------- | AH | AL | AX \

| IP | Instruction |-----------------| | | | Pointer | BH | BL |

BX | common |-------------------| |-----------------| | registers

| O D I T S Z A P C | Flags | CH | CL | CX |

------------------- |-----------------| | | DH | DL | DX /

|-----------------| | SI | \ |-----------------| | string registers |

DI | / |-----------------| | SP | \ |-----------------| | stack

registers | BP | / |-----------------| | CS | \ |-----------------| |

| DS | | |-----------------| | segment registers | ES | |

|-----------------| | | SS | / ----------------- AX, BX, CX, DZ

sono registri a 16 bit; AL e AH, ecc sono registri a 8

bit. Nei processori successivi al 80386 ci sono anche registri a 32 bit. La loro denominazione e' semplicissima: basta preporre una E sul registro desiderato. es: EAX, EBX. EBP, ESP, EIP, ecc. Vediamo ora a cosa servono i registri della cpu. AX...DX sono i registri comuni. Sono usati come accumulatori temporanei. SI e DI sono i registri per le stringhe. Essi sono usati per confrontare, copiare, spostare le stringhe. SP e BP sono i registri per lo stack. Lo stack e' un pila (LIFO) di dati. LIFO vuol dire Last In First Out. Per spiegarci meglio la coda che fate al supermercato e' FIFO (First In First Out) cioe' ilprimo che si mette in fila sara' il primo ad uscire. Lo stack e' il contrario: il primo che entra sara' l'ultimo ad uscire. Un po' come un cestino per la carta... quando lo svuoti le prime cose che escono sono le ultime che hai buttato. Il registro SP (Stack Poiter) punta all'ultimo elemento dello stack (quindi puntera' al pezzo di carta che hai buttato per ultimo). Per recuperare dati che si trovano in mezzo allo stack, basterà' spostare questo puntatore. Il registro BP punta alla base dello stack ed e' usato per i record di attivazione delle funzioni chiamate. CS...SS sono i registri di segmento. Vediamo che cosa e' un segmento. La memoria gestita da un 8086 e' divisa in blocchi da 64 Kb, poiché' puo' indirizzare solo 16 bit (2^16 = 65536 = 64 K). Il segmento rappresenta l'indirizzo del blocco utilizzato in quel momento. Per conoscere la posizione all'interno del segmento, si usa l'offset, rappresentato dal registro IP. Nei processori a 32 bit i valori cambiano... provate a calcolare quanto si puo' indirizzare.... cmq le cose si complica un po' e non e' questo l'intento del tutorial. Ecco in dettaglio i registri di segmento: CS Code segment. Contiene il codice da eseguire. DS Data segment. Contiene i dati da trattare: stringhe, variabili, ecc. ES come DS ma usato per confrontare le stringhe. SS Stack Segment. IP e' l'instruction pointer. Esso punta alla prossima istruzione che dovra' essere eseguita. Le Flags possono assumere valore 1 o 0 (on or off). C = Carry flag P = Parity flag A = Auxilary carry flag Z = Zero flag S = Sign flag (+ or -) O = Overflow flag I = Interrupt enable D = Direction flag T = Trap flag La piu' importante e' sicuramente la ZERO flag. Essa e' settata dopo ogni confronto. Assume il valore 0 oppure 1 a seconda del tipo di istruzione usata per effettuare il confronto. All'inizio abbiamo parlato delle istruzioni assembly. Vediamone ora il significato di alcune di esse. ** CALL ** Utilizzo: CALL destinazione Es.: CALL 004DF856 ---> esegue la sub 004DF856 subroutine: 004DF856 ... 004DF857 ... ....... 004DFA21 RET ---> ritorna all'istruzione successiva a CALL Esegue una subroutine alla "destinazione" e ritorna quando incontra RET. ** CMP ** Utilizzo : CMP registro1, registro2 CMP memoria, registro CMP registro, memoria Es.: CMP eax, ebx Confronta due registri e assegna il valore 1 al flag ZF (Zero Flag) se i registri sono uguali, altrimenti lascia 0. Varianti: CMPSB Sorgente e' messo in DS:SI e destinazione in ES:DI. CMPSW Come sopra solo che compara una word al posto di un byte. ** DEC **Utilizzo : DEC registro Es.: DEC eax Diminuisce di 1 il valore del "registro". (vedi anche INC). ** DIV ** Utilizzo : DIV registro1, registro2 Es.: DIV eax, 014 Divide registro1 per registro2. Il risultato viene >Es.: INC eax Aumenta di 1 il valore del "registro". (vedi anche DEC). ** INT ** Utilizzo : INT numero_dell_interrupt Es.: INT 21 Effettua una chiamata all' Interrupt desiderato. ** Jump ** Utilizzo: Jxx indirizzo Es.: Jxx 004056DE Esistono molti tipi di Jump e, a seconda del tipo le "xx" di Jxx cambieranno. Opcode Mnemonic Meaning Jump Condition 77 JA Jump if Above CF=0 and ZF=0 73 JAE Jump if Above or Equal CF=0 72 JB Jump if Below CF=1 76 JBE Jump if Below or Equal CF=1 or ZF=1 72 JC Jump if Carry CF=1 E3 JCXZ Jump if CX Zero CX=0 74 JE Jump if Equal ZF=1 7F JG Jump if Greater (signed) ZF=0 and SF=OF 7D JGE Jump if Greater or Equal (signed) SF=OF 7C JL Jump if Less (signed) SF != OF 7E JLE Jump if Less or Equal (signed) ZF=1 or SF!=OF JMP Unconditional Jump unconditional 76 JNA Jump if Not Above CF=1 orZF=1 72 JNAE Jump if Not Above or Equal CF=1 73 JNB Jump if Not Below CF=0 77 JNBE Jump if Not Below or Equal CF=0 and ZF=0 73 JNC Jump if Not Carry CF=0 75 JNE Jump if Not Equal ZF=0 7E JNG Jump if Not Greater (signed) ZF=1 or SF!=OF 7C JNGE Jump if Not Greater or Equal (signed) SF != OF 7D JNL Jump if Not Less (signed) SF=OF 7F JNLE Jump if Not Less or Equal (signed) ZF=0 and SF=OF 71 JNO Jump if Not Overflow (signed) OF=0 7B JNP Jump if No Parity PF=0 79 JNS Jump if Not Signed (signed) SF=0 75 JNZ Jump if Not Zero ZF=0 70 JO Jump if Overflow (signed) OF=1 7A JP Jump if Parity PF=1 7A JPE Jump if Parity Even PF=1 7B JPO Jump if Parity Odd PF=0 78 JS Jump if Signed (signed) SF=1 74 JZ Jump if Zero ZF=1 ** MOV ** Utilizzo: MOV destinazione, sorgente Es.: MOV eax, ebx Copia il valore di [sorgente] in [destinazione]. Varianti: MOVSB Sorgente e' messo in DS:SI e destinazione in ES:DI. MOVSW Come sopra solo che copia una word al posto di un byte. ** MUL ** Utilizzo : MUL registro1, registro2 Es.: MUL eax, 014 Moltiplica registro1 per registro2. Il risultato viene messo in registro1. ** NOP ** Utilizzo: NOP Es.: NOP Non esegue alcuna istruzione. (e allora a che serve??? Serve serve...) se devi eliminare una call, che fai ?? la cancelli ?? no ! Usi una NOP... ** POP ** Utilizzo : POP destinazione Es.: POP eax Toglie dallo stack l'ultimo elemento e lo mette in "destinazione". ** PUSH ** Utilizzo : PUSH sorgente Es.: PUSH eax PUSH 004056FD Mette in cima allo stack "sorgente". ** REP ** Utilizzo : REP Es.: REPZ CMPSW <--- istruzione ripetuta Ripete l'esecuzione di una istruzione su stringhe "while" CX != 0. Ad ogni passo CX e' decrementato di 1. Varianti REPE Es.: REPE CMPSB compara ogni byte in una stringa "while" sono uguali. REPZ Ripete "while" zero flag e' 0 (off) "while" ha lo stesso significato del C. quindi in italiano "while" CX != 0 si potrebbe tradurre "continua finche CX diventa 0" ** RET ** Utilizzo : RET Es.: RET Ritorna da una procedura. (vedi CALL) ** TEST ** Utilizzo : TEST destinazione, sorgente Es.: TEST eax, eax Esegue un AND logico tra destinazione e sorgente. Aggiorna i flag ma non salva il risultato .

 

 

Scarica il testo appena letto in formato ZIP

 

Se non hai WinZip puoi scaricarlo cliccando direttamente Qui