15
6.5 MMIX Befehle 291 In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ A OCTA #FFFF FFFF FFFF FFFF B TETRA #8765 4321 LOC #100 Main LDTU $0,B XXX XXXXXXXX TRAP 0,Halt,0 c) Geben Sie für das oben gezeigte Programm den Inhalt des 64 Bit breiten Wortes an, welches durch die Marke A adressiert wird, wenn XXX XXXXXXXX durch folgende Befehle ersetzt wird: STB $0,A: STTU $0,A: STT $0,$254,6: T d) Geben Sie für das oben gezeigte Programm den Inhalt des 64 Bit breiten Wortes an, welches durch die Marke A adressiert wird, wenn XXX XXXXXXXX durch folgende Befehle ersetzt wird: STW $0,A: STWU $0,A: STT $0,A: STO $0,A: STB $0,$254,5: STW $0,$254,1: ST0 $0,$254,5: : a iii. , : _o← :;fff÷±t o.O $oi¥oeaF i ( 321 FFF . - - FFFF k32n FFF r FFFF 87654324 FF . . F ITOH 8+654327 TO FFFF FFFF FFH FFFF 0~ 432N FFFF . - - FFFF own 0000.060 8765434

AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

  • Upload
    others

  • View
    29

  • Download
    0

Embed Size (px)

Citation preview

Page 1: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 291

In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen

Befehl verwendet:

LOC Data_SegmentGREG @

A OCTA #FFFF FFFF FFFF FFFFB TETRA #8765 4321

LOC #100Main LDTU $0,B

XXX XXXXXXXXTRAP 0,Halt,0

c) Geben Sie für das oben gezeigte Programm den Inhalt des 64 Bit breiten Wortes

an, welches durch die Marke A adressiert wird, wenn XXX XXXXXXXX durch folgende

Befehle ersetzt wird:

STB $0,A:

STTU $0,A:

STT $0,$254,6:

T d) Geben Sie für das oben gezeigte Programm den Inhalt des 64 Bit breiten Wortes

an, welches durch die Marke A adressiert wird, wenn XXX XXXXXXXX durch folgende

Befehle ersetzt wird:

STW $0,A:

STWU $0,A:

STT $0,A:

STO $0,A:

STB $0,$254,5:

STW $0,$254,1:

ST0 $0,$254,5:

:a iii. ,

:

⇒→

_o←:;fff÷±t→

o.O$oi¥oeaFi( 321 FFF . -

-FFFF

k32n FFF r. FFFF

87654324 FF . . .

F

ITOH 8+654327←

TO FFFF FFFF FFH FFFF

0~ 432N FFFF . - - .

FFFF

own 0000.060 8765434

Page 2: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

292 6 MMIX-Prozessor

e) Geben Sie hexadezimal das 32 Bit breite Befehlswort des Befehls STBU $0,A an,

wenn dieser in obigem Programmcode den Platzhalter XXX XXXXXXXX ersetzt.

T f) Geben Sie die Befehle an, mit denen Sie

• an Adresse 0x2000 0000 0000 0000 ein 64 Bit breites Datum anlegen,

• dieses Datum über die Marke Data ansprechbar machen und

• das Datenwort mit 0x1234 5678 initialisieren;

• an Adresse 0x100 ein Programm beginnen und

• das an Adresse Data gespeicherte Datenwort in Register 1 einlesen,

• Bits 7 ... 0 des Registers 1 an Adresse Data schreiben,

• Bits 7 ... 0 des Registers 1 an Adresse 0x2000 0000 0000 0002 schreiben,

• Bits 31 ... 0 des Registers 1 an Adresse 0x2000 0000 0000 000A schreiben.

0→

-

.0O

O

