Dokumente und Mars-Simulator

This commit is contained in:
Riwoldt
2025-03-26 09:10:55 +01:00
parent 85f594994e
commit 4501819ac9
73 changed files with 1064 additions and 0 deletions

BIN
MARS/Bitte lesen!.pdf Normal file

Binary file not shown.

BIN
MARS/MARS Simulator.jar Normal file

Binary file not shown.

View File

@@ -0,0 +1,68 @@
######################################################################
##### Beispielcode fuer logische Operationen and, or, xor, nor #####
######################################################################
.data
source1: .word 0xFFFF0000
source2: .word 0x46A1F0B7
and: .asciiz "\n11111111111111110000000000000000 AND\n01000110101000011111000010110111 =\n"
or: .asciiz "\n11111111111111110000000000000000 OR\n01000110101000011111000010110111 =\n"
xor: .asciiz "\n11111111111111110000000000000000 XOR\n01000110101000011111000010110111 =\n"
nor: .asciiz "\n11111111111111110000000000000000 NOR\n01000110101000011111000010110111 =\n"
nl: .asciiz "\n"
.text
lw $s1, source1 # $s1 = 0xFFFF0000
lw $s2, source2 # $s2 = 0x46A1F0B7
# Operationen
and $s3, $s1, $s2
or $s4, $s1, $s2
xor $s5, $s1, $s2
nor $s6, $s1, $s2
# Ausgabe and
la $a0, and
li $v0, 4
syscall
move $a0, $s3
li $v0, 35
syscall
la $a0, nl
li $v0, 4
syscall
# Ausgabe or
la $a0, or
li $v0, 4
syscall
move $a0, $s4
li $v0, 35
syscall
la $a0, nl
li $v0, 4
syscall
# Ausgabe xor
la $a0, xor
li $v0, 4
syscall
move $a0, $s5
li $v0, 35
syscall
la $a0, nl
li $v0, 4
syscall
# Ausgabe nor
la $a0, nor
li $v0, 4
syscall
move $a0, $s6
li $v0, 35
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,29 @@
###############################################################################
# Multipliziert zwei Integerzahlen, zeigt die Verwendung der Register hi, lo #
# die benoetigt werden, weil das Produkt von 32-Bit-Zahlen bis zu 64-Bit lang #
# wird. Bei der Division wird der Quotient in lo und der Rest in hi abgelegt #
###############################################################################
.data
number1: .word 0x0fffffff
number2: .word 0x12345678
number3: .word 0x01234567
.text
# Laden der Beispielzahlen in t0, t1, t2
lw $t0, number1
lw $t1, number2
lw $t2, number3
# Multiplikation
mul $t3, $t0, $t1 # Die unteren 32 Bits des Produkts werden in $t3 abgelegt
mfhi $s0 # Um auf die oberen 32 Bits zugreifen zu k<EFBFBD>nnen, wird mfhi ben<EFBFBD>tigt
mflo $s1 # Fuer den Zugriff auf die unteren 32 Bits des Produkts wird mflo verwendet
# Division $t0 durch $t1
div $t0, $t2 # speichert den Quotienten in lo und den rest in hi
mfhi $s2 # holt den Rest der Division aus hi und legt ihn in $s2 ab
mflo $s3 # holt den Quotienten aus lo und legt ihn in $s3 ab
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,44 @@
####################################################################
##### Beispielcode f<EFBFBD>r Schiebeoperationen sll, srl, sra #####
####################################################################
.data
src: .word 0xf30002a8
sll: .asciiz "\nshift left logical\n11110011000000000000001010101000 um 4 Stellen = \n"
srl: .asciiz "\nshift right logical\n11110011000000000000001010101000 um 4 Stellen = \n"
sra: .asciiz "\nshift right arithmetic\n11110011000000000000001010101000 um 4 Stellen = \n"
.text
lw $s0, src # $s0 = 0xf30002a8
# Schiebeoperationen
sll $s1, $s0, 4 # Schiebe den Inhalt von $s0 um 4 Stelle nach links, fuelle rechts mit 0en auf
srl $s2, $s0, 4 # Schiebe den Inhalt von $s0 um 4 Stellen nach rechts, fuelle links mit 0en auf
sra $s3, $s0, 4 # Schiebe den Inhalt von $s0 um 4 Stellen nach rechts, fuelle links mit dem Vorzeichenbit auf
# Ausgabe sll
la $a0, sll
li $v0, 4
syscall
move $a0, $s1
li $v0, 35
syscall
# Ausgabe srl
la $a0, srl
li $v0, 4
syscall
move $a0, $s2
li $v0, 35
syscall
# Ausgabe sra
la $a0, sra
li $v0, 4
syscall
move $a0, $s3
li $v0, 35
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,31 @@
########################################################################
##### Folgender High-Level Code wird in Assembler umgesetzt: #####
##### int sum = 0; #####
##### for (i = 1; i < 101; i = i*2) #####
##### sum = sum + i; #####
########################################################################
##### addiert die Vielfachen von 2 von 1 bis 100, zeigt die #####
##### Verwendung der 'set less than' Anweisung slt #####
########################################################################
addi $s1, $zero, 0 # Initialisierung der Summe sum in $s1 mit 0
addi $s0, $zero, 1 # Initialisierung des Zaehlers i in $s0 mit 1
addi $t0, $0, 101 # Obergrenze 101
loop:
slt $t1, $s0, $t0 # if (i<101) $t1 = 1, else $t1 = 0
beq $t1, $zero, done # if $t1 == 0 (i >=101), spring zur Marke done
add $s1, $s1, $s0 # sum = sum + i
sll $s0, $s0, 1 # i = i * 2
j loop # Sprung zu loop
done:
li $v0, 10 # Der Wert 10 fuer den syscall bedeutet:
syscall # terminate execution
##########################################################################
# Dieses Beispiel fuer eine Schleife, die slt nutzt, entstammt dem Buch: #
# Harris & Harris: Digital Design and Computer Architecture, Kap. 6 #
##########################################################################

