Ricerca…


Registri a 16 bit

Quando Intel ha definito l'8086 originale, era un processore a 16 bit con un bus indirizzo a 20 bit (vedere sotto). Hanno definito 8 registri a 16 bit generici, ma hanno assegnato loro ruoli specifici per determinate istruzioni:

  • AX Il registro Accumulatore.
    Molti opcode hanno assunto questo registro o erano più veloci se specificato.
  • DX Il registro dei dati.
    A volte questo è stato combinato con i 16 bit alti di un valore a 32 bit con AX , ad esempio come risultato di un multiplo.
  • CX Il registro dei conteggi.
    Questo è stato utilizzato in una serie di istruzioni orientate al ciclo come contatore implicito per tali cicli - ad esempio LOOPNE (ciclo se non uguale) e REP (spostamento / confronto ripetuto)
  • BX Il registro di base.
    Questo potrebbe essere usato per indicizzare la base di una struttura in memoria - nessuno dei registri precedenti potrebbe essere usato per indicizzare direttamente nella memoria.
  • SI Il registro dell'indice di origine.
    Questo era l'indice implicito della fonte in memoria per determinate operazioni di spostamento e confronto.
  • DI Il registro dell'indice di destinazione.
    Questo era l'indice di destinazione implicito nella memoria per determinate operazioni di spostamento e confronto.
  • SP Il registro del puntatore dello stack.
    Questo è il registro meno generico nel set! Indicava la posizione corrente nello stack, che era utilizzata esplicitamente per le operazioni PUSH e POP , implicitamente per CALL e RET con subroutine e MOLTO implicitamente durante gli interrupt. Come tale, usarlo per qualsiasi altra cosa era pericoloso per il tuo programma!
  • BP Il registro del puntatore di base.
    Quando le subroutine chiamano altre subroutine, lo stack contiene più "stack frames". BP poteva essere usato per mantenere il frame dello stack corrente, e quando veniva chiamata una nuova subroutine, doveva essere salvata sullo stack, il nuovo stack frame creato e usato, e al ritorno dalla subroutine interna il vecchio valore del frame dello stack poteva essere ripristinato .

Gli appunti:

  1. I primi tre registri non possono essere utilizzati per l'indicizzazione in memoria.

  2. BX , SI e DI per indice di default nel segmento dati corrente (vedi sotto).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. DI , quando utilizzato in operazioni da memoria a memoria come MOVS e CMPS , utilizza esclusivamente il segmento aggiuntivo (vedere sotto). Questo non può essere ignorato.

  4. SP e BP utilizzano il segmento di stack (vedi sotto) per impostazione predefinita.

Registri a 32 bit

Quando Intel ha prodotto l'80386, è passato da un processore a 16 bit a uno a 32 bit. L'elaborazione a 32 bit significa due cose: entrambi i dati manipolati erano a 32 bit e gli indirizzi di memoria a cui si stava accedendo erano a 32 bit. Per fare ciò, ma rimangono comunque compatibili con i processori precedenti, hanno introdotto nuove modalità per il processore. Era in modalità a 16 bit o in modalità a 32 bit, ma era possibile ignorare questa modalità in base alle istruzioni per i dati, l'indirizzamento o entrambi!

Prima di tutto, hanno dovuto definire registri a 32 bit. Lo hanno fatto semplicemente estendendo gli otto esistenti da 16 bit a 32 bit e dando loro nomi "estesi" con un prefisso E : EAX , EBX , ECX , EDX , ESI , EDI , EBP ed ESP . I 16 bit inferiori di questi registri erano gli stessi di prima, ma le metà superiori dei registri erano disponibili per operazioni a 32 bit come ADD e CMP . Le metà superiori non erano accessibili separatamente come avevano fatto con i registri a 8 bit.

