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