Rechner, Hardware und Assembler

Transcrição

Rechner, Hardware und Assembler
Einführung in die
Informatik I
Prinzipieller Aufbau eines Rechners und Assembler Programmierung
Prof. Dr. Nikolaus Wulff
Aufbau eines Rechners
1. LCD Bildschirm
2. Hauptplatine
3. Prozessor
4. Speicherbausteine
5. externe Controller
6. Netzteil
7. CD Laufwerk
8. Festplatte
9. Maus
10.Tastatur
Prof. Dr. Nikolaus Wulff
Informatik I
2
Zentrale Bausteine
•
•
•
•
Rechenwerk / CPU (ALU)
Arbeitsspeicher
Festplatte(n)
E/A Module
– Grafikkarte
– Tastatur und Maus Controller
• Bus System
– Datenbus
– Adressbus
– Steuerbus
Prof. Dr. Nikolaus Wulff
Informatik I
3
Harvard Architektur
• Unterschiedlicher Speicher für Daten und Programme.
• Vorteil: Strikte Trennung von Daten und Programm.
– Viren haben es schwerer Programme zu manipulieren
• Nachteil: Zwei verschiedene Speicher und unter
Umständen „Verschwendung von Speicher“.
Prof. Dr. Nikolaus Wulff
Informatik I
4
Die von Neumann Architektur
• Der Speicher beinhaltet Programm und Daten.
• Eine Bitfolge kann Datum oder Programm sein...
Prof. Dr. Nikolaus Wulff
Informatik I
5
Prinzip des von Neumann-Rechners
• Interne Befehlssignale sind binär codiert.
• Befehle, Adressen und Daten werden einheitlich im
Speicher abgelegt.
• Es werden Worte fester Bit-Länge abgearbeitet.
• Der Daten- und Befehlsstrom wird von einem Bus auf
Anforderung geliefert.
• Sequentielle, taktgesteuerte Verarbeitung.
• CPU und Bus haben unterschiedliche Taktfrequenzen.
– Es gibt inzwischen mehrere Bussysteme: Grafikkarte AGP,
Hauptspeicher, L1 und L2 Cache, etc.
Prof. Dr. Nikolaus Wulff
Informatik I
6
CPU & ALU
Prof. Dr. Nikolaus Wulff
Informatik I
7
Aufteilung der CPU
• Die CPU (central processing unit) unterteilt sich in
das Steuerwerk:
– Befehlszähler (Adresse des nächsten Befehls)
– Befehlsregister (Menomic des aktuellen Befehls)
– Adressregister (Adresse des nächsten Datums)
• und das Rechenwerk:
– ALU (arithmetic and logical unit)
– mehrere Register für Berechnungen (aktuelle Daten)
• EAX, EBX, ECX, ...
– Zusatzregister (Flags) für Status
• Over- & Underflow, Vorzeichen-Bit, Zero-Bit, etc.
Prof. Dr. Nikolaus Wulff
Informatik I
8
Das BIOS
• Damit der Rechner in einen betriebsbereiten Zustand
gelangt und mit den Peripheriegeräten kommunizieren
kann, wird das Basic- Input-Output-System beim Start
geladen.
• Hersteller hinterlegen hier ihre eigene Treiber z.B. für
den Festplattencontroller und den Chipsatz.
• Dieses BIOS stellt durch (Software) Interrupts standardisierte Schnittstellen zur Verfügung. Bei DOS ist
das z. B. der Interrupt 21h. Linux Systeme verwenden
Interrupt 80h.
• Interrupts werden direkt in Assembler angesprochen.
Prof. Dr. Nikolaus Wulff
Informatik I
9
Register des 8086
• Die modernen CPU's bauen auf ihren „Urvätern“ den
8086 16-Bit und 8008 8-Bit Prozessoren auf:
all purpose register
accumulator
status register
loop counter
data i/o
instruction pointer
code segment
data segment
stack segment
extra segment
stack pointer
base pointer
string source
string dest.
– Da sich mit 16-Bit nur 216=64 kByte adressieren lassen
werden die DS,CS,SS,ES Register als Offset verwendet.
– Der 80386 hat 32-Bit Register EAX, EBX etc.
Prof. Dr. Nikolaus Wulff
Informatik I
10
Prinzip von Maschinencode
• Maschinencode wird sequentiell ausgeführt. Z.B. lade
den Wert der Variablen x in das Register EAX und
addiere dazu den Wert 5, anschließend schreibe
diesen Wert zurück in die Variable x.
• Maschinencode besteht aus ganz grundlegenden,
einfachen Anweisungen.
• Das Ein- und Auslesen der Variablen x aus dem
Hauptspeicher, erfolgt mittels entsprechender
Kommunikation des Steuerwerks mit dem Datenbus.
• Jede CPU hat einen anderen Befehlssatz und
entsprechend unterscheiden sich auch die
Assemblerbefehle. Sie sind nicht plattformneutral.
Prof. Dr. Nikolaus Wulff
Informatik I
11
Einige Assembler Befehle
• add: Addition von Ganzzahlen. I.A. wird der Inhalt
eines Registers oder einer Speicheradresse zum
Akkumulator addiert. add bx
• mov: Lese- oder Schreibbefehl von einer
Speicheradresse zum Register oder zurück.
mov ax, ds:[bx]
• inc / dec: Inkrementiere oder Dekrementiere das
angegebene Register. inc bx
• jmp: Fahre mit der Bearbeitung an der angegeben
Stelle fort. jmp 010h oder jmp Label_A
• push/pop: Sichere/restauriere Register push bx
Prof. Dr. Nikolaus Wulff
Informatik I
12
Intel und AT&T Syntax
1. Assembler Sprache ist abhängig von der Ziel CPU.
2. Intel und AT&T (GNU) Assembler haben eine
unterschiedliche Syntax:
Intel
mov eax,
1
mov ebx,0ffh
mov ebx, eax
AT&T
movl
$1, %eax
movl $0xff, %ebx
movl %eax, %eax
mov eax,[ecx]
add eax,[ebx+ecx]
movl (%ecx),%eax
addl (%ebx,%ecx),%eax
• Assembler-Code ist meist unportabel und schwerer zu
warten als Hochsprachen-Code.
Prof. Dr. Nikolaus Wulff
Informatik I
13
Beispiel eines encoding
• Alle Befehle liegen als Binärfolgen vor. Um z.B. den
Assemblerbefehl: add word_array[bx+di],-3
• binär zu codieren, muss die entsprechende Befehlsfolge aus den 8086 Datenblättern entnommen werden:
– Befehl add: 100000sw mod reg rm
– (s: sign) (w: word) sw=112 100000112 = 8316
– mod: indirect 16 bit = 102 , reg =000, rm=ds:[bx+di]=0012
=> 100000012 = 8116
– Addresse von word_array 10EF16 (als Beispiel)
– -310 = FD16
Befehlsfolge: 83 81 EF 10 FD
• So zu programmieren ist keine gute Idee...
Prof. Dr. Nikolaus Wulff
Informatik I
14
Maschinencode und Hochsprache
• Der Vorteil von Hochsprachen wie C liegt auf der
Hand: Statt im „nackten Maschinenhexcode“
83 81 EF 10 FD
• oder als Assembleranweisung
add word_array[bx+di],-3
• wird in C wesentlich lesbarer codiert:
word_array[i] -= 3;
– Variable i ist der Index, der im Register bx gehalten wird
– word_array und i sind woanders deklariert...
• Letztendlich wird der C Quelltext vom Compiler in
den Maschinencode übersetzt.
Prof. Dr. Nikolaus Wulff
Informatik I
15
Assembler ohne Schleifen
• Mit Assembler können nur Konstrukte verwendet
werden, die von der CPU direkt als Maschinencode
abgearbeitet werden können.
• Es gibt keine if-else und switch-case Anweisungen
und auch for- oder while-Schleifen fehlen.
• Diese Konstrukte müssen mit Sprungziel (label) und
goto Anweisung (jmp) selber codiert werden.
• Assembler Code ist daher nicht nur unleserlich,
sondern auch ziemlich fehlerträchtig im Vergleich zu
Hochsprachen wie Java oder C. Allerdings lassen sich
hier alle Vorteile der Hardware effizient ausnutzen.
Prof. Dr. Nikolaus Wulff
Informatik I
16
if-else mit Assembler
org 100h
mov ah, 01h
int 021h
cmp al, '5'
ja L1
mov dx,msg_1
mov ah,9h
int 021h
jmp ende
L1: mov
mov
int
ende:
mov
int
; Fkt 1: Wert über die Tastatur einlesen
; DOS Interrupt 21h ausfuehren
; Tastaturwert mit ASCII '5' vergleichen
;
;
;
;
;
dx,msg_2
ah,9h
021h
;
ah,4Ch
21h
;
;
char *msg_1 = "Zahl <= 5\n";
Falls groesser 5 springe zu Label L1
char *msg_2
= "Zahl laden
>5\n";
Adresse
der Zeichenkette
Fkt 9: Zeichenkette ausgeben
Meldung 1 mit Interrupt 21h ausgeben
int main() {
Sprung zum Label ende
int x = getchar();
if (x <= '5')
printf(msg_1);
Meldung 2 ausgeben
else
Fkt 4C: printf(msg_2);
Beende das Programm
Programm
beenden
return
0;
}
section .data
msg_1: db 'Zahl <= 5', 10, '$'
msg_2: db 'Zahl > 5' , 10, '$'
Prof. Dr. Nikolaus Wulff
Codebereich
Informatik I
Datenbereich
17
JMP Befehle
• Die Sprungbefehle jmp ende und ja L1 sind gegen
symbolische Konstanten (Label) definiert, die vom
Assembler in Sprungadressen umgesetzt werden, auf
die der Instruktionszähler IP dann entsprechend
gesetzt wird.
• Die Bearbeitung des Programms geht dann weiter mit
den Befehlen, auf die der IP zeigt.
• Ähnlich aufwändig ist das Programmieren von
Schleifen.
Prof. Dr. Nikolaus Wulff
Informatik I
18
Assembler Schleife
mov cx, 7
mov ax, 1
mov bx, 1
label_1:
mul bx
inc bx
dec cx
jne label_1
; counter register auf 7
; accumulator auf 1
; multipikator auf 1
;
;
;
;
ax = ax*bx
bx = bx + 1 = bx++
cx = cx – 1 = cx-- falls cx==0 wird ZF=1
(Jump Not Equal) ZF!=1, d.h. solange cx>0
int c=7, b=1, a=1;
int c, a=1;
while (c) {
a *=b;
b++;
c--;
}
for (c=2; c<=7; c++) {
a *=c;
}
Prof. Dr. Nikolaus Wulff
7
a= ∏c=1 c ≡ 7!
Informatik I
19
C Code und Assembler
• Der C Code wird in mehren Phasen übersetzt.
• Meist ist eines der Zwischenergebnisse Assemblercode, der mit dem Debugger angezeigt werden kann.
• Für zeitkritische Anwendungen kann hier optimiert
werden. I. A. ist dies jedoch den Aufwand nicht wert.
• Der Assemblercode ist hilfreich, um zu verstehen, wie
Maschinencode abgearbeitet wird und wo Optimierungsmöglichkeiten sind.
• Dies ist dies eine gute Möglichkeit, um das Zusammenspiel der unterschiedlichen Register einer CPU zu
verstehen.
Prof. Dr. Nikolaus Wulff
Informatik I
20
C / Assembler Beispiel
• Das folgende Beispiel wurde ohne Optimierung
übersetzt und zeigt C und Assembler Code parallel.
• Das Programm ruft eine C Unterroutine. Folgende
Fragen stellen sich:
– Wie und wo werden die Parameter übergeben?
– Wie werden die Rückgabeparameter zurückgegeben?
– Wie wird sichergestellt, das die Register des aufrufenden
Programms nicht von der Subroutine verändert werden?
• Das Beispiel verwendet int Variablen zur Berechnung
der Fakultät mit dem MS C Compiler.
• Methoden mit Gleitpunktzahlen oder mehr Parametern werden entsprechend aufwendiger...
Prof. Dr. Nikolaus Wulff
Informatik I
21
Der C Code
int faculty(int x) {
register int c=x;
register int y=x;
for (c--; c>0; c--) {
y *=c;
}
return y;
}
void main() {
int x, y;
x = 5;
y = faculty(x);
}
Anweisung c und y
möglichst im Register
zu halten...
• Die main Routine ruft die C Unterroutine faculty und
übergibt den Parameter x und erwartet das Ergebnis in
der Variablen y...
Prof. Dr. Nikolaus Wulff
Informatik I
22
Unterroutinen Aufruf
56:
0040113F
57:
00401146
00401149
0040114A
0040114F
00401152
x = 5;
x5
mov
dword ptr [ebp-4],5
y = faculty(x);
eax  x
mov
eax,dword ptr [ebp-4]
eax  Stack
push
eax
call
@ILT+30(faculty)(00401023
add
esp,4
mov
dword ptr [ebp-8],eax
• Das int Argument x =[ebp-4] wird mit dem Register
eax auf den Stack gelegt (push), um es an die Subroutine faculty zu übergeben.
• Der int Rückgabewert y =[ebp-8] wird nach der
Ausführung aus dem Register eax wieder ausgelesen.
Prof. Dr. Nikolaus Wulff
Informatik I
23
Parameterübgabe
• Am Anfang der Methode werden die verwendeten
Register mit push gesichert...
21:
int faculty(int x) {
00401050
push
ebp
00401051
mov
ebp,esp
00401053
sub
esp,48h
00401056
push
ebx
00401057
push
esi
00401058
push
edi
22:
register int c=x;
00401068
mov
eax,dword
0040106B
mov
dword ptr
23:
register int y=x;
0040106E
mov
ecx,dword
00401071
mov
dword ptr
Prof. Dr. Nikolaus Wulff
Informatik I
Basezeiger sichern
ebp  Stackzeiger
neuer Stack für die Fkt.
Register sichern
ptr [ebp+8]
[ebp-4],eax
eax  x
c  eax
ptr [ebp+8]
[ebp-8],ecx
ecx  x
y  ecx
24
Die for-Schleife
24:
00401074
00401077
0040107A
0040107D
0040107F
00401082
00401085
00401088
0040108C
25:
0040108E
00401091
00401095
26:
00401098
for(c--; c>0; c--) {
mov
edx,dword ptr [ebp-4]
sub
edx,1
mov
dword ptr [ebp-4],edx
jmp
faculty+38h (00401088)
mov
eax,dword ptr [ebp-4]
sub
eax,1
mov
dword ptr [ebp-4],eax
cmp
dword ptr [ebp-4],0
jle
faculty+4Ah (0040109a)
y *= c;
mov
ecx,dword ptr [ebp-8]
imul
ecx,dword ptr [ebp-4]
mov
dword ptr [ebp-8],ecx
}
jmp
faculty+2Fh (0040107f)
Prof. Dr. Nikolaus Wulff
Informatik I
edx  c
edx = c-c  edx
eax  c
eax = c-c  eax
c>0?
=> Ende
ecx  y
ecx  y*c
ecx  y
25
Beende der Funktion mit Rückgabe
21:
int faculty(int x) {
22:
/** ... */
27:
return y;
0040109A
mov
eax,dword ptr [ebp-8] eax  y
28:
}
0040109D
pop
edi
0040109E
pop
esi
mit push gesicherte
0040109F
pop
ebx
Register zurückladen
004010A0
mov
esp,ebp
alten Stack zurückladen
004010A2
pop
ebp
Basezeiger zurückladen
004010A3
ret
• Am Ende der Routine sind alle Register (bis auf eax)
wieder im ursprünglichen Zustand.
• eax dient zur Rückgabe des int Ergebnis.
Prof. Dr. Nikolaus Wulff
Informatik I
26
Zusammenfassung
• Assembler Code ist wesentlich schwieriger zu lesen
als C Code.
• Zeigt aber deutlich das Zusammenspiel von Code und
dessen Umsetzung mit Hilfe von Modifikationen der
CPU-Register.
• Die Einführung der Hochsprachen vereinfachte die
Programmierung erheblich und erlaubte eine wesentlich schnellere Entwicklung.
• Von Zeit zu Zeit ist es nützlich, sich beim Ausführen
einfacher Anweisungen daran zu erinnern, welche
komplexe Operationen sich innerhalb eines Rechners
abspielen.
Prof. Dr. Nikolaus Wulff
Informatik I
27