( OC #Zo . - .0

Dose GREG @

→ Data OCTA Fm 345678

Loc #zou

Main LDO $1 , Data

STD $1 ,Data

STB$1 ,

Base ,2

STT $7,

Base ,#A

Page 3: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 293

Gegeben ist der folgende Programmcode:

LOC Data_SegementGREG @

Label OCTA #1234 5678

LOC #100Main LDO $0,Label

STB $0,LabelLDA $2,LabelSTB $0,$2,2STT $0,$2,10

T g) Zeichnen Sie byteweise den Inhalt des Speichers von Adresse 0x20 ... 00 bis

0x20 ... 00F, der sich nach Ausführung des o.g. Programms ergibt.

f &

o$oFto2234J6T|

÷zips-

-

0ssae se §

0×20 . - - -

-00 do 78 78 78

0×20 - --

07 oo00 oe oo

-7 .. -

-

02' - 00 78 28

. -- -03

,

' ' 00 oo oo

. , -04 1-Z 22?Z22

. .

.-

05 ) 4 34 34 34

, . . -06 56 56 JG oz

..

-

-07 78 78 7f As

e-.

.

08 ? ? ? ? 22 ¢

.. -

-09 2 ? ?

I

34

.

.-

.

OA ? ? ? of

.- -

VOB ? ?? 28

7 ? ?,

✓-

icierOD ? ?

'

z

? ? . I

.

. -OE

, 7.

1 7

. ✓ -OF

iii 7

~,

10 l c(

Page 4: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

296 6 MMIX-Prozessor

Zugriff auf Spezialregister

Befehl Operanden Name/Aktion Definition

GET $X,Z Get value of special purpose register $X S(Z)

PUTX,$Z Put value to special purpose register S(X) $ZX,Z Put immed. value to spec. purp. reg. S(X) u

064(u(Z))

T a) Tragen Sie in nachfolgender Befehlssequenz Befehle zur Berechnung der Fest-

kommadivisioni dividend/divisor ein und speichern Sie das Ergebnis an der

Marke Quotient und den Divisionsrest an der Marke Remainder ab.

LOC Data_SegmentGREG @

Dividend OCTA 7Divisor OCTA 3Quotient OCTARemainder OCTA

dividend IS $0divisor IS $1quotient IS $2remainder IS $3

LOC #100Main LDO dividend,Dividend

LDO divisor,Divisor

TRAP 0,Halt,0

DIU quotient ,dividend ,

divisor

GET reminder .RR

STO quotient ,Quotient

ffo reminder ,Reminder

Page 5: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 301

T e) Geben Sie den MMIX-Code an, der nachfolgenden C-Code implementiert:

C-Code: int a, b;

...

if(a > 0 && b < 0){

a = 1;}else if(a > 0 || b == 0){

a = 2;}else{

a = 3;}

MMIX-Code:

:oz'

Page 6: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

302 6 MMIX-Prozessor

Befehle für Funktionsaufrufe

Befehl Operanden Name/Aktion Definition

GO$X,$Y,$Z Go to location

$X u

064( u(@) + 4) );

@ u

064( u($Y)+u($Z) )

$X,$Y,Z Go to location immediate$X u

064( u(@) + 4) );

@ u

064( u($Y) + u(Z) )

T a) Was ist der Haupt-Unterschied zwischen dem JMP-Befehl und dem GO-Befehl?

T b) Wo speichern GO-Befehle die Rücksprungadresse ab?

T c) Was ist die ‘‘Rücksprungadresse’’?

T d) Wenn GO Absolute Adressierung verwendet: Wie wird die Abolute Adresse (64 Bit)

im 32 Bit breiten Befehlswort abgelegt?

e) Geben Sie den Befehl an, mit dem Sie die Funktion fkt aufrufen und die Rück-

sprungadresse in Register 0 ablegen.

TMP -1 relative Adressieouy ( nah hinter lnad

GO → Absolute Adigiuuag ,

Vonuqoringn ,relakvAtpudm Speicher t die

w ioh guede bin )

