Rechnerstrukturen 1, Sommersemester 2020
3. Aufgabe: MIPS-Assemblerprogramm
Mit dem unten aufgeführten Abschnitt eines C-Programms wird das Skalarprodukt der Vektoren, die in den Feldern iVec1 und iVec2 gespeichert sind, gebildet und mit 5 multipliziert, falls der berechnete Wert von iSkalar < iVergleichswert ist. Das endgültige Ergebnis wird im aktuellen Element des Vektors iSkalar gespeichert. Der Wert der Variable iVLength gibt die Zahl der Elemente je Vektor an.
Zur Vereinfachung der Lösung können Sie annehmen, dass es für die Multiplikation von zwei Registerinhalten einen Assemblerbefehl der Form
mult $RegZiel, $RegQ1, $RegQ2 (z. B.: mult $t2, $t3, $t4 realisiert $t2 = $t3∙$t4)
gibt. Es ist sichergestellt, dass das Produkt der Multiplikation die 32-bit Wortbreite des MIPS nicht überschreitet. Der Speicher wird byteweise adressiert.
Bevor Sie den dargestellten C-Programmabschnitts mit MIPS-Assemblerbefehlen codieren, legen Sie in einer Tabelle fest, welche Variablen welches MIPS-Register belegen soll.
int iVec1[1024][32], iVec2[1024][32], iSkalar[1024], iFlag[1024]; int iVLength, iAnzSkalar;
int iVergleichswert;
int iI, iJ;
for (iI = 0; iI < iAnzSkalar; iI = iI +1) { iSkalar[iI] = 0;
iFlag[iI] = 1;
for (iJ = 0; iJ < iVLength; iJ = iJ +1) {
iSkalar[iI] = iSkalar[iI] + (iVec1[iI][iJ] ∙ iVec2[iI][iJ]); }
if (iSkalar[iI] < iVergleichswert) {
iFlag[iI] = -1;
/* folgende Multiplikation ohne mult-Befehl realisieren */ iSkalar[iI] = iSkalar[iI] ∙ 5;
} }
1 Rüffer, 2020
Rechnerstrukturen 1, Sommersemester 2020
2 Rüffer, 2020
Rechnerstrukturen 1, Sommersemester 2020
$t0 ←
$t2 ←
$t3 ←
$t4 ←
$t5 ←
$t6 ←
rel. Adressse iV ec1[iI][iJ], iV ec2[iI][iJ] iAnzSkalar
iVLength
iVergleichswert
akt. Wert iSkalar[iI] akt. Wert iFlag[iI]
$t7 $t8 $t9
$s0 $s1
← ← ←
← ←
Wert iVec1[iI][iJ] Wert iVec2[iI][iJ] Entscheidungsregister
iI iJ
3
Rüffer, 2020
Rechnerstrukturen 1, Sommersemester 2020
FOR1:
add $s0, $0, $0
lw $t2, iAnzSkalar($0)
sll $t2, $t2, 2
lw $t3, iVLength($0)
sll $t3, $t3, 2
lw $t4, iVergleichswert($0)
slt $t9, $s0, $t2 beq $t9, $0, ENDF1
add $t5, $0, $0 addi $t6, $0, 1 add $s1, $0, $0 sll $t0, $s0, 5
slt $t9, $s1, $t3 beq $t9, $0, ENDF2
add $t0, $t0, $s1
lw $t7, iV ec1($t0) lw $t8, iV ec2($t0) mult $t9, $t7, $t8 add $t5, $t5, $t9 addi $s1,$s1,4
j FOR2
slt $t9, $t5, $t4 beq $t9, $0, FI
addi $t6, $0, -1 sll $t9, $t5, 2 add $t5, $t5, $t9
sw $t6, iFlag($s0) sw $t5, iSkalar($s0) addi $s0,$s0,4
j FOR1
#iI=0
#$t2= iAnzSkalar #$t2= iAnzSkalar ∙ 4 #$t3= iVLength #$t3= iVLength ∙ 4 #$t4= iVergleichswert
#$t9= 1, wenn iI < iAnzSkalar # 0 sonst
# akt. Wert iSkalar[iI] = 0
# akt. Wert iFlag[iI] = 1
#iJ=0
# rel. Zeiger für iVec1[iI][0] und iVec2[iI][0] erzeugen # shiftamount = ld(32)
# $t9 = 1, wenn iJ < iVLength
# rel. Zeiger für iVec1[iI][iJ] und iVec2[iI][iJ] # erzeugen
# $t5 = iVec1[iI][iJ]
# $t6 = iVec2[iI][iJ]
# $t9 = iVec1[iI][iJ] ∙ iVec2[iI][iJ]
# $t9 = 1, wenn iSkalar[iI] < iVergleichswert
# iFlag[iI] = -1
# $t5 = 4 ∙ iSkalar[iI] # $t5 = 5 ∙ iSkalar[iI]
FOR2:
ENDF2:
FI:
ENDF1: nop
4 Rüffer, 2020
Rechnerstrukturen 1, Sommersemester 2020
Anordnung der Feldelemente
Abbildung im Speicher (byteweise Adressierung)
5 Rüffer, 2020