Assembler - Adressierungsarten

Transcription

Assembler - Adressierungsarten
Assembler - Adressierungsarten
Dr.-Ing. Volkmar Sieh
Department Informatik 3: Rechnerarchitektur
Friedrich-Alexander-Universität Erlangen-Nürnberg
SS 2008
logo
Assembler - Adressierungsarten– 1/31– 2008-04-01
Adressierungsarten – Einführung
Beispiel (C, C++, Java):
i n t a , ∗b , c [ 1 0 ] ;
s t r u c t { char y ; i n t x ; i n t ∗p } d , ∗ e , f [ 5 ] ;
. . . = 13;
...
...
...
...
...
...
=
=
=
=
=
=
a;
∗b ;
c[ i ];
d.x;
e−>x ;
f [ i ]. x;
a = ...;
∗b = . . . ;
c[ i ] = ...;
d.x = ...;
e−>x = . . . ;
f [ i ]. x = ...;
... und Kombinationen davon:
c [ f [ e−>x ] . y ] = . . . ;
∗ f [∗ b ] . p = . . . ;
Assembler - Adressierungsarten– 2/31– 2008-04-01
logo
Adressierungsarten – effektive Adresse
Bei vielen Adressierungsarten wird eine sogenannte „effektive
Adresse” dynamisch zur Laufzeit berechnet.
Gründe (Beispiele):
Basisadresse einer Datenstruktur fest, Index variabel (z.B.
beim Array-Zugriff)
Basisadresse einer Datenstruktur variabel, Displacement
bekannt (z.B. beim Zugriff über Pointer auf Records)
logo
Assembler - Adressierungsarten– 3/31– 2008-04-01
Adressierungsarten – effektive Adresse
Beispiel: Zugriff auf Array-Elemente:
short int i ;
// A d r e s s e 8
s h o r t i n t f [ 5 ] ; // A d r e s s e 14
f [ i ] = 300;
Adresse von i bekannt (8)
Adresse von f bekannt (14)
Größe der Elemente von f bekannt (2)
Adresse(f [i]) = Adresse(f ) + i ∗ 2
logo
Assembler - Adressierungsarten– 4/31– 2008-04-01
Adressierungsarten – effektive Adresse
Beispiel: Zugriff auf Record-Elemente über Pointer:
struct rec {
s h o r t i n t x ; long i n t i ;
short int y ; short int z ;
};
s t r u c t r e c ∗p ; // A d r e s s e 8
s t r u c t r e c s ; // A d r e s s e 14
p−>y = 9 ;
Adresse von p bekannt (8)
Displacement von s.y bezüglich s
bekannt (6)
Adresse(p− > y ) = p + 6
Assembler - Adressierungsarten– 5/31– 2008-04-01
logo
Adressierungsarten
Bei der Ausführung von Befehlen mit Parametern (z.B. Addition
zweier Werte) sind folgende Punkte sind zu unterscheiden:
wo stehen die eigentlichen Parameter (im Befehl, im Register
oder im Speicher)
wo stehen die Informationen, wie man an die Parameter
kommt (i.a. sind diese Informationen Teil des Befehls)
wie berechnet sich die effektive Adresse (wenn die Parameter
im Speicher stehen)
logo
Assembler - Adressierungsarten– 6/31– 2008-04-01
Adressierungsarten – Überblick
Register
Immediate Operand
Direct (Absolute) Address
Register Indirect
Register Indirect with Index
Register Indirect with Displacement / PC-relative
Register Indirect with Index and Displacement
Memory Indirect
Register Indirect with Pre-/Post-Decrement
Register Indirect with Pre-/Post-Increment
...
logo
Assembler - Adressierungsarten– 7/31– 2008-04-01
Adressierungsarten – Register
Register-Name bzw. -Nummer ist Bestandteil des Befehls
Operand liegt im Register
Syntax-Beispiele (i80x86):
movl %eax , . . .
movb . . . , %a l
Verwendung: Schreiben bzw. Lesen von in Registern gespeicherten
Variablen
r e g i s t e r s h o r t i n t r ; /∗ r l i e g t im R e g i s t e r %ax ∗/
r e g i s t e r s h o r t i n t s ; /∗ s l i e g t im R e g i s t e r %bx ∗/
r = s;
ergibt compiliert:
logo
movw %bx , %ax
Assembler - Adressierungsarten– 8/31– 2008-04-01
Adressierungsarten – Immediate Operand
Operand ist Bestandteil des Befehls
Syntax-Beispiele (i80x86):
movl $14 , . . .
movl $0x14 , . . .
movb $ ’ a ’ , . . .
Verwendung: Zuweisung von Konstanten an Variablen
r e g i s t e r long i n t x ; /∗ x l i e g t im R e g i s t e r %edx ∗/
x = 14;
ergibt compiliert:
movl $14 , %edx
Assembler - Adressierungsarten– 9/31– 2008-04-01
logo
Adressierungsarten – Immediate Operand
Anmerkung:
Viele Prozessoren (besonders RISC-CPUs) verwenden zur
Kodierung der Befehle jeweils gleichlange Byte-Folgen (z.B.
m88100: jeder Befehl ist genau 4 Bytes lang).
Aber: unmöglich, z.B. einen movl 0x12345678, %eax-Befehl
(allein Konstante ist 4 Byte lang) in 4 Bytes zu kodieren.
Abhilfe: Aufteilen des Befehls in zwei Teil-Befehle:
statt einem Befehl
movl $0x12345678 , %eax
zwei Befehle
s e t h i $0x1234 , %eax
s e t l o $0x5678 , %eax
logo
Assembler - Adressierungsarten– 10/31– 2008-04-01
Adressierungsarten – Direct (Absolute) Address
effektive Adresse ist Bestandteil des Befehls
Operand liegt im Speicher
Syntax-Beispiele (i80x86):
movl 1 2 3 6 , . . .
movb . . . , 4345
Hinweis: Statt der Adressen werden häufig lieber symbolische
Werte geschrieben. Z.B.:
movl v a r x , . . .
movb . . . , f l a g
Die symbolischen Werte müssen jedoch auf irgendeine Weise
definiert werden (z.B. durch define- oder equ-Anweisungen).
Definition im Folgenden aus Platzgründen häufig weggelassen.
Assembler - Adressierungsarten– 11/31– 2008-04-01
logo
Adressierungsarten – Direct (Absolute) Address
Verwendung: Schreiben bzw. Lesen von im Speicher abgelegten
Variablen
char c ; /∗ c h a t A d r e s s e 1245 ∗/
char d ; /∗ d h a t A d r e s s e 1246 ∗/
c = ’A ’ ; d = c ;
ergibt compiliert:
movb $65 , 1245
movb 1 2 4 5 , 1246
oder (lesbarer)
#d e f i n e c
#d e f i n e d
1245
1246
logo
movb $ ’A ’ , c
movb c , d
Assembler - Adressierungsarten– 12/31– 2008-04-01
Adressierungsarten – Register Indirect
Register-Name/-Nummer ist Bestandteil des Befehls
Register enthält effektive Adresse
Operand liegt im Speicher
Syntax-Beispiele (i80x86):
movl (%ebx ) , . . .
movb . . . , (%ebp )
logo
Assembler - Adressierungsarten– 13/31– 2008-04-01
Adressierungsarten – Register Indirect
Verwendung: z.B. Schreiben bzw. Lesen von Variablen über
Pointer, die in Registern liegen.
r e g i s t e r s h o r t i n t ∗p ; /∗ p l i e g t im R e g i s t e r %edx
short int x ;
/∗ x h a t d i e A d r e s s e 1456 ∗/
p = &x ;
∗p = 1 4 ;
x = ∗p ;
ergibt compiliert:
movl $1456 , %edx
movw $14 , (%edx )
movw (%edx ) , 1456
Assembler - Adressierungsarten– 14/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with Index
Register-Namen/-Nummern sowie Scale-Faktor sind
Bestandteile des Befehls
Register A enthält Anfangsadresse des Objektes
(„Startadresse”, „Basisadresse”)
Register B enthält Index
effektive Adresse berechnet sich als
Adresse = Basisadresse + Index ∗ ScaleFaktor
Operand liegt im Speicher
Syntax-Beispiele (i80x86):
movl (%ebx , %ecx , 4 ) , . . .
movb . . . , (%ebp , %edi , 8 )
Assembler - Adressierungsarten– 15/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with Index
Verwendung: Schreiben bzw. Lesen von Array-Elementen
short int f [ 1 0 0 ] ;
/∗ f h a t d i e A d r e s s e 1246 ∗/
r e g i s t e r s h o r t i n t ∗p ; /∗ p l i e g t im R e g i s t e r %ebx
r e g i s t e r s h o r t i n t i ; /∗ i l i e g t im R e g i s t e r %e c x
p = &f [ 0 ] ;
p [ i ] = 50;
f [1] = p[ i ];
ergibt compiliert:
movl $1246 , %ebx
movw $50 , (%ebx , %ecx , 2 )
movw (%ebx , %ecx , 2 ) , 1248
Assembler - Adressierungsarten– 16/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with Displacement
Register-Name/-Nummer sowie Displacement sind
Bestandteile des Befehls
Register enthält Basisadresse
effektive Adresse berechnet sich als
Adresse = Basisadresse + Displacement
Operand liegt im Speicher
Syntax-Beispiele (i80x86):
movl 4(%ebp ) , . . .
movb . . . , 17(% e s i )
logo
Assembler - Adressierungsarten– 17/31– 2008-04-01
Adressierungsarten – Register Indirect with Displacement
Bemerkungen:
wird für das Register der Instruction-Pointer/Program-Counter
verwendet, spricht man auch von „PC-relativer”-Adressierung
statt der Bezeichnung Displacement wird auch häufig die
Bezeichnung „Offset” verwendet
logo
Assembler - Adressierungsarten– 18/31– 2008-04-01
Adressierungsarten – Register Indirect with Displacement
Verwendung: Schreiben bzw. Lesen von Record-Elementen über
Pointer
s t r u c t r e c { long i n t x ; char c ; s h o r t i n t s ; } ;
struct rec r ;
/∗ r h a t d i e A d r e s s e 3456 ∗/
r e g i s t e r s t r u c t r e c ∗p ; /∗ p l i e g t im R e g i s t e r %e a x
p = &r ;
p−>c = ’A ’ ;
r . s = p−>s ;
ergibt compiliert:
movl $3456 , %eax
movb $ ’A ’ , 4(%eax )
movw 6(%eax ) , 3462 /∗ =3456+6 ; m i t A l i g n m e n t ∗/
Assembler - Adressierungsarten– 19/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with Index and
Displacement
Register-Name/-Nummer, Scale-Faktor sowie Displacement
sind Bestandteile des Befehls
Register A enthält Basisadresse
Register B enthält Index
effektive Adresse berechnet sich als
Adresse = Basisadresse + Index ∗ ScaleFaktor + Displacement
Operand liegt im Speicher
Syntax-Beispiele (i80x86):
movw 4(%ebp , %eax , 8 ) , . . .
movl . . . , 16(%edx , %ebx , 4 )
Assembler - Adressierungsarten– 20/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with Index and
Displacement
Verwendung: Schreiben bzw. Lesen von Record-Elementen eines
Arrays
s t r u c t r e c { long i n t x ; char c ; s h o r t i n t s ; } ;
struct rec f [ 1 0 0 ] ;
/∗ f h a t d i e A d r e s s e 452 ∗/
r e g i s t e r s t r u c t r e c ∗p ; /∗ p l i e g t im R e g i s t e r %e c x
r e g i s t e r long i n t i ;
/∗ i l i e g t im R e g i s t e r %e a x
p = &f [ 0 ] ;
p [ i ] . c = ’A ’ ;
f [2]. s = p[ i ]. s ;
ergibt compiliert:
logo
movl $452 , %ecx
movb $ ’A ’ , 4(%ecx , %eax , 8 )
movw 6(%ecx , %eax , 8 ) , 474 /∗ =452+2∗8+6 ; m i t A l i g n m
Assembler - Adressierungsarten– 21/31– 2008-04-01
Adressierungsarten – Memory Indirect
Speicheradresse ist Bestandteil des Befehls
effektive Adresse ist der Inhalt der angegebenen Speicherzelle
Operand liegt im Speicher
Syntax-Beispiele:
movl ( 2 4 ) , . . .
movb . . . , ( 4 6 5 )
logo
Assembler - Adressierungsarten– 22/31– 2008-04-01
Adressierungsarten – Memory Indirect
Verwendung: Schreiben bzw. Lesen von Variablen über Pointer, die
im Speicher liegen
s h o r t i n t x ; /∗ x h a t d i e A d r e s s e 340 ∗/
s h o r t i n t ∗p ; /∗ p h a t d i e A d r e s s e 342 ∗/
p = &x ;
∗p = 4 5 ;
x = ∗p ;
ergibt compiliert:
movl $340 , 342
movw 4 5 , ( 3 4 2 )
movw ( 3 4 2 ) , 340
Assembler - Adressierungsarten– 23/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with
Pre-/Post-Increment/Decrement
Register-Name/Nummer sowie die Größe des Operanden sind
Bestandteile des Befehls
Register enthält effektive Adresse
Operand liegt im Speicher
vor/nach dem Zugriff auf den Operanden wird Registerinhalt
inkrementiert/dekrementiert (um die Größe des Operanden)
Syntax-Beispiele (i80x86):
movw
movb
movl
movw
−(%esp ) , . . .
+(%eax ) , . . .
. . . , (%ebp)+
. . . , (%ecx)−
Assembler - Adressierungsarten– 24/31– 2008-04-01
logo
Adressierungsarten – Register Indirect with
Pre-/Post-Increment/Decrement
Verwendung: Push und Pop von Werten auf dem Stack (später)
s t r u c t r e c { long i n t x ; s h o r t i n t y ; char c ; } ;
s t r u c t r e c a ; /∗ a h a t d i e A d r e s s e 1232 ∗/
s t r u c t r e c b ; /∗ b h a t d i e A d r e s s e 344 ∗/
a = b;
ergibt compiliert:
movl
movl
movl
movw
movb
$1232 , %eax
$344 , %ebx
(%ebx )+ , (%eax)+
(%ebx )+ , (%eax)+
(%ebx )+ , (%eax)+
Assembler - Adressierungsarten– 25/31– 2008-04-01
logo
Adressierungsarten – m68x05
tax
txa
lda
ldx
lda
ldx
sta
stx
lda
ldx
sta
stx
lda
ldx
sta
stx
/∗ R e g . −> R e g . ∗/
#12
#34
1234
5678
1234
5678
,x
,x
,x
,x
12 , x
34 , x
56 , x
78 , x
/∗ I m m e d i a t e Operand −> R e g . ∗/
/∗ D i r e c t A d d r e s s −> R e g . ∗/
/∗ R e g . −> D i r e c t A d d r e s s ∗/
/∗ R e g . I n d i r e c t −> R e g . ∗/
/∗ R e g . −> R e g . I n d i r e c t ∗/
/∗ R e g . I n d i r e c t w i t h D i s p l a c e m e n t −> R e
logo
/∗ R e g . −> R e g . I n d i r e c t w i t h D i s p l a c e m e
Assembler - Adressierungsarten– 26/31– 2008-04-01
Adressierungsarten – Hinweise
nicht alle CPUs können alle Adressierungsarten (insbesondere
viele Einschränkungen bei RISC-CPUs und kleinen
Mikro-Controllern)
nicht alle Adressierungsarten sind mit allen Registern möglich
(z.B. ist der Instruction Pointer nicht als Basis- oder
Index-Register erlaubt)
nicht alle Kombinationen von Adressierungsarten (Ziel und
Quelle) sind möglich (z.B. erlauben viele CPUs movl 1232,
432 nicht)
es existieren i.a. Einschränkungen für die möglichen Werte
bzw. die Größe von Scale-Faktor und Displacement (z.B. kann
der Scale-Faktor nur 1, 2, 4 oder 8 betragen; Displacement
häufig < 256)
Assembler - Adressierungsarten– 27/31– 2008-04-01
logo
Adressierungsarten – Hinweise
Zum Teil werden Befehle und Adressierungsarten (z.B. aus
historischen Gründen) anders geschrieben. Beispiele (i80x86):
statt
movl %eax , −(%esp )
movl (%esp )+ , %eax
wird verwendet
p u s h l %eax
p o p l %eax
movl %e f l a g s , −(%esp )
movl (%esp )+ , %e f l a g s
pushfl
popfl
movl $1234 , %e i p
jmp 1234
movl (%esp )+ , %e i p
ret
logo
Assembler - Adressierungsarten– 28/31– 2008-04-01
Adressierungsarten – lea-Befehl
Nicht alle Programmier-Konstrukte zum Zugriff auf Variablen
innerhalb von (verschachtelten) Arrays und Records sind direkt
umsetzbar. Z.B.:
char f [ 1 0 ] [ 1 0 ] ;
int i , j ;
f [ i ][ j ] = ...;
Adresse(f [i][j]) wäre im Beispiel Adresse(f ) + i ∗ 10 + j. Dafür
existiert keine Adressierungsart (bei den meisten Prozessoren).
In diesen Fällen muss die Adresse explizit berechnet werden
lea-Befehl
logo
explizite Arithmetik (später)
Assembler - Adressierungsarten– 29/31– 2008-04-01
Adressierungsarten – lea-Befehl
s t r u c t r e c { s h o r t i n t v a l u e ; char name [ 6 ] ; } ;
struct rec r ;
/∗ r h a t d i e A d r e s s e 432 ∗/
r e g i s t e r s t r u c t r e c ∗p ; /∗ p l i e g t im R e g i s t e r %e a x
r e g i s t e r long i n t i ;
/∗ i l i e g t im R e g i s t e r %ebx
p = &r ; p−>name [ i ] = ’A ’ ;
ist equivalent zu
r e g i s t e r char ∗n ;
/∗ n l i e g t im R e g i s t e r %e c x
p = &r ; n = &p−>name [ 0 ] ; n [ i ] = ’A ’ ;
ergibt compiliert
movl $432 , %eax
l e a 2(%eax ) , %ecx
movb $ ’A ’ , (%ecx , %ebx , 1 ) ;
Assembler - Adressierungsarten– 30/31– 2008-04-01
logo
Adressierungsarten – Hinweise
Ersatz für fehlende Adressierungsarten:
movl 1 2 3 4 5 6 7 8 , %eax
movl ( 1 2 3 4 5 6 7 8 ) , %eax
movl 8(%eax ,%ebx , 1 ) , % eax
movl $12345678 , %eax
movl (%eax ) , %eax
movl $12345678 , %eax
movl (%eax ) , %eax
movl (%eax ) , %eax
l e a l 8(%eax ) , %eax
movl (%eax ,%ebx , 1 ) , % eax
Weitere Adressierungsarten können über Arithmetik-Befehle
nachgebildet werden.
logo
Assembler - Adressierungsarten– 31/31– 2008-04-01