Ridspruyadiesse ( Jup - Nichtl

In Register ×

Die tossed . nidyk Befehlswort .

Wenn

Go an einu durch via teilban Adresx a ist,

dawn ist die R.s. a a*4.

$Y =) Basioediesx ,in Reg . Ygspeidwt

7 / $7 ⇒ offset

Page 7: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 303

Namensräume - der PREFIX-Befehl

Der PREFIX-Befehl ist ein Assembler-Befehl. Er wird verwendet, um in einem Pro-

gramm vorkommenden Namen vom Assembler-Präprozessor durch Voranstellen einer

Zeichenkette automatisiert ändern zu lassen. Dazu wird der PREFIX-Befehl mit der

voranzustellenden Zeichenkette als Operand aufgerufen.

PREFIX Zeichenkette

Ab dieser Anweisung setzt der Assembler-Präprozessor vor jeden Namen die angege-

bene Zeichenkette. Hat beispielsweise die Zeichenkette den Wert ‘‘abc:’’, dann wird ein

Name ‘‘def’’ in ‘‘abc:def’’ geändert.

Fügt man vor jede Funktion einen PREFIX-Befehl mit dem Funktionsnamen als Zeichen-

kette ein, erzeugt man automatisch für jede Funktion einen eigenen Namensraum. Eine

Variable i in der Funktion fkt bekommt dann den (globalen) Namen fkti und eine Variable

i in der Funktion fkt2 den Namen fkt2i. Auf diese Weise kann der Assembler beide

Variable als unterschiedliche Variable erkennen und es kommt zu keinem Konflikt, wenn

der Assembler beispielsweise i sowohl durch $1 ersetzen soll (für die Funktion fkt1) als

auch durch $2 (für die Funktion fkt2).

Um den Funktionsnamen besser vom Variablennamen abgrenzen zu können, bietet es

sich an, an die Prefix-Zeichenkette noch ein markantes Zeichen anzuhängen, beispiels-

weise einen Bindestrich oder einen Doppelpunkt.

Um einen Namensraum zu beenden, d.h. um den Assembler-Präprozessor anzuweisen,

vorkommenden Namen die Zeichenkette nicht mehr voranzustellen, wird der PREFIX-

Befehl mit einem Doppelpunkt als Operand aufgerufen.

PREFIX :

Will man innerhalb eines Namensraums verhindern, dass der Assembler-Präprozessor

einen Namen ändert, schreibt man vor den betreffenden Namen einen Doppelpunkt,

z.B. ‘‘:def’’ statt ‘‘def’’. Auf diese Weise kann man auf globale Namen wie z.B. den

Stackpointer SP zugreifen.

a) Geben Sie die Anweisung an, mit denen Sie den Namensraum ‘‘Main:’’ eröffnen

und in diesem Namensraum die globale Marke ‘‘Main’’ definieren.

:0

Page 8: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

304 6 MMIX-Prozessor

b) Wie kann man einen Namensraum beenden, d.h. wie kann man den Assembler

anweisen, Marken/Namen nicht mehr umzuwandeln?

c) Wie kann man – innerhalb eines Namensraums – verhindern, dass der Assembler

einer bestimmten Marke bzw. einem bestimmten Namen die im PREFIX-Befehlangegebene Zeichenkette voranstellt?

T d) Wozu dient der PREFIX-Befehl?

T e) Welche Auswirkung hat der Befehl PREFIX mein_prefix auf darauf folgendeMMIX-

Anweisungen?

Genneiwuyu

.Naumoraiwne

→ low,

global ?

( Variable .Fkt . )

→ def ( Nemeu .

Variable )

↳ nein . prefixdeef

( Rein Textuxttuy )

Page 9: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 305

T f) Geben Sie die Anweisungen an, mit denen Sie den Namensraum ‘‘Fkt:’’ eröffnen

und die globale Marke ‘‘Fkt’’ anlegen.

Funktionsaufrufe

Mit Funktionen werden logisch zusammengehörige Befehle zur Bereitstellung einer