Il processore doveva disporre di modalità separate a 16 e 32 bit perché Intel utilizzava gli stessi codici opzionali per molte delle operazioni: CMP AX,DX in modalità a 16 bit e CMP EAX,EDX in modalità a 32 bit aveva esattamente gli stessi opcode ! Ciò significava che lo stesso codice NON poteva essere eseguito in nessuna delle due modalità:

L'opcode per "Sposta immediatamente in AX " è 0xB8 , seguito da due byte del valore immediato: 0xB8 0x12 0x34

L'opcode per "Sposta immediatamente in EAX " è 0xB8 , seguito da quattro byte del valore immediato: 0xB8 0x12 0x34 0x56 0x78

Quindi l'utente deve sapere in quale modalità si trova il processore durante l'esecuzione del codice, in modo che sappia emettere il numero corretto di byte.

Registri a 8 bit

I primi quattro registri a 16 bit potevano avere i loro byte superiore e inferiore a cui si accede direttamente come propri registri:

  • AH e AL sono le metà alta e bassa del registro AX .
  • BH e BL sono le metà alta e bassa del registro BX .
  • CH e CL sono le metà alta e bassa del registro CX .
  • DH e DL sono le metà alta e bassa del registro DX .

Nota che questo significa che alterare AH o AL modificherà immediatamente anche AX ! Si noti inoltre che qualsiasi operazione su un registro a 8 bit non può influenzare il suo "partner" - l'incremento di AL tale che esso trabocchi da 0xFF a 0x00 non altera AH .

I registri a 64 bit hanno anche versioni a 8 bit che rappresentano i loro byte più bassi:

  • SIL per RSI
  • DIL per RDI
  • BPL per RBP
  • SPL per RSP

Lo stesso vale per i registri da R8 a R15 : le rispettive parti di byte inferiori sono denominate R8B - R15B .

Registri di segmento

Segmentazione

Quando Intel stava progettando l'8086 originale, c'erano già un certo numero di processori a 8 bit con capacità a 16 bit, ma volevano produrre un vero processore a 16 bit. Volevano anche produrre qualcosa di meglio e più capace di ciò che era già là fuori, quindi volevano essere in grado di accedere a più del massimo di 65.536 byte di memoria impliciti dai registri di indirizzamento a 16 bit.

Registri originali del segmento

Così hanno implementato l'idea di "Segmenti" - un blocco di memoria di 64 kilobyte indicizzato dai registri degli indirizzi a 16 bit - che potrebbe essere ri-basato per indirizzare diverse aree della memoria totale. Per contenere queste basi di segmenti, hanno incluso i registri di segmento:

  • CS Il registro del segmento di codice.
    Ciò mantiene il segmento del codice attualmente in esecuzione, indicizzato dal registro IP implicito (Puntatore di istruzioni).
  • DS Il registro dei segmenti di dati.
    Questo contiene il segmento predefinito per i dati manipolati dal programma.
  • ES Il registro dei segmenti extra.
    Questo contiene un secondo segmento di dati, per operazioni simultanee di dati attraverso la memoria totale.
  • SS Il registro del segmento di stack.
    Questo contiene il segmento di memoria che contiene lo stack corrente.

Dimensione del segmento?

I registri di segmento potevano essere di qualsiasi dimensione, ma rendendoli larghi 16 bit rendeva facile l'interoperabilità con gli altri registri. La prossima domanda era: i segmenti dovrebbero sovrapporsi e, in caso affermativo, quanto? La risposta a questa domanda determinerebbe la dimensione totale della memoria a cui si potrebbe accedere.

Se non ci fosse sovrapposizione, lo spazio di indirizzamento sarebbe 32 bit - 4 gigabyte - una dimensione inaudita in quel momento! Una sovrapposizione più "naturale" di 8 bit produrrebbe uno spazio di indirizzamento a 24 bit o 16 megabyte. Alla fine, Intel ha deciso di salvare altri quattro pin di indirizzo sul processore, rendendo lo spazio di indirizzamento di 1 megabyte con una sovrapposizione di 12 bit: lo consideravano sufficientemente grande per il tempo!