View File

@@ -0,0 +1,54 @@
##################################################################################
##### Beispielcode zur Verwendung von Lade- und Speicherbefehlen lb, lbu, sb #####
##################################################################################
.data
src: .word 0xf78c4203
lbu: .asciiz " Nach dem Ladebefehl lbu $s1, 2($s0) steht in Register $s1 nun das mit 0en erweiterte Byte 2 des Eingabewortes: \n"
lb: .asciiz "\n Nach dem Ladebefehl lb $s2, 2(s0) steht in Register $s2 nun das vorzeichenerweiterte Byte 2 des Eingabewortes: \n"
sb: .asciiz "\n Mit dem Speicherbefehl sb $s3, 3(s0) wird das Byte 3 in $s0 durch das least significant Byte\n aus $s3 ersetzt, die anderen Bytes aus $s3 wurden ignoriert: \n"
.text
# Laden der Adresse von src in s0
la $s0, src
# Laden eines Beispielwerts in s1-s3, damit erkennbar wird, was mit den Werten in den Zielregistern passiert
li $s1, 0x6c00216f
li $s2, 0x6c00216f
li $s3, 0x6c00216f
# Laden des Bytes 2, also 0x8c mit dem lbu Befehl in Register $s1
lbu $s1, 2($s0)
# In s1 steht nun das mit 0 erweiterte Byte, Ausgabe:
la $a0, lbu
li $v0, 4
syscall
move $a0, $s1
li $v0, 34
syscall
# Laden des Bytes 2, also 0x8c mit dem lb Befehl in Register $s2
lb $s2, 2($s0)
# In s2 steht nun das vorzeichenerweiterte Byte, Ausgabe:
la $a0, lb
li $v0, 4
syscall
move $a0, $s2
li $v0, 34
syscall
# Bedeutet: Nimm das least significant Byte aus $s3 und ersetze damit das Byte 3 in $s0
sb $s3, 3($s0)
# In s0 wurde durch den sb Befehl das Byte 3 durch das Byte 0 aus $s3 ersetzt
la $a0, sb
li $v0, 4
syscall
lw $a0, ($s0)
li $v0, 34
syscall
# exit
li, $v0, 10
syscall

View File

@@ -0,0 +1,53 @@
###############################################################################
##### Beispielcode fuer den Aufruf eines Unterprogramms #####
##### mit Uebergabe- und Rueckgabewerten #####
##### Folgender High-Level-Code wird in Mips-Assembler uebersetzt: #####
###############################################################################
##### int main () #####
##### { #####
##### int y; #####
##### ... #####
##### y = diffofsum (2,3,4,5); #####
##### ... #####
##### } #####
##### int diffofsums (int f, int g, int h, int i) #####
##### { #####
##### int result; #####
##### result = (f+g)-(h+i); #####
##### return result; #####
##### } #####
###############################################################################
main:
# Laden der f,g,h,i in die Uebergaberegister a0-a3
addi $a0, $zero, 2
addi $a1, $zero, 3
addi $a2, $zero, 4
addi $a3, $zero, 5
# Aufruf der Unterprozedur diffofsum, Speichern der Ruecksprungadresse in $ra
jal diffofsums
# Benutzen des Rueckgabewertes, der in $v0 liegt, $s0 = y
add $s0, $v0, $zero
# exit
li $v0, 10
syscall
####################### Unterprogramm diffofsums ##############################
diffofsums:
add $t0, $a0, $a1 # t0 = f+g
add $t1, $a2, $a3 # t1 = h+i
sub $t2, $t0, $t1 # s0 = (f+g)-(h+i)
add $v0, $t2, $zero # v0 = result
jr $ra # Ruecksprung
####################### Ende des Unterprogramms diffofsums ####################
###############################################################################
## Dieser Beispielcode fuer den Aufruf eines Unterprogramms wurde dem Buch ##
## Digital Design & Computer Architecture von Harris & Harris entnommen ##
###############################################################################