Gesamt-Funktionalität zusammengefasst und durch Funktionsaufrufe von beliebigen

Stellen im Programm abrufbar. Durch diese Struktur gebende Maßnahme werden

Programme übersichtlicher und kürzer:

• Übersichtlicher, da der Programm-Code die Zerlegung eines großen Problems

in kleinere Probleme durch Funktionsaufrufe widerspiegelt, und

• kürzer, da eine Funktionalität (viele Befehle) nur einmal aus Befehlen zusam-

mengesetzt werden muss und durch Sprünge in die Funktion (wenige Befehle)

beliebig oft verwendet werden kann.

Beispiel: Email-Adresse von Personen aus einer csv-Datei (csv = comma separated

values =Werte durch Komma getrennt) extrahieren und jeder Person ein Email schreiben:

• Aufruf einer Funktion, welche den Namen der csv-Datei als Parameter überge-

ben bekommt und den Inhalt der Datei in den String s einliest.

• Aufruf einer Funktion, welche den String s sowie das Zeichen \n als Parameter

übergeben bekommt, den String an den Zeichen \n in Teil-Stings s1, s2, ... auf-

trennt und als Ergebnis ein Array von Zeigern auf die Teil-Strings zurückliefert.

• Für jeden Teilstring s

i

: Aufruf einer Funktion, welche den String s

i

und das

Komma-Zeichen als Parameter übergeben bekommt, den String an den Kom-

mas in Teilstrings s

i

j

auftrennt und als Ergebnis ein Array von Zeigern auf die

Teil-Strings zurückliefert.

• Auswahl des Teil-Strings s

i

j

, in dem die EMail-Adresse gespeichert ist.

• Für jede Email-Adresse s

i

j

: Aufruf einer Funktion, die als Parameter die Email-

Adresse und den Email-Text bekommt und den Email-Text an die angegebene

Email-Adresse verschickt.

PREFIX Fkt :

:Fkt.

.-

Page 10: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 321

T i) Was ist der Stack?

T j) Wo beginnt der Stack und in welche Richtung wächst er?

T k) Was ist der Stack-Pointer?

T l) Wie werden Daten adressiert, die auf dem Stack liegen?

Beih in Avbeitsspidw .

Es ulhilt

.locale Vi

iegiesiclwkRegistertoR

. s ,

a .

( Richoprungadreosen )

Ended . Datugmnts und waihst Ridingkleiner er Adresom .

Ein Register ,da , die Ad= do xhttt

aef dm State atgelyk Elements entlidt.

TMAER its den S . P C Skd . Pointe )

adroit

Page 11: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

322 6 MMIX-Prozessor

T m) Welche Operationen muss man ausführen um die Werte zweier Register (acht Byte

breite Datenworte) auf dem Stack abzulegen?

T n) Wie wird der Stack bei Funktionsaufrufen verwendet?

@ Substratum : 2-8--206 ( 2 Bytes )

@ n.

Datuwwt gespidut and :c Wwe d. SP

2 .Dale wort

' '

' '' '

' '

d. SP

← 8

Bin Afefd .Feet .

° Parmeter ⇒ Stack

In.

Ikt .

. R.s.ae ⇒ Stade

• diejmige Register ,d :& von der aufgrufue

Fkt . geeidut under ⇒ in Stack sicken .

. Raitt Stach

.Parmeter . .

. Ergebnis !

. Ergebnis ⇒ Slade

a giaidwte Reg .in Stach =) wieduheroklbn

• Stack =) Rs .a( auslesa )

a RP ..

. .

auf Ergbrisvon Fktu tedgm

.

GO - Befell e) FonkhionsowfrufuNaeh Ruekw ⇒ Ergetn

'

's⇐ Slack ( asluof

Page 12: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 323

T o) Geben Sie den Befehl an mit dem Sie für den Stack-Pointer ein globales Register

reservieren und dieses mit 0x4000 00000000 0000 initialisieren.