Più registri di segmenti!

Quando Intel stava progettando l'80386, ha riconosciuto che la suite esistente di 4 registri segmenti non era sufficiente per la complessità dei programmi che volevano che fosse in grado di supportare. Quindi hanno aggiunto altri due:

  • FS Il registro del segmento lontano
  • GS Il registro dei segmenti globali

Questi nuovi registri di segmento non avevano alcun utilizzo forzato dal processore: erano semplicemente disponibili per qualsiasi cosa il programmatore volesse.

Alcuni dicono che i nomi sono stati scelti per continuare semplicemente il tema C , D , E del set esistente ...

Registri a 64 bit

AMD è un produttore di processori che aveva concesso in licenza il design dell'80386 di Intel per produrre versioni compatibili, ma in competizione. Hanno apportato modifiche interne al design per migliorare il throughput o altri miglioramenti del design, pur essendo ancora in grado di eseguire gli stessi programmi.

Per Intel one-up, hanno creato estensioni a 64 bit per il design Intel a 32 bit e hanno prodotto il primo chip a 64 bit che poteva ancora eseguire codice x86 a 32 bit. Intel ha finito per seguire il design di AMD nelle loro versioni dell'architettura a 64 bit.

Il design a 64 bit ha apportato una serie di modifiche al set di registri, pur rimanendo compatibile con le versioni precedenti:

  • I registri general purpose esistenti sono stati estesi a 64 bit e denominati con un prefisso R : RAX , RBX , RCX , RDX , RSI , RDI , RBP e RSP .

    Di nuovo, le metà inferiori di questi registri erano gli stessi registri E prefisso di prima, e le metà superiori non potevano essere accessibili in modo indipendente.

  • Altri 8 registri a 64 bit sono stati aggiunti e non nominati ma semplicemente numerati: R8 , R9 , R10 , R11 , R12 , R13 , R14 e R15 .
    • La metà inferiore di 32 bit di questi registri è da R8D a R15D (D per DWORD come al solito).
    • È possibile accedere ai 16 bit più bassi di questi registri con il suffisso di una W al nome del registro: da R8W a R15W .
  • Ora è possibile accedere agli 8 bit più bassi di tutti i 16 registri:
    • Il tradizionale AL , BL , CL e DL ;
    • I byte bassi dei registri puntatori (tradizionalmente): SIL , DIL , BPL e SPL ;
    • E i byte bassi degli 8 nuovi registri: da R8B a R15B .
    • Tuttavia, AH , BH , CH e DH sono inaccessibili nelle istruzioni che utilizzano un prefisso REX (per dimensioni di operando a 64 bit o per accedere a R8-R15 o per accedere a SIL , DIL , BPL o SPL ). Con un prefisso REX, il pattern a bit del codice macchina che in genere significa AH indica SPL e così via. Vedere la Tabella 3-1 del manuale di riferimento delle istruzioni di Intel (volume 2).

