BX turbo
Transcript
BX turbo
Famiglia x86 8086-88, 80186, 80286, 80386-386SX, 80486DX-SX, Pentium,P6 Linguaggio Assembler Programmazione in linguaggi alto livello (HLL), p. es. Pascal: + livello di astrazione (istruzioni più potenti) + chiarezza, leggibilità, concisione + correttezza, modificabilità, manutenzione + portabilità (attraverso compilatori per ambienti diversi) Programmazione in linguaggio macchina: - inferiore secondo i criteri precedenti; p.es. che vuol dire: 001010111000011100010111001000101110100000000000000000 + controllo sulla macchina → efficienza (memoria-tempo). Linguaggio assembler: corr. quasi 1-1 con linguaggio macchina, ma + leggibile (mnemonici per istruzioni, simboli per dati). P. es.: sub ax,cx mov cx,ax mov dx,0 ; istruzioni corrispondenti alla ; sequenza di bit ; più in alto Assembler è il programma traduttore da l. assembler a l. macchina All’assembler vanno preferiti gli HLL tranne che per: 1. sistemi real-time, p.es. controllo di processi 2. controllo fine di hardware, p.es. device driver, kernel SO 3. routine critiche per l’efficienza (in particolare nei casi 1,2) Elementi dell’architettura x86 - 15/11/99 12.19 1/10 Formati e memorizzazione dei dati binari Bit, nibble (semibyte), byte, word (=2byte), doubleword, quadword. In genere questi dati si disegnano in orizzontale, numerando i bit da destra (bit 0, LSB=Least Significant Bit) a sinistra (MSB=Most SB) Lo stesso vale per i byte all’interno di word, etc.. P.es. una word: 15 8 7 0 high byte low byte La memoria si pensa come una sequenza di (celle contenenti 1) byte Ogni byte è numerato da 0 in su, con interi detti indirizzi. Per convenzione, i byte si disegnano con indirizzi crescenti dall’alto in basso e, se si sfruttano pure le righe, da sinistra a destra: Rappresentazione della memoria CD 20 Output Turbo Debugger 0H 1H Indirizzi Byte in Hex Ascii 0FFFFFH 1M = 2^20=16^5 =100000H Una word di byte basso e alto si memorizza in 2 byte consecutivi p.es. di indirizzi n,n+1; si dice allora che l’indirizzo della word è n; NB: le word n e n+1 si sovrappongono per il byte n+1; p.es. word0=(0,1), word1=(1,2) Tutte le nozioni introdotte valgono per ogni architettura/CPU, ma: 1. quelle big-endian pongono nel byte n e nel byte n+1. 2. quelle little-endian, tra cui l’80x86, pongono in n e in n+1; P.es. nel riquadro (x86), le word di indirizzi e sono e . Per l’x86, si dice paragrafo un gruppo di 16= byte consecutivi di cui il primo ha indirizzo multiplo di (terminante per ). Esempio: i byte costituiscono un paragrafo, Elementi dell’architettura x86 - 15/11/99 12.19 no. 2/10 Dati numerici in Turbo Assembler • sequenza di cifre, non iniziante per lettera ( • terminata dal simbolo della base: , Esempi: , , , , , o non ), e (default). (errore:default base 10), (errore: 3) Prime istruzioni / Registri AX, BX, CX, DX Alcune istruzioni simboliche con operandi dati immediati e registri “generali” a 16/8 bit: ( , ), ( , ), ( , ), ( , ) mov add sub inc mul reg,dato reg,dato reg,dato reg reg ; ; ; ; ; ! reg:= dato reg:= reg+dato reg:= reg-dato reg:= reg+1 dx,ax := ax*reg ! " " ! " ! Dove: reg è uno tra AX, AL, AH, BX ... dato è numerico o come reg reg e dato hanno = ampiezza NB: AH (registro)≠0AH (numero) Esempi (con istruzioni simboliche e binarie, per la CPU): Istruzioni CPU B80510 BB1000 2D0200 F7E3 050100 40 B9AB23 80C501 Istruz. simboliche mov ax,1005H mov bx,0010H sub ax,0002H mul bx add ax,1 inc ax mov cx,23ABH add ch,01 Elementi dell’architettura x86 - 15/11/99 12.19 Osservazioni ; le istr. CPU andranno poste in celle ; di memoria, quindi le word in esse ; hanno i byte scambiati! (x86 l.end.) ; NB: a ax si somma la word 0001, non 1 ; 1 byte: stesso effetto dei 3 di add ax,1 ; adesso ch vale 24 3/10 # $ % Registri di stato: * + , - & ' e ( ) . ha 16 bit o flag: i flag 1,3,5,15 sono unused; 12,13,14 servono per il multitasking; gli altri riflettono il risultato dell’ultima operazione: 0 (CF) carry flag ( sse il MSB del risultato dà luogo a un riporto) NB: sse = “se e solo se” / mov al,0ffH add al,3H ; al diventa 02 e si riporta 1, CF viene posto a 1 2 (PF) parity flag ( sse gli 8 bit meno significativi del risultato contengono un numero pari di bit 1) 4 (AF) auxiliary (o adjust) flag ( sse i bit 3,2,1 o 0 danno un riporto; serve per certe operazioni aritmetiche) 6 (ZF) zero flag ( sse il risultato è 0) 7 (SF) sign flag ( sse il risultato è <0, → SF=MSB del risultato) 8 (TF) trap flag (usato per il debugging) 9 (IF) interrupt flag ( sse interrupt abilitato) / / / / / 10 (DF) direction flag (usato per operazioni su stringhe) 11 (OF) overflow flag ( sse il risultato è un signed troppo grande in valore assoluto per essere rappresentato). / (Instruction Pointer) è un registro a 16 bit; al power-on va a ; dopo ogni istruzione non salto di L byte risulta incrementato di L; (l’effetto dei salti su è più complesso) 0 1 2 0 2 2 2 1 In ogni caso, , insieme a , specifica l’indirizzo di memoria della prossima istruzione da eseguire (vedi oltre). 0 1 3 Elementi dell’architettura x86 - 15/11/99 12.19 4 4/10 Memoria segmentata L’8086 ha 20 pin ( ) su cui pone l’indirizzo a 20 bit (5 cifre hex) del byte di memoria cui vuole accedere tra i 220=1M byte indirizzabili. 5 6 7 5 8 9 Segmento: sequenza di 64kb consecutivi allineati con un paragrafo, cioè di indirizzo iniziale della forma in esadecimale. : ; < = 6 I 16 bit si dicono (indirizzo del) segmento; individuano 1 di 216=64K segmenti distinti, ma non disgiunti (vedi p.es. i segmenti , ). : ; < = > ? 5 @ > ? A @ Un byte in un segmento è individuato da un indirizzo detto offset (distanza) dalla base del segmento; l’offset richiede 16 bit (è < 64k). NB: i progettisti volevano indirizzi di segmento ed offset esattamente di 2 byte. Un byte di indirizzo a 20 bit I si trova in più segmenti; quindi è individuato dalle coppie segmento-offset S,O per cui I=O+S× Memoria Indirizzi fisici C D E E segmento:offset E C D E G H I J K L D E B E K L M K L M E R E R E M C D C G E E O P K L J M N H I O M C Q M C F E P C C 6 (segmentox16)+offset segment 1500 C 8 E G H I E E M C Q M seg. 168F F G H I E C J K L M Nel seguito si denota con l’indirizzo segmentato della cella all’offset del segmento , e con la cella stessa. S T U U S S T V U W L’hw della BIU (Bus Interface Unit) genera l’indirizzo fisico 1 byte Z [ 1 byte 5 6 7 5 X così: Y 1/2 byte Z [ registro di segmento + NB: l’esecuzione delle istruzioni causa gli accessi alla memoria via \ offset (2 byte) A19 Elementi dell’architettura x86 - 15/11/99 12.19 = A0 ] ^ \ _ ` La causa dell’accesso determina offset e registro di segmento impiegati. 5/10 Memoria segmentata, registri di segmento, istruzioni Ogni accesso a memoria è effetto dell’esecuzione di un’istruzione. L’indirizzo su è calcolato dalla CPU a partire da un offset e un registro di segmento tra , , , a b c d a e f g h g i g g g Offset e registro di segmento coinvolti dipendono dalla relazione tra: • tipo di accesso alla memoria • istruzione che causa l’accesso L’esecuzione di un’istruzione I0 causa il prelievo della successiva I determinata come segue: • I0 modifica i registri • a NB: b c d a e f g (Code Segment) e j (Instruction Pointer) k di I sono generati dal segmento in f e dall’offset in g j k o e ; I0 salto cambia opportunamente di L. I0 non salto, lunga L byte, accresce j k f j g j k k Le istruzioni specifiche per lo stack (p.es. , ) generano indirizzi fisici nello stack usando (Stack Segment). l g Elementi dell’architettura x86 - 15/11/99 12.19 m n o l p l g 6/10 Memoria segmentata, istruzioni e operandi Un’istruzione I può avere una locazione come operando; p.es. mov al,[12fbH] ; copia in al il byte di offset 12fb e segmento??? L’esecuzione di I genera q r • l’offset specificato da I ( r s t v q della locazione-operando usando: u w x y nell’esempio) e • il registro di segmento definito implicitamente, come segue. Caso 1: registro di segmento definito esplicitamente, da un prefisso dell’istruzione I detto di segment override: 26A0fb12 mov al,ES:[12fb] ; il s. override prefix 26 indica ES Caso 2: registro di segmento definito implicitamente (se l’istruzione I non ha prefisso) come segue: • z se I usa z 8A4604 • • | per specificare l’offset dell’operando; p.es.: mov al,[bp+4] ; al:= SS:[bp+4] z z (Extended Seg.) per l’operando destinazione di I su stringhe } ~ { (Data Segment) in tutti gli altri casi; p.es.: A0fb12 mov al,[12fb] Elementi dell’architettura x86 - 15/11/99 12.19 ; al:= DS:[12fb] cf. con 26A0fb12 7/10 Registri e Offset Più esattamente, dato un oggetto da indirizzare, si hanno queste possibili relazioni tra registro di segmento e specifica dell’offset: Oggetto Registro segmento Istruzione Dato di programma Dato in stack Stringa destinazione Elementi dell’architettura x86 - 15/11/99 12.19 Specifica offset esplicito o , o o 8/10 Memoria segmentata: pro e contro Critiche alla memoria segmentata x86: • complicazione concettuale rispetto alla memoria piatta • aggravio sulle prestazioni per il calcolo dell’indirizzo fisico (di fatto avviene in parallelo ad altre attività, quindi incide poco). Vantaggi tenuti in conto dai progettisti dell’8086 1. backward compatibility con il software per la CPU 8080 (l’8080 aveva indirizzi fisici a 16 bit); 2. istruzioni più brevi (contengono indirizzi a 16 anziché a 20 bit); 3. memoria indirizzabile > 64K pur con registri di indirizzi a 16 bit (all’epoca, il n. max di transistor su un chip era limitato); 4. il programmatore ha a disposizione una memoria composta, concettualmente, di segmenti distinti. NB: in realtà assembler/linker scelgono: • per i vari segmenti “logici” definiti dal programmatore • segmenti di memoria anche non disgiunti per tutti i 64K, ma solo per le parti iniziali effettivamente occupate Di fatto quindi i segmenti logici in cui è organizzato un programma: • sono logicamente distinti e disgiunti • questa proprietà è assicurata dall’uso ordinato della memoria, • ma non è una proprietà dell’architettura/memoria virtuale 8086 Elementi dell’architettura x86 - 15/11/99 12.19 9/10 Memoria segmentata e software Da (4) conseguono ulteriori importanti vantaggi per il software x86: • dati e istruzioni possono stare in segmenti diversi (se Indirizzo Istr. CS:0000 Istr. bin A20000 Istr. simbolica mov [0000],al ≠ ) ;modifica DS:[0], non CS:[0] • possibilità di distribuire dati e istruzioni tra più segmenti; p.es.: mov mov mov mov mov al,[20] ah,ES:[30] ax,1f3a ds,ax al,[20] ; ; ; ; ; operando all’offset 20 nel segmento in DS operando all’offset 30 nel segmento in ES 1f3a sarà il prossimo segmento per i dati NB: mov ds,1f3a è illegale ds:[20] non è, in generale, quello di prima • programmi rilocabili (caricabili ovunque senza modifiche); p.es.: Programma binario da caricare in memoria ¢ ¢ ¢ ¢ caricamento con modifica caricamento senza modifica Il programma vuole scrivere sul byte [0] ma si può caricare solo da [5640] Memoria piatta Memoria segmentata x86 ¡ Esempio: configurazione tipica di un programma in esecuzione. 96000 9600 CS B12F DS 64K B12F0 B12F SS 64K Elementi dell’architettura x86 - 15/11/99 12.19 10/10