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