T p) Warum initialisieren wir den Stack-Pointer mit 0x4000 00000000 0000, d.h. mit

dem Beginn des Poolsegments, und nicht mit dem Ende des Datensegments?

T q) Geben Sie die MMIX-Befehle an, mit denen Sie Register $1 und $2 auf den Stack

schreiben und dann die Funktion fkt aufrufen. Nehmen Sie an, dass Ihr Code im

Namensraum Main: steht und fkt im Namensraum Fkt: unter dem Namen :fktangelegt wurde. Sichern Sie die Rücksprungadresse in Register 0.

SP GREG #4o . -- o

Ven Schreiber : Wet ✓ .

S - P veroiyat

It Oleta ± SP - 8 =) # ZEFFF . . .F8

(Datnoymat )

FUB :S ,P,

:SP ; 2*8

HE sto $n ,

: sad

JTO $2 ,:SP

,

1×8

60 $0 ,:tht

Page 13: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

324 6 MMIX-Prozessor

Nehmen Sie an, dass Sie eine Funktion im Namensraum Fkt: implementieren.

T r) Geben Sie die MMIX-Befehle an, mit denen Sie die Register 0, 1, 2 und 3 auf den

Stack sichern und anschließend zwei acht Byte breite Parameter vom Stack in die

Register 1 und 2 einlesen.

T s) Zeichnen Sie, wie der Stack nach diesen Operationen aussieht.

SUB '

.SP

,

-

- SD,

4*18

~STO $0 ,

:SP,

0

STO $7,

: sp ,a←8

~

STO $2 ,

'

' SP,

22.8~

SIZ $3,

'

.

SP,

3.8

( DO

$1,750, 4.8←

( Do $2 , isp, 5.8

→FDoa¥:#=p

Page 14: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

6.5 MMIX Befehle 325

T t) Im Hauptprogramm wurden die Parameter in die Register 1 und 2 geschrieben.

Im Unterprogramm wurden Register 1 und 2 dann auf den Stack gesichert und

dann dieselben Werte wieder vom Stack in Register 1 und 2 geladen, obwohl

sich die Werte von Register 1 und 2 in der Zwischenzeit nicht geändert hatten.

Warum haben wir und diesen Schritt nicht gespart sondern dieselben Werte, die

in Registern 1 und 2 waren, nochmal reingeschrieben?

T u) Warum speichert man die Rücksprungadresse auf dem Stack?

T v) Was würde passieren, wenn der Stack so groß wird, dass er mit den Daten

zusammenstößt, die am Beginn des Datensegments liegen?

CHAOS

Page 15: AOCTA#FFFFFFFFFFFFFFFF o← o.O $oi¥oeaF · In folgendem Programmcode wird XXX XXXXXXXX als Platzhalter für einen einzelnen Befehl verwendet: LOC Data_Segment GREG @ AOCTA#FFFFFFFFFFFFFFFF

326 6 MMIX-Prozessor

T w) Geben Sie die MMIX-Befehle an, mit denen Sie den Inhalt von Register 3 als

Ergebnis auf dem Stack ablegen, dann die Register 0, 1, 2 und 3 wiederherstellen

und anschließend zurück zum Funktionsaufrufer springen.

T x) Nehmen Sie an, Sie sind wieder im Hauptprogramm. Geben Sie die Befehle an mit

denen Sie das Ergebnis der Funktion vom Stack in das Register 1 einlesen.

T y) Warum muss der Stack-Pointer angepasst werden nachdem das Ergebnis vom

Stack geladen wurde?

STO $3 ,:SP ,

5.8

LDO $0 ,, SP

,0

( Do $1 ,:S ?

,

a .8

LDU $2 /:Sp ,2.8

LDO $3 ,:SP ,

3 . 8

ADD :SP, :s@ ,

5.8

60 $01 $010

. ( D 0 $7 , " SP,

0

ADD : SP ,: SD ,

7.8

Dorit as w :c antufayaisoiuhf

#f@