1.3 ALU-Funktion und Simulation mit VisUAL2
Präsentation: Funktionsweise ALU und Flags
Seltsame Unterschiede zwischen STM32CubeIDE und VisUAL2
- Kommentare in Cube mit // in VisUAL mit ;
- Marken werden in VisUAL ohne : am Ende definiert
- In Cube IDE kann # oft weggelassen werden
- In VisUAL geht bx lr nicht, verwende mov pc,lr
- VisUAL2 kann keinen mul-Befehl?! 😭
Addition, Subtraktion und Flags
Mission: Übersetze in Assembler mit Hilfe der Formelsammlung und simuliere mit VisUAL2
Das sollte dazu schon verstanden worden sein: Ganzzahlige und negative Zahlen, Ausdrücke und Operationen.
// C/Java-Code
r0 = 5;
r1 = r0 + 10;
r2 = r0 - r1;
r2 = r2 + 10;
; ARM-Assember-Code
mov r0,#5
add r1,r0,#10
sub r2,r0,r1
add r2,r2,#10
Aufgaben
// C/Java-Code
R0 = 10;
R1 = R0 + 5;
R2 = R0 + R1;
R3 = R0 - R1;
Lösung
mov R0,#10
add R1,R0,#5
add R2,R0,R1
sub R3,R0,R1
end
// C/Java-Code
R0 = 0b1110;
R1 = R0 & 0b0101; // Bitweises Und
R2 = R0 | 0b0101; // Bitweises Oder
R3 = -R0; // Negation, 2er Komplement
R4 = ~R0; // Bitweises Invertieren, 1er Komplement
Lösung
mov R0,#0b1110
and R1,R0,#0b0101
orr R2,R0,#0b0101
mov R3,#0
sub R3,R3,R0
mvn R4,R0
Flags N,Z,C,V werden mit angehängtem ‘s’ gesetzt
; ARM-Assember-Code
movs r0,#5
adds r1,r0,#10
subs r2,r0,r1
adds r2,r2,#10
Für bedingte Verzweigungen sind die Nebenergebnisse einer ALU-Operation von Interesse: Ist das Ergebnis negativ (negative), ist es Null (Zero), gibt es einen Überlauf (Carry) usw. Um diese Nebenergebnisse in Flags zu speichern, um sie bei nachfolgenden bedingten Verzweigungen verwenden zu können muss ein ‘s’ an die Assembler-Befehle angehängt werden. Rechts unten in VisUAL werden diese als Flags angezeigt N = Negative, Z = Zero, C = Carry und V = Overflow
Beobachte beim Steppen durch das Programm diese Flags rechts unten bei VisUAL2. Die Operationen verändern die Flags.
Beispiele und Aufgaben zu Flags
Unbedingte Sprünge mit b (Branch)
Um an eine bestimmte Stelle im Programm zu springen benutze den b (Branch) Befehl. Der Assembler hilft die Adresse der Einsprungstelle bequem markieren zu können mit Marken (engl. Label). Wenn eine Marke vor einen Befehl gesetzt wird, merkt sich der Assembler die Speicherstelle des Befehls hier subs mit der Adresse 0x4. Beim Sprungbefehl wird beim Assemblieren der Wert der Marke in den Maschinenbefehl eingefügt.
mov r0,#2
marke subs r0,r0,#1
b marke ; springe zu marke
Bedingte Sprünge, das Prinzip
Bedingte Sprünge werden in Abhängigkeit der Werte der Flags N,Z,C,V ausgeführt. Damit lässt sich das bedingte Verhalten von if-else, switch, while, do-while. und for realisieren. In der Formelsammlung stehen die Bedingungen. Z.B. bne also branch if not eq (equal), wenn zwei gleiche Zahlen abgezogen werden, ist das Ergebnis nicht 0, also z=0. Oder wenn das Ergebnis einer Operation nicht 0 ist, also nicht equal to Zero -> Z=0. Dann wird bei NE gesprungen.
mov r0,#2
marke subs r0,r0,#1
bne marke ; != 0 dann marke
r0 = 2;
while (r0 != 0){
r0 = r0 - 1;
}
if-else-Anweisung
Um Werte zu vergleichen werden sie schlicht von einander abgezogen also r0>10 wird zu r0-10 und dabei werden die Flags gesetzt, die leistet der cmp (Compare) Befehl. Bei signed werden auch negative Werte zugelassen. Mit welchen Werten für r0 sollten Sie den Code testen? Versuchen Sie den C-Code zu assemblieren und decken sie die rechten Lösungen zunächst ab 😁.
r0 = 11; // Werte zum Testen
if (r0>10){
r1 = 1;
} else {
r1 = 0;
}
mov r0,#11
cmp r0,#10 ; r0-10 Flags setzen
bgt true ; r0>10?
mov r1,#0
b ende
true mov r1,#1
ende
while-Schleife
Welche Werte nimmt r1 während der Schleife an, welchen Wert hat r0 nach der Schleife?
Testen Sie den Code. Erstellen Sie einen PAP.
r0 = 0;
while(r0<=5){
r1 = r0;
r0++;
}
mov r0,#0
while cmp r0,#5
bgt ende
mov r1,r0
add r0,r0,#1
b while
ende
Lösung PAP
for-Schleife
Welche Werte nimmt r1 während der Schleife an, welchen Wert hat r0 nach der Schleife? Testen Sie den Code. Erstellen Sie einen PAP.
for(r0=3;r0<6;r0++){
r1 = r0;
}
mov r0,#3
for cmp r0,#6
bge ende
mov r1,r0
add r0,r0,#1
b for
ende
Lösung PAP
do-while-Schleife
Welche Werte nimmt r1 während der Schleife an, welchen Wert hat r0 nach der Schleife? Testen Sie den Code. Erstellen Sie einen PAP.
r0 = 4;
do{
r1 = r0;
r0--;
} while (r0>0);
mov r0,#4
do mov r1,r0
subs r0,r0,#1
bgt do
ende
Lösung PAP
switch-Anweisung
Welche Werte nimmt r1 für die Testwerte 0,1,2,-1 für r0 an? Erstellen Sie einen PAP.
r0 = 2; // Werte zum Testen
switch (r0){
case 0:
r1 = 100;
break;
case 1:
case 2:
r1 = 200;
break;
default:
r1 = 0;
}
mov r0,#2
cmp r0,#0 ; case 0
beq case0
cmp r0,#1 ; case 1
beq case1
cmp r0,#2 ; case 2
beq case1
mov r1,#0 ; default
b ende
case0 mov r1,#100
b ende
case1 mov r1, #200
ende
Lösung PAP
Einfacher Unterprogramm-Aufruf
Unterprogramme werden mit dem bl label (Branch Linked) Befehl aufgerufen, dabei wird die Adresse des dem Aufruf Befehls folgenden Befehls im LR-Register (R14) gespeichert, damit am Ende des Unterprogramms wieder die richtige Stelle des aufrufenden Programmteils zurückgesprungen werden kann. Für den Rücksprung aus dem Unterprogramm wird bei STM32 der Befehl bx lr und bei Visual2 mov pc, lr (move ProgramCounter <- LinkRegister) ausgeführt.
In diesem Beispiel werden noch keine Parameter und Rückgabewerte betrachtet, es wird nur auf globale Variablen zugegriffen.
Testen Sie das Assemblerprogramm: Achten Sie dabei auf die Register LR (R14) und PC (R15).
Erstellen Sie einen PAP.
int r0 = 2; // Testwert
int r1 = 1; // Testwert
void main(){ // Hauptprogramm
max(); // Unterprogrammaufruf
r1 = 4;
max();
}
void max(){
if (r1>r0) r0=r1;
}
mov r0,#2
mov r1,#1
main bl max ; Unterprogrammaufruf
mov r1,#4
bl max
end ; Pseudobefehl Programm zu Ende
max cmp r1,r0
ble maxend
mov r0,r1
maxend mov pc,lr ; bx lr bei STM32
Lösung PAP
Mögliche Aufgabenmuster
- C/Java Programm -> Assembler mit PAP, dazu Fragen zu Werten, Tabelle mit Ein- Ausgabewerten bzw. Werteverlauf
- Assembler-Programm -> PAP erstellen und Code analysieren, Tabelle mit Ein- Ausgabewerten bzw. Werteverlauf
- Textuelle Beschreibung von Problem -> PAP und Assembler
- Tabelle mit Ein- Ausgabeverhalten -> PAP und Assembler
Assembler-Befehle ausführen
Die Ergebnisse nach der Ausführung der Assembler-Befehle sollen in die Tabelle eingetragen werden. N,Z,C sind die gesetzten Flags durch den Befehl. Hex,Dec,Bin ist das Format in dem in den Spalten R0,R1 die Werte von R0 und R1 nach der Ausführung des Befehls angezeigt werden sollen. Sie können mit Visual2 Ihre Ergebnisse überprüfen.
Befehl | N | Z | Hex | Bin | Dec | R0 | R1 |
---|---|---|---|---|---|---|---|
movs r0,#1 | 0 | 0 | X | 1 | 0 | ||
add r1,r0,#10 | 0 | 0 | X | 0b1 | 0b1011 | ||
subs r1,r0,#1 | X | ||||||
subs r1,r0,#3 | X | ||||||
ands r1,r1,#0x7 | X | ||||||
orrs r1,r0,#0x10 | X | ||||||
movs r1,#0x20 | X | ||||||
tst r1,#0b10110 | X | ||||||
movs r1,#-1 | X | ||||||
mvns r0,#2 | X |
Code für Visual
movs r0,#1
add r1,r0,#10
subs r1,r0,#1
subs r1,r0,#3
ands r1,r1,#0x7
orrs r1,r0,#0x10
movs r1,#0x20
tst r1,#0b10110
movs r1,#-1
mvns r0,#2
Spass mit Modulo-Operator % und bitweisem Und &
Welche Werte hat das Register nach der jeweiligen Operation?
Der Modulo-Operator % gibt den Rest einer Division zurück.
Lösung
r0 | r0%2 | r0&1 | r0%4 | r0&3 | r0&6 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 0 |
2 | 0 | 0 | 2 | 2 | 2 |
3 | 1 | 1 | 3 | 3 | 2 |
4 | 0 | 0 | 0 | 0 | 4 |
5 | 1 | 1 | 1 | 1 | 4 |
r0 | r0%2 | r0&1 | r0%4 | r0&3 | r0&6 |
---|---|---|---|---|---|
0 | 0 | ||||
1 | 1 | ||||
2 | 0 | ||||
3 | 1 | ||||
4 | 0 | ||||
5 | 1 |
Aufgabe if-Anweisung1
r0=-1; // Testwerte
if(r0<0) r0=0;
else if(r0>3) r0=3;
Erstellen Sie eine eine Tabelle mit Testwerten und erwarteten Ergebnissen. Begründen Sie die Wahl ihrer Testwerte. Übersetzten Sie Assembler und überprüfen Sie Ihr Programm mit den Testwerten. Erstellen Sie einen PAP.
Lösung Tabelle
r0 vorher | r0 nachher |
---|---|
-1 | 0 |
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 3 |
Lösung Begründung
Testen mit negativer Zahl, 0, und immer um die Grenzwerte der Bedingungen um Fehler zu entdecken.
Lösung Assembler
mov r0,#-1
cmp r0,#0
bge else
mov r0,#0
b ende
else cmp r0,#3
ble ende
mov r0,#3
ende
Lösung PAP
Textaufgabe1
Der Wertebereich des Registers r0 soll auf {-2..2} begrenzt werden, erstellen Sie PAP, Assembler, Testtabelle..
Lösung Assembler
mov r0,#3 ; Testwerte
cmp r0,#-2
bge else
mov r0,#-2
b ende
else cmp r0,#2
ble ende
mov r0,#2
ende
Aufgabe while-Schleife1
r0 = 1;
while(r0<16){
r0 = r0<<1;
ausgeben(r0); // Ausgabe auf LEDs
}
Welche Werte in Binär werden ausgegeben?
Welchen Wert hat r0 nach der while-Schleife?
Assemblieren Sie (ausgeben(r0) weglassen) und testen Sie die Werte für r0.
Erstellen Sie einen PAP.
Lösungsvorschlag Assembler
mov r0,#1
while cmp r0,#16 ; r0-16 setzt Flags
bge ende ; r0>=16?
lsl r0,r0,#1
b while
ende
Lösungsvorschlag PAP
Aufgabe while-Schleife2
r0 = 64;
while(r0>0){
r0 = r0>>1;
}
Welche Werte in Binär nimmt r0 an?
Assemblieren und testen Sie.
Erstellen Sie einen PAP.
Was würde bei der Bedingung r0>=0 passieren?
Lösungsvorschlag Assembler
mov r0,#64
while cmp r0,#0 ; r0-0 setzt Flags
ble ende ; r0<=0?
lsr r0,r0,#1
b while
ende
Lösungsvorschlag PAP
Aufgabe while-Schleife3
Welche Werte in Binär nimmt r0 an?
Assemblieren und testen Sie.
Erstellen Sie einen PAP.
r0 = 1;
while(r0<32){
r0 = r0*2+1;
}
Lösungsvorschlag Assembler
mov r0,#1
while cmp r0,#32 ; r0-32 setzt Flags
bge ende ; r0>=32?
lsl r0,r0,#1
add r0,r0,#1
b while
ende
Lösungsvorschlag PAP
Was würde bei r0=r0<<1+1 passieren?
Siehe https://mezdata.de/pi-basis/010_ausdruecke/index.php
Aufgabe SPS-Schaltung
r0 = testwert;
if((r0&0b11)==0b11){
r0 |= 0b100;
}else{
r0 &= ~0b100;
}
// welchen Wert hat r0[2] jetzt?
Erklären Sie mit Beispiel bitweises und &, bitweises oder |, Zuweisungen |=, &=, bitweises Invertieren ~.
Erstellen Sie eine Tabelle mit Testwerten für r0: 0..7 und den Ergebnissen nach Ausführung des Codes.
Welche logische Funktion wird dabei simuliert?
Hinweis: Einzelne Bits in einem Register werden in [] Klammern dargestellt, z.B. r0[1:0] meint die Bits 1 und 0 in Register r0.
Erstellen und testen Sie den Assemblercode, r0[1:0] dürfen dabei nicht verändert werden. Tipp: Verwenden Sie ggfs. ein Hilfsregister, z.B. r1.
Erstellen Sie einen PAP dazu.
Lösungsvorschlag Assembler
mov r0,#3 ; Testwert
and r1,r0,#0b11 ; Maske
cmp r1,#0b11 ; r1-0b11 setzt Flags
bne else
orr r0,r0,#0b100
b ende
else bic r0,r0,#0b100
ende
Lösungsvorschlag PAP
Bonus-Aufgabe Fakultätsfunktion fak(n:GZ):GZ
Erstellen Sie ein C/Java-Programm für die Fakultätsfunktion https://de.wikipedia.org/wiki/Fakultät_(Mathematik)
Erstellen Sie ein Assembler-Programm wobei r0 den Eingabeparameter enthält und r1 den Rückgabewert.
Testen Sie das Programm mit den Werten 0,1,2,4,6.
Das wäre mein Lösungsversuch, leider kann VisUAL2 kein mul…
int r0,r1; // Glob. Variablen
main(){
r0 = 1; // Testwerte
fak();
}
void fak(){
int r2=2;
r1=1;
while (r2<=r0){
r1=r1*r2;
r2++;
}
}
mov r0,#1 ; Testwerte
bl fak ; Unterprogrammaufruf
end
fak mov r1,#1
mov r2,#2
while cmp r2,r0
bgt fakend
mul r1,r1,r2
add r2,r2,#1
b while
fakend mov pc,lr