View File

@@ -0,0 +1,18 @@
#############################################################################
# Addiert zwei Integerzahlen, legt die Summe im temporaeren Register $t2 ab #
#############################################################################
.data
# Deklaration der Variablen
number1: .word 3
number2: .word 11
.text
# Laden der Werte in die temporaeren Register
lw $t0, number1($zero)
lw $t1, number2($zero)
# Addition t2 = t0 + t1
add $t2, $t0, $t1
# exit
li $v0, 10 # der Wert 10 fuer den syscall bedeutet: exit (terminate execution)
syscall

View File

@@ -0,0 +1,27 @@
#############################################################################################
# Addiert zwei Integerzahlen, legt die Summe im temporaeren Register $t2 ab und gibt sie aus#
#############################################################################################
.data
# Deklaration der Variablen
number1: .word 3
number2: .word 11
.text
# Laden der Werte in die temporaeren Register
lw $t0, number1($zero)
lw $t1, number2($zero)
# Addition t2 = t0 + t1
add $t2, $t0, $t1
# Wert ausgeben:
li $v0, 1 # der Wert 1 fuer den syscall bedeutet: $a0 = integer to print
move $a0, $t2 # legt den Wert aus $t2 im Register $a0 fuer Parameteruebergabe ab
syscall
# exit
li $v0, 10 # der Wert 10 fuer den syscall bedeutet: exit (terminate execution)
syscall

View File

@@ -0,0 +1,46 @@
########################################################################
# liest zwei Integerzahlen ein, addiert sie und gibt das Ergebnis aus #
########################################################################
.data
prompt1: .asciiz "\nBitte die erste Zahl eingeben, x = "
prompt2: .asciiz "\nBitte die zweite Zahl eingeben, y = "
message: .asciiz "\nDas Ergebnis der Addition ist x + y = "
.text
# Ausgabe der ersten Nachricht: prompt1
li $v0, 4 # der Wert 4 fuer den syscall bedeutet: print string
la $a0, prompt1 # laedt die Adresse des ersten Strings in $a0
syscall
# erste Zahl einlesen und im temporaeren Register $t0 ablegen
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall
move $t0, $v0
# Ausgabe der zweiten Nachricht: prompt2
li $v0, 4
la $a0, prompt2
syscall
# zweite Zahl einlesen und in $t1 ablegen
li $v0, 5
syscall
move $t1, $v0
# Ausgabe der dritten Nachricht: message
li $v0, 4
la $a0, message
syscall
# Addition
add $t2, $t0, $t1
# Ausgabe der Summe
li $v0, 1
move $a0, $t2
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,46 @@
##########################################################################################
# liest zwei Integerzahlen ein, subtrahiert die zweite von der ersten, gibt Ergebnis aus #
##########################################################################################
.data
prompt1: .asciiz "\nBitte die erste Zahl eingeben:, x = "
prompt2: .asciiz "\nBitte die zweite Zahl eingeben, y = "
message: .asciiz "\nDas Ergebnis der Subtraktion ist x - y = "
.text
# Ausgabe der ersten Nachricht: prompt1
li $v0, 4 # der Wert 4 fuer den syscall bedeutet: print string
la $a0, prompt1 # laedt die Adresse des ersten Strings in $a0
syscall
# erste Zahl einlesen und im temporaeren Register $t0 ablegen
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall
move $t0, $v0
# Ausgabe der zweiten Nachricht: prompt2
li $v0, 4
la $a0, prompt2
syscall
# zweite Zahl einlesen und in $t1 ablegen
li $v0, 5
syscall
move $t1, $v0
# Ausgabe der dritten Nachricht: message
li $v0, 4
la $a0, message
syscall
# Subtraktion
sub $t2, $t0, $t1
# Ausgabe der Differenz
li $v0, 1
move $a0, $t2
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,49 @@
###################################################################
# liest zwei Integerzahlen ein, multipliziert sie und gibt das #
# Ergebnis als Gleitkommazahl in doppelter Genauigkeit aus #
###################################################################
.data
prompt1: .asciiz "\nBitte die erste Zahl eingeben, x = "
prompt2: .asciiz "\nBitte die zweite Zahl eingeben, y = "
message: .asciiz "\nDas Ergebnis der Multiplikation als double ist x * y = "
.text
# Ausgabe der ersten Nachricht: prompt1
li $v0, 4 # der Wert 4 fuer den syscall bedeutet: print string
la $a0, prompt1 # laedt die Adresse des ersten Strings in $a0
syscall
# erste Zahl einlesen und im temporaeren Register $t0 ablegen
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall
move $t0, $v0
# Ausgabe der zweiten Nachricht: prompt2
li $v0, 4
la $a0, prompt2
syscall
# zweite Zahl einlesen und in $t1 ablegen
li $v0, 5
syscall
move $t1, $v0
# Multiplikation
mul $t2, $t0, $t1
mfhi $t3
# Transport des Integerprodukts zum Coproc1 und Konvertieren zu double
mtc1.d $t2, $f12
cvt.d.w $f12, $f12
# Ausgabe der dritten Nachricht: message
li $v0, 4
la $a0, message
syscall
# Ausgabe des Produkts als double
li $v0, 3 # der Wert 3 fuer den syscall bedeutet: $f12 = double to print
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,54 @@
###########################################################################
# liest zwei Integerzahlen ein, dividiert die erste durch die zweite und #
# und gibt das Ergebnis als Gleitkommazahl in doppelter Genauigkeit aus #
###########################################################################
.data
prompt1: .asciiz "\nBitte die erste Zahl (den Dividenden) eingeben, x = "
prompt2: .asciiz "\nBitte die zweite Zahl (den Divisor) eingeben, y = "
message: .asciiz "\nDas Ergebnis der Division (der Quotient) ist x : y = "
.text
# Ausgabe der ersten Nachricht: prompt1
li $v0, 4 # der Wert 4 fuer den syscall bedeutet: print string
la $a0, prompt1 # laedt die Adresse des ersten Strings in $a0
syscall
# erste Zahl einlesen und im temporaeren Register $t0 ablegen
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall
move $t0, $v0
# erste Zahl zum Coproc 1 transferieren und konvertieren
mtc1.d $t0, $f4
cvt.d.w $f4, $f4
# Ausgabe der zweiten Nachricht: prompt2
li $v0, 4
la $a0, prompt2
syscall
# zweite Zahl einlesen und in $t1 ablegen
li $v0, 5
syscall
move $t1, $v0
# zweite Zahl zum Coproc 1 transferieren und konvertieren
mtc1.d $t1, $f6
cvt.d.w $f6, $f6
# Division durchfuehren, Ergebnis in $f12 speichern
div.d $f12, $f4, $f6
# Ausgabe der dritten Nachricht: message
li $v0, 4
la $a0, message
syscall
# Ausgabe des Quotienten
li $v0, 3 # der Wert 3 fuer den syscall bedeutet: $f12 = double to print
syscall
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,148 @@
########################################################################################
# Liest 2 Integerzahlen ein, ruft 4 Unterprogramme auf, in denen die Zahlen addiert, #
# subtrahiert, multipliziert und dividiert werden, gibt die jeweiligen Ergebnisse aus.#
# Leicht modifizierte und uebersetzte (aus DLX-Assembler) Version einiger STA aus #
# dem Kurstext Computersysteme I, Version 2011 #
########################################################################################
.data
prompt1: .asciiz "\nBitte die erste Zahl eingeben, x = "
prompt2: .asciiz "\nBitte die zweite Zahl eingeben, y = "
.text
main:
# Ausgabe der ersten Nachricht prompt1
li $v0, 4 # der Wert 4 fuer den syscall bedeutet: print string
la $a0, prompt1 # laedt die Adresse des ersten Strings in $a0
syscall
# erste Zahl einlesen und im Parameteruebergabe-Register $a1 ablegen
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall
move $a1, $v0
# Ausgabe der zweiten Nachricht prompt2
li $v0, 4
la $a0, prompt2 # Adresse des zweiten Strings in $a0 laden
syscall
# zweite Zahl einlesen und im Parameteruebergabe-Register $a2 ablegen
li $v0, 5
syscall
move $a2, $v0
# Aufrufe der Unterprogramme
jal add
jal sub
jal mul
jal div
# exit
li $v0, 10
syscall
#############################################################################################
############# Unterprogramme ####################
#############################################################################################
# Additionsfunktion wie in a)
add:
.data
message_add: .asciiz "\nDas Ergebnis der Addition ist x + y = "
.text
# Addition
add $t1, $a1, $a2
# Ausgabe der Nachricht
li $v0, 4
la $a0, message_add
syscall
# Ausgabe der Summe
li $v0, 1
move $a0, $t1
syscall
# Ruecksprung
jr $ra
# Subtraktionsfunktion wie in b)
sub:
.data
message_sub: .asciiz "\nDas Ergebnis der Subtraktion ist x - y = "
.text
# Subtraktion
sub $t1, $a1, $a2
# Ausgabe der Nachricht
li $v0, 4
la $a0, message_sub
syscall
# Ausgabe der Differenz
li $v0, 1
move $a0, $t1
syscall
# Ruecksprung
jr $ra
# Multiplikationsfunktion wie in c)
mul:
.data
message_mul: .asciiz "\nDas Ergebnis der Multiplikation als double ist x * y = "
.text
# Multiplikation
mul $t1, $a1, $a2
# Transport des Produkts zu Coproc1 und Konvertieren zu double
mtc1.d $t1, $f12
cvt.d.w $f12, $f12
# Ausgabe der Nachricht
li $v0, 4
la $a0, message_mul
syscall
# Ausgabe des Produkts
li $v0, 3
syscall
# Ruecksprung
jr $ra
# Divisionsfunktion wie in d)
div:
.data
message_div: .asciiz "\nDas Ergebnis der Division ist x : y = "
.text
# Transport der Zahlen zum Coproc1, Konvertieren zu double
mtc1.d $a1, $f4
cvt.d.w $f4, $f4
mtc1.d $a2, $f6
cvt.d.w $f6, $f6
# Division
div.d $f12, $f4, $f6
# Ausgabe der Nachricht
li $v0, 4
la $a0, message_div
syscall
# Ausgabe des Quotienten
li, $v0, 3
syscall
# Ruecksprung
jr $ra
################################################################################################
########################## Ende der Unterprogramme ################################
################################################################################################

View File

@@ -0,0 +1,63 @@
############################################################
# Berechnung der Fakultaet von n, also n! #
############################################################
.data
prompt: .asciiz "\nBitte geben Sie die Zahl ein, deren Fakultaet berechnet werden soll: n = "
message: .asciiz "\n Die Fakultaet von n ist:\n n! = "
.text
main:
# n einlesen und in $a0 ablegen
la $a0, prompt # Laden der Adresse des Strings prompt
li $v0, 4 # Der Wert 4 fuer den syscall bedeutet print string
syscall # Ausgabe des Strings prompt
li $v0, 5 # der Wert 5 fuer den syscall bedeutet read integer
syscall # n in $v0 einlesen
move $a0, $v0 # n in $a0 ablegen
# Wert fuer die Abbruchbedingung
li $s1, 1
# Aufruf des Unterprogramms fac
jal fac
move $t0, $v0 # in $v0 stand das Ergebnis, ablegen in $t0
la $a0, message # Laden der Adresse des Strings message
li $v0, 4 # der Wert 4 fuer den syscall bedeutet print string
syscall # Ausgabe des Strings message
move $a0, $t0 # Laden des Ergebnisses in $a0
li $v0, 1 # der Wert 1 fuer den syscall bedeutet print integer
syscall # Ausgabe des Ergebnisses
# exit
li $v0, 10
syscall
#################### Unterprogramm fac #####################
fac:
addi $sp, $sp, -8 # Auf dem Stack Platz fuer 2 Eintraege schaffen
sw $s0, 0($sp) # Sichern des Registers $s0
sw $ra, 4($sp) # Sichern der Ruecksprungadresse
add $s0,$zero,$a0 # laedt das Argument in $s0
beq $s0, $s1, done # wenn das Argument = 1 ist, springe zur Marke done, Abbruchbedingung
addi $a0, $a0, -1 # dekrementiere das Argument (n-1)
# rekursiver Aufruf mit n-1
jal fac
# hierhin wird bei Rueckkehr aus fac gesprungen, wenn fac sich selbst aufgerufen hat
mult $s0, $v0 # Ergebnis mit dem Argument multiplizieren
mflo $v0 # Produkt als Ergebnis zurueckgeben
j end # Sprung zur Marke end
done: # diese Zeile wird nur einmal ausgefuehrt, wenn fac mit a0=1 aufgerufen wurde
li $v0, 1 # ist das Argument = 1, wird 1 zurueckgegeben
end:
lw $s0, 0($sp) # Zuruecklesen des Registers $s0 vom Stack
lw $ra, 4($sp) # Zuruecklesen der Ruecksprungsadresse vom Stack
addi $sp, $sp, 8 # Stackpointer wieder auf den Wert vor Aufruf des Unterprogramms setzen
jr $ra # Ruecksprung
################# Ende des Unterprogramms fac ##################

View File

@@ -0,0 +1,87 @@
######################################################################################
# Liest eine natuerliche Zahl n <= 25 ein und gibt die ersten n Fibonacci-Zahlen aus #
## Leicht modifizierte Version der Datei Fibonacci.asm, die auf der MARS Website ##
#### unter 'Tutorial materials' zum Download zur Verfuegung steht: ####
##### http://courses.missouristate.edu/KenVollmar/mars/tutorial.htm #####
######################################################################################
.data
fibs: .word 0:25 #'array' fuer die berechneten Fibonaccizahlen
size: .word 25 # Groesse dieses 'arrays'
prompt: .asciiz "\nBitte geben Sie eine Zahl (n <= 25) an, n = "
.text
main:
la $s0, fibs # Adresse des 'arrays' laden
la $s5, size # Adresse der size Variable laden
lw $s5, 0($s5) # Arraygroesse laden
input:
# Einlesen und Ueberpruefen von n
la $a0, prompt # Adresse des Strings laden
li $v0, 4 # der Wert 4 fuer den syscall bedeutet print string
syscall # String ausgeben
li $v0, 5 # der Wert 5 fuer den syscall bedeutet: read integer
syscall # n einlesen, gelesener Wert steht in $v0
bgt $v0, $s5, input # Falls der eingegebene Wert groesser als 25 ist, neu einlesen
blt $v0, $zero, input # Falls der eingegebene Wert kleiner Null ist, neu einlesen
add $s5, $zero, $v0 # korrekt eingelesenen Wert in $s5 speichern
# Da die ersten beiden Fibonacci-Zahlen 1 sind, wird 1 direkt gespeichert
li $s2, 1
sw $s2, 0($s0) # F[0]=1
sw $s2, 4($s0) # F[1]=1
addi $s1, $s5, -2 # dient als Counter fuer die Schleife, laeuft n-2 mal
loop:
# Schleife zur Berechnung der Fibonaccizahlen
lw $s3, 0($s0) # Wert aus F[x-2] holen
lw $s4, 4($s0) # Wert aus F[x-1] holen
add $s2, $s3, $s4 # F[x] = F[x-2] + F[x-1]
sw $s2, 8($s0) # F[x] speichern
addi $s0, $s0, 4 # Inkrementieren der Adresse
addi $s1, $s1, -1 # Dekrementieren des Counters
bgtz $s1, loop # Wiederholen der Schleife loop, solange $s1>0
# Nach der Schleife liegen die Fibonacci-Zahlen vor und muessen noch ausgegeben werden
la $a0, fibs # Erster Parameter fuer die print Funktion ist das gefuellte array
add $a1, $zero, $s5 # Zweiter Parameter ist n (gespeichert in $s5)
jal print # Aufruf des Unterprogramms print
# exit
li $v0, 10
syscall
############ Unterprogramm zur Ausgabe der berechneten Fibonacci-Zahlen #########################
.data
space: .asciiz " " # Leerstelle, die zwischen den Zahlen eingefuegt wird
message: .asciiz "\nDie Fibonacci-Zahlen sind: \n"
.text
print:
add $t0, $zero, $a0 # Startadresse des arrays f<EFBFBD>r Ausgabe
add $t1, $zero, $a1 # counter
la $a0, message # Adresse des Strings 'message' laden
li $v0, 4 # Der Wert 4 fuer den syscall bedeutet print string
syscall # Ausgabe des Strings
loop2:
# Schleife zur Ausgabe der Zahlen
lw $a0, 0($t0) # Laden der aktuellen Fibonaccizahl
li $v0, 1 # der Wert 1 fuer den syscall bedeutet: print integer
syscall # Ausgabe der Zahl
la $a0, space # Laden der Adresse des Leerstellenstrings
li $v0, 4 # Der Wert 4 fuer den syscall bedeutet: print string
syscall # Leerstelle ausgeben
addi $t0, $t0, 4 # Inkrementieren der Adresse der auszugebenden Daten
addi $t1, $t1, -1 # Dekrementieren des counters
bgtz $t1, loop2 # Wiederholen der Schleife loop2, solange $t1>0
jr $ra # Ruecksprung zu main
############## Ende des Unterprogramms zur Ausgabe der Fibonacci-Zahlen ###########################

View File

@@ -0,0 +1,88 @@
########################################################################################
# Wandelt eine vorzeichenbehaftete 32-Bit-Integer-Zahl in die 32-Bit-IEEE-754-Form #
# um, legt diese an der Speicherstelle dst ab und gibt sie aus. #
# Aufgabe zur Code-Analyse der Pruefungsklausur Computersysteme im SS14, urspruenglich #
# in DLX-Assembler verfasst, uebersetzt und modifiziert von C. Hesseling im Jan 2017 #
########################################################################################
.data
src: .word 0xFFFFFF85
dst: .word 0xDEADBEEF
mask1: .word 0x80000000
mask2: .word 0xFFFFFFFF
mask3: .word 0x7FFFFF
message1: .asciiz "\nDie 32-Bit-IEEE-754-Darstellung ist binaer: "
message2: .asciiz " und hexadezimal: "
.text
# Laden der zu wandelnden Zahl und der Masken in die Register
lw $t1, src
lw $t2, mask1
lw $t3, mask2
lw $t4, mask3
# Bitweise UND-Verknuepfung mit Maske 1, Vorzeichentest, wenn Zahl positiv ist, springe zu m1
and $t5, $t1 , $t2
beqz $t5, m1
# Die beiden folgenden Zeilen werden nur ausgefuehrt, wenn die Ursprungszahl negativ ist:
# Bitweise Negation durch die Verwendung von Maske 2, danach Addition von 1,
# berechnet also das Zweierkomplement
xor $t1, $t1, $t3
addi $t1, $t1, 0x1
# Maske 1 in $t2 wird so verschoben, dass sie nun das Bit 30 statt Bit 31 extrahiert,
# der Zaehler in $t6 wird mit 0 initialisiert
m1: srl $t2, $t2, 1
and $t6, $zero, $zero
# Schleife: Der Inhalt von $t1 wird solange nach links verschoben, bis ein
# 1-Bit an Position 30 erkannt wird, dann wird zu m3 gesprungen,
# die Anzahl der Verschiebungen wird in Register $t6 gespeichert:
m2: and $t7, $t1, $t2
bnez $t7, m3
addi $t6, $t6, 1
sll $t1, $t1, 1
j m2
# In den folgenden Zeilen werden Charakteristik und Mantisse berechnet und
# das Ergebnis in $t5 abgelegt:
m3: # Berechnung der Charakteristik und Verknuepfung mit $t5
addi $t7, $zero, 30
sub $t6, $t7, $t6
addi $t6, $t6, 127
sll $t6, $t6, 0x17
or $t5, $t5, $t6
# Berechnung der Mantisse und Verknuepfung mit $t5
srl $t1, $t1, 0x7
and $t1, $t1, $t4
or $t5, $t5, $t1
# Ausgabe des Strings message1
la $a0, message1
li $v0, 4
syscall
# Ausgabe des Ergebnisses binaer
move $a0, $t5
li $v0, 35
syscall
# Ausgabe des Strings message2
la $a0, message2
li $v0, 4
syscall
# Ausgabe des Ergebnisses hexadezimal
move $a0, $t5
li $v0, 34
syscall
# Ablage des Ergebnisses an der Speicherstelle dst
sw $t5, dst
# exit
li $v0, 10
syscall

View File

@@ -0,0 +1,41 @@
################################################################################################
# Das Programm wandelt fuer ein Feld von Bytes jeweils das obere Nibble und anschliessend das #
# untere Nibble in die entsprechende ASCII-Darstellung um und speichert diese auf dem Stack. #
# Aufgabe zur Code-Analyse der Pruefungsklausur Computersysteme im WS14/15, #
# urspruenglich in DLX-Assembler verfasst, uebersetzt von C. Hesseling im Jan 2017 #
################################################################################################
.data
in: .byte 0x5d 0x18 0x2a 0x34 0x00
mask: .word 0xF
.text
la $t1, in # laedt die Adresse des byte-Arrays in $t1
lw $t2, mask # laedt die Maske mask in $t2
lb $t3, ($t1) # laedt ein Byte aus dem Byte-Array in $t3
addi $t1,$t1,1 # inkrementiert die Adresse, sodass bei erneutem Zugriff das naechste Byte geladen wird
beqz $t3, m2 # Beendet das Programm, wenn das geladene Byte = 0 ist
m1: srl $t4, $t3, 0x4 # Schiebt den Inhalt von $t3 um 4 nach rechts und speichert das Ergebnis in $t4
jal m3 # Sprung zu m3 (Pc+4 wird in Register 31 = $ra gespeichert)
and $t4, $t3, $t2 # bitweise UND-Verknuepfung von $t3 und der Maske in $t2, Ergebnis in $t4
jal m3 # Sprung zu m3 (PC+4 wird in Register 31 = $ra gespeichert)
lb $t3, ($t1) # Naechstes Byte aus dem Array laden
addi $t1, $t1, 1 # Adresse inkrementieren
bnez $t3, m1 # Sprung zu m1, falls das geladene Byte ungleich 0 ist
m2: li $v0, 10 # exit
syscall
m3: addi $t5,$t4,0x30 # 0x30 wird addiert, hier sind die ASCII-Zeichen ab '0' hinterlegt
slti $t6,$t4,0xA # falls das aktuelle Nibble > 10 ist, wird 0x7 addiert, um auf die Zeichen
bnez $t6,m4 # 'A' bis 'F' zu verweisen, sonst weiter mit Marke m4
addi $t5,$t5,0x7
m4: addi $sp, $sp, -4 # Praedekrement des Stackpointers
sb $t5, ($sp) # Sichern von $t5 auf dem Stack
jr $ra # Ruecksprung
################################################################################################
##### In der ASCII-Tabelle stehen die Zeichen fuer '0' bis '9' an der Stelle 48 bis 57, ###
##### die Zeichen 'A' bis 'F' stehen an der Stelle 65 bis 70 ####
################################################################################################

View File

@@ -0,0 +1,58 @@
################################################################
#
# Column-major order traversal of 16 x 16 array of words.
# Pete Sanderson
# 31 March 2007
#
# To easily observe the column-oriented order, run the Memory Reference
# Visualization tool with its default settings over this program.
# You may, at the same time or separately, run the Data Cache Simulator
# over this program to observe caching performance. Compare the results
# with those of the row-major order traversal algorithm.
#
# The C/C++/Java-like equivalent of this MIPS program is:
# int size = 16;
# int[size][size] data;
# int value = 0;
# for (int col = 0; col < size; col++) {
# for (int row = 0; row < size; row++) }
# data[row][col] = value;
# value++;
# }
# }
#
# Note: Program is hard-wired for 16 x 16 matrix. If you want to change this,
# three statements need to be changed.
# 1. The array storage size declaration at "data:" needs to be changed from
# 256 (which is 16 * 16) to #columns * #rows.
# 2. The "li" to initialize $t0 needs to be changed to the new #rows.
# 3. The "li" to initialize $t1 needs to be changed to the new #columns.
#
.data
data: .word 0 : 256 # 16x16 matrix of words
.text
li $t0, 16 # $t0 = number of rows
li $t1, 16 # $t1 = number of columns
move $s0, $zero # $s0 = row counter
move $s1, $zero # $s1 = column counter
move $t2, $zero # $t2 = the value to be stored
# Each loop iteration will store incremented $t1 value into next element of matrix.
# Offset is calculated at each iteration. offset = 4 * (row*#cols+col)
# Note: no attempt is made to optimize runtime performance!
loop: mult $s0, $t1 # $s2 = row * #cols (two-instruction sequence)
mflo $s2 # move multiply result from lo register to $s2
add $s2, $s2, $s1 # $s2 += col counter
sll $s2, $s2, 2 # $s2 *= 4 (shift left 2 bits) for byte offset
sw $t2, data($s2) # store the value in matrix element
addi $t2, $t2, 1 # increment value to be stored
# Loop control: If we increment past bottom of column, reset row and increment column
# If we increment past the last column, we're finished.
addi $s0, $s0, 1 # increment row counter
bne $s0, $t0, loop # not at bottom of column so loop back
move $s0, $zero # reset row counter
addi $s1, $s1, 1 # increment column counter
bne $s1, $t1, loop # loop back if not at end of matrix (past the last column)
# We're finished traversing the matrix.
li $v0, 10 # system service 10 is exit
syscall # we are outta here.

View File

@@ -0,0 +1,60 @@
#############################################################################
# Row-major order traversal of 16 x 16 array of words.
# Pete Sanderson
# 31 March 2007
#
# To easily observe the row-oriented order, run the Memory Reference
# Visualization tool with its default settings over this program.
# You may, at the same time or separately, run the Data Cache Simulator
# over this program to observe caching performance. Compare the results
# with those of the column-major order traversal algorithm.
#
# The C/C++/Java-like equivalent of this MIPS program is:
# int size = 16;
# int[size][size] data;
# int value = 0;
# for (int row = 0; col < size; row++) {
# for (int col = 0; col < size; col++) }
# data[row][col] = value;
# value++;
# }
# }
#
# Note: Program is hard-wired for 16 x 16 matrix. If you want to change this,
# three statements need to be changed.
# 1. The array storage size declaration at "data:" needs to be changed from
# 256 (which is 16 * 16) to #columns * #rows.
# 2. The "li" to initialize $t0 needs to be changed to new #rows.
# 3. The "li" to initialize $t1 needs to be changed to new #columns.
#
.data
data: .word 0 : 256 # storage for 16x16 matrix of words
.text
li $t0, 16 # $t0 = number of rows
li $t1, 16 # $t1 = number of columns
move $s0, $zero # $s0 = row counter
move $s1, $zero # $s1 = column counter
move $t2, $zero # $t2 = the value to be stored
# Each loop iteration will store incremented $t1 value into next element of matrix.
# Offset is calculated at each iteration. offset = 4 * (row*#cols+col)
# Note: no attempt is made to optimize runtime performance!
loop: mult $s0, $t1 # $s2 = row * #cols (two-instruction sequence)
mflo $s2 # move multiply result from lo register to $s2
add $s2, $s2, $s1 # $s2 += column counter
sll $s2, $s2, 2 # $s2 *= 4 (shift left 2 bits) for byte offset
sw $t2, data($s2) # store the value in matrix element
addi $t2, $t2, 1 # increment value to be stored
# Loop control: If we increment past last column, reset column counter and increment row counter
# If we increment past last row, we're finished.
addi $s1, $s1, 1 # increment column counter
bne $s1, $t1, loop # not at end of row so loop back
move $s1, $zero # reset column counter
addi $s0, $s0, 1 # increment row counter
bne $s0, $t0, loop # not at end of matrix so loop back
# We're finished traversing the matrix.
li $v0, 10 # system service 10 is exit
syscall # we are outta here.

BIN
MARS/Tutorials/HowTo.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Neu/Nand2Tetris.odt Normal file

Binary file not shown.

BIN
asm/ASM-Simulator.jar Normal file

Binary file not shown.

BIN
asm/How-To.pdf Normal file

Binary file not shown.