Scrivendo su un registro a 32 bit si azzerano sempre i 32 bit superiori del registro a larghezza intera, diversamente dalla scrittura in un registro a 8 o 16 bit (che si fonde con il vecchio valore, che è una dipendenza extra per l'esecuzione fuori ordine ).

Registro delle bandiere

Quando l'unità logica aritmetica x86 (ALU) esegue operazioni come NOT e ADD , contrassegna i risultati di queste operazioni ("diventato zero", "overflow", "diventato negativo") in uno speciale registro FLAGS 16 bit. I processori a 32 bit l'hanno aggiornato a 32 bit e lo hanno chiamato EFLAGS , mentre i processori a 64 bit l'hanno aggiornato a 64 bit e lo hanno chiamato RFLAGS .

Codici di condizione

Ma non importa il nome, il registro non è direttamente accessibile (eccetto per un paio di istruzioni - vedi sotto). Invece, i singoli flag sono referenziati in alcune istruzioni, come il salto condizionale o il Set condizionale, noto come Jcc e SETcc dove cc significa "codice di condizione" e fa riferimento alla seguente tabella:

Codice di stato Nome Definizione
E , Z Uguale, zero ZF == 1
NE , NZ Non uguale, non zero ZF == 0
O straripamento OF == 1
NO No Overflow OF == 0
S firmato SF == 1
NS Non firmato SF == 0
P Parità PF == 1
NP Nessuna parità PF == 0
-------------- ---- ----------
C , B , NAE Carry, Below, Not Above or Ugual CF == 1
NC , NB , AE No Carry, Not Below, Above or Ugual CF == 0
A , NBE Sopra, non sotto o uguale CF == 0 e ZF == 0
NA , BE Non sopra, sotto o uguale CF == 1 o ZF == 1
--------------- ---- ----------
GE , NL Maggiore o uguale, non minore SF == OF
NGE , L Non maggiore o uguale, meno SF ! = OF
G , NLE Maggiore, non minore o uguale ZF == 0 e SF == OF
NG , LE Non maggiore, minore o uguale ZF == 1 o SF ! = OF

In 16 bit, sottrarre 1 da 0 è 65,535 o -1 seconda che venga utilizzata l'aritmetica non firmata o firmata, ma la destinazione mantiene 0xFFFF entrambi i casi. È solo interpretando i codici di condizione che il significato è chiaro. È ancora più significativo dire se 1 è sottratto da 0x8000 : in aritmetica senza segno, questo semplicemente cambia 32,768 in 32,767 ; mentre in aritmetica firmata cambia -32,768 in 32,767 - un overflow molto più degno di nota!

I codici di condizione sono raggruppati in tre blocchi nella tabella: segno-irrilevante, non firmato e firmato. La denominazione all'interno di questi ultimi due blocchi utilizza "Sopra" e "Sotto" per i non firmati e "Maggiore" o "Meno" per i firmati. Quindi JB sarebbe "Jump if Below" (senza segno), mentre JL sarebbe "Jump if Less" (firmato).

Accesso diretto ai FLAGS

I suddetti codici di condizione sono utili per interpretare concetti predefiniti, ma i bit di flag attuali sono anche disponibili direttamente con le seguenti due istruzioni:

  • LAHF carica il registro AH con le bandierine
  • SAHF Store AH registrati in Flags

Solo alcune bandiere vengono copiate con queste istruzioni. L'intero registro FLAGS / EFLAGS / RFLAGS può essere salvato o ripristinato nello stack:

  • PUSHF / POPF push / pop a 16 bit FLAGS sui / dai la pila
  • PUSHFD / POPFD Push / pop a 32 bit EFLAGS sui / dai la pila
  • PUSHFQ / POPFQ push / pop a 64 bit RFLAGS sulla / dalla pila

Notare che interrompe il salvataggio e ripristina automaticamente il registro [R/E]FLAGS corrente.

Altre bandiere

Oltre ai flag ALU descritti sopra, il registro FLAGS definisce altri flag di stato del sistema:

  • IF la bandiera di interruzione.
    Questo viene impostato con l'istruzione STI per abilitare globalmente gli interrupt e cancellato con l'istruzione CLI per disabilitare globalmente gli interrupt.
  • DF La bandiera di direzione.
    Le operazioni da memoria a memoria come CMPS e MOVS (per confrontare e spostarsi tra le posizioni di memoria) aumentano o diminuiscono automaticamente i registri indice come parte dell'istruzione. Il flag DF indica quale succede: se cancellato con l'istruzione CLD , vengono incrementati; se impostati con l'istruzione STD , vengono decrementati.
  • TF The Trap Flag. Questa è una bandiera di debug. Impostandolo si metterà il processore in modalità "single-step": dopo l'esecuzione di ogni istruzione, chiamerà il "Single Step Interrupt Handler", che dovrebbe essere gestito da un debugger. Non ci sono istruzioni per impostare o cancellare questo flag: è necessario manipolare il bit mentre è in memoria.

80286 bandiere

Per supportare le nuove strutture di multitasking nell'80286, Intel ha aggiunto ulteriori flag al registro FLAGS :

  • IOPL Il livello di privilegio I / O.
    Per proteggere il codice multitasking, alcune attività necessitavano di privilegi per accedere alle porte I / O, mentre altre dovevano essere fermate per accedervi. Intel ha introdotto una scala Privilege a quattro livelli, con 00 2 il più privilegiato e 11 2 il meno. Se IOPL era inferiore al livello di privilegio corrente, qualsiasi tentativo di accedere alle porte I / O o abilitare o disabilitare le interruzioni causerebbe invece un errore di protezione generale.
  • NT Nested Task flag.
    Questo flag è stato impostato se una Task CALL e un'altra Task, che ha causato un cambio di contesto. Il flag impostato indicava al processore di eseguire un cambio di contesto quando veniva eseguito il RET .

80386 bandiere

Il 386 aveva bisogno di bandiere aggiuntive per supportare funzionalità extra progettate nel processore.

  • RF La bandiera di ripresa.
    Il `386 ha aggiunto i registri di debug, che potevano richiamare il debugger su vari accessi hardware come leggere, scrivere o eseguire una determinata posizione memry. Tuttavia, quando il gestore debug ritornava per eseguire l'istruzione, l'accesso richiamava immediatamente il gestore debug! O almeno lo sarebbe se non fosse per il Flag di Resume, che viene automaticamente impostato in entrata nel gestore di debug e automaticamente cancellato dopo ogni istruzione. Se il Flag di ripresa è impostato, il gestore di debug non viene richiamato.
  • VM La bandiera virtuale 8086.
    Per supportare il vecchio codice a 16 bit e il nuovo codice a 32 bit, l'80386 poteva eseguire attività a 16 bit in modalità "Virtual 8086", con l'aiuto di un dirigente Virtual 8086. Il flag VM indicava che questa attività era un'attività virtuale 8086.

80486 bandiere

Con il miglioramento dell'architettura Intel, è diventato più veloce grazie a tecnologie come le cache e l'esecuzione super-scalare. Questo doveva ottimizzare l'accesso al sistema facendo delle ipotesi. Per controllare queste ipotesi, erano necessarie più bandiere:

  • Flag di allineamento AC L'architettura x86 può sempre accedere a valori di memoria multi-byte su qualsiasi limite di byte, a differenza di alcune architetture che richiedono che siano allineati in base alla dimensione (i valori a 4 byte devono essere presenti su contorni a 4 byte). Tuttavia, era meno efficiente farlo, poiché erano necessari più accessi di memoria per accedere ai dati non allineati. Se è stato impostato il flag AC , un accesso non allineato genererebbe un'eccezione anziché eseguire il codice. In questo modo, il codice potrebbe essere migliorato durante lo sviluppo con l' AC set, ma disattivato per il codice di produzione.

Pentium Flags

Il Pentium ha aggiunto più supporto per la virtualizzazione, oltre al supporto per l'istruzione CPUID :

  • VIF Il flag di interrupt virtuale.
    Questa è una copia virtuale IF di questa attività, indipendentemente dal fatto che questa attività desideri disattivare gli interrupt, senza influire effettivamente sugli interrupt globali.
  • VIP The Virtual Interrupt Pending Flag.
    Ciò indica che un interrupt è stato virtualmente bloccato da VIF , quindi quando l'attività esegue una STI può essere generato un interrupt virtuale per esso.
  • ID Il flag CPUID -allowed.
    Se consentire o meno a questa attività di eseguire l'istruzione CPUID . Un monitor virtuale potrebbe non permetterlo e "mentire" con l'attività richiedente se esegue l'istruzione.


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow