|
GRUNDLAGEN DER INFORMATIK WS 0203 - Vorlesung |
1. Informatik im Licht von IT2006
In der ersten Vorlesung hatten wir uns mit dem Bild vertraut gemacht, das vom Bundesministerium im Rahmen des neuen Forschungsprogramms IT2006 für die Informations und Kommunikationsindustrie in den nächsten vier Jahren gezeichnet wird:
IT2006-Sicht auf die Informatik 2002-2006
Wir wollen diese Sicht jetzt durch eine andere Sicht ergänzen.
2. Eine Informatik-Themenkarte aus Sicht der 'typischen' Einsatzsituation
Diese andere Sicht geht aus von den 'Realisierungssituationen', wie sie aus Sicht des 'Informatikers vor Ort' erscheinen.
Informatik-Themenkarte
3. Die Verwandlung von Weltausschnitten in Bits und Signale
Wie man aus der vorausgehenden Themenkarte zur Informatik schon erkennen kann, besteht eine Leistung der Informatik daran, bestimmte problemorientierte Ausschnitte der realen Welt in einem mehrstufigen Prozess so zu übersetzen (transformieren), dass dieses Problem am Ende in Form von Bitfeldern vorliegt, die implizit eine solche Befehlsstruktur kodieren, dass eine Maschine (ein Mikroprozessor), diese Bitfelder in ein gewünschtes Verhalten umsetzt. Es beginnt mit normalsprachlicher Kommunikation unterstützt durch Aufzeigesituationen, Gesten, Grafiken, Bildern, Beispiele von Handlungsabläufen usw. Es entstehen vereinbarte Texte ('Lastenhefte'); diese werden in unterschiedliche abstrakte Konzepte/ Modelle/ Strukturen übersetzt (völlig betriebssystemunabhängig); diese dann wieder in verschiedene Programmiersprachen (nahezu betribssystemunabhängig); und der Quellkode der Programmiersprachen wird dann stufenweise weiter übersetzt in Assemblerkode (noch vergleichsweise unabhängig von einem bestimmten Prozessor), und dann in den Objektkode (Binärekode) eines konkreten Prozessors. Der Prozessor besteht aus physikalischen Gattern, die durch die Verteilung und den Fluss elektrischer Ladungen charakterisierbar sind. Damit erreicht die kodierte Welt den Bereich kontrollierter elektrischer Signale. Wie diese physikalischen Signale technisch realisiert werden, das ändert sich nahezu von Tag zu Tag. Die Grundlagenforschung ist hier sehr in Bewegung. Letzteres ist auch dringend geboten, da die für die Produktion von Chips und Rechnern relevanten Weltrohstoffvorräte (Blei, Kupfer, Zink,...) nach Wissensstand vom Jahr 2002 in ca. 20-30 Jahren nicht regenerierbar erschöpft sein werden. Keine Chips, keine Computer, keine IT-Industrie, .... keine attraktive Perspektive.
Transformation eines Problems in Binaerkode
4. Beispiel: C-Quellcode -> Assembler -> Binärcode
Das folgende Beispiel soll jenen Abschnitt in der Übersetzung von einem Stück Realwelt in den Objektcode eines Mikroprozessors verdeutlichen, der bei dem Quellcode einer Hochsprache (hier 'C') beginnt, und dann über Assembler-Code zum Binär-Code führt. Dabei wird gebrauch gemacht von dem Assembler-Programm 'as' und dem Linker-Programm 'ld', wie es unter Linux zusammen mit dem GNU-C-Compiler 'gcc' standardmaessig zur Verfügung steht. Auf Details der Assemblerprogrammierung wird hier aber nicht eingegangen. Für Interessierte sei verwiessen auf die hervorragende Seite der Linux Assembler Organisation. Hier gibt es nicht nur eine umfassende Erklärung und Erörterung des Themas Assemblerprogrammierung (vor allem, warum man es möglichst vermeiden sollte!!!), sondern auch weitere Artikel, Beispiele und Programme.
/*************************************************************** * * start.c * * author: gdh * date: oct-8, 2002 * * idea: Erstes einfaches Beispiel für ein einfaches C-Programm * before: Keine * after: Keine * compilation: gcc -o start start.c * usage: start * ***************************************************************/ #include <stdio.h> int main(void) { printf("Jetzt kommt es: \n\n"); printf("Das berühmte erste Hallo...\n"); printf("!!!!!!!!!!!!!\n"); return(0); /* auch möglich: return 0; */ }
Dieser C-Quellcode wird mit dem GNU-C-Compiler 'gcc' in ein Assamblerformat übersetzt, das von der Syntax her zur AT&T-Familie gehört, im Gegensatz zur Intel-Syntax. Doch gibt es Werkzeuge, beide Dateiformate ineinander zu übersetzen.
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2 > gcc -v -S start.cDer Compiler wird hier mit zwei Optionen aufgerufen: '-v' steht für 'verbose', d.h. der Vorgang der Übersetzung wird ein wenig kommentiert, und '-S' steht für 'Assemblermodus', d.h. das Ergebnis ist Code für den GNU-Assembler 'as' bzw. 'gas'; die Ergebnisdatei bekommt das Suffix '.s'.
Reading specs from /usr/lib/gcc-lib/i486-suse-linux/2.95.3/specs gcc version 2.95.3 20010315 (SuSE) /usr/lib/gcc-lib/i486-suse-linux/2.95.3/cpp0 -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=95 -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di486 -D__i486 -D__i486__ start.c /tmp/ccKXHEcc.i GNU CPP version 2.95.3 20010315 (SuSE) (i386 Linux/ELF) #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include /usr/include End of search list. The following default directories have been omitted from the search path: /usr/include/g++ /usr/lib/gcc-lib/i486-suse-linux/2.95.3/../../../../i486-suse-linux/include End of omitted list. /usr/lib/gcc-lib/i486-suse-linux/2.95.3/cc1 /tmp/ccKXHEcc.i -quiet -dumpbase start.c -version -o start.s GNU C version 2.95.3 20010315 (SuSE) (i486-suse-linux) compiled by GNU C version 2.95.3 20010315 (SuSE).
Dies erzeugt die Datei start.s.
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2> cat start.s.file "start.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "Jetzt kommt es: \n\n" .LC1: .string "Das ber\374hmte erste Hallo...\n" .LC2: .string "!!!!!!!!!!!!!\n" .text .align 16 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $8,%esp addl $-12,%esp pushl $.LC0 call printf addl $16,%esp addl $-12,%esp pushl $.LC1 call printf addl $16,%esp addl $-12,%esp pushl $.LC2 call printf addl $16,%esp xorl %eax,%eax jmp .L2 .p2align 4,,7 .L2: movl %ebp,%esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.3 20010315 (SuSE)"
Dieser Assemblercode wird dann dem Assembler 'as' übergeben, der daraus Objektcode mit der endung '.o' erzeugt. Die Option '-a' fordert den Assembler auf, die Speicherbelegung mit aufzulisten.
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2 > as -a -o start.o start.sGAS LISTING start.s page 1 1 .file "start.c" 2 .version "01.01" 3 gcc2_compiled.: 4 .section .rodata 5 .LC0: 6 0000 4A65747A .string "Jetzt kommt es: \n\n" 6 74206B6F 6 6D6D7420 6 65733A20 6 0A0A00 7 .LC1: 8 0013 44617320 .string "Das ber\374hmte erste Hallo...\n" 8 626572FC 8 686D7465 8 20657273 8 74652048 9 .LC2: 10 0030 21212121 .string "!!!!!!!!!!!!!\n" 10 21212121 10 21212121 10 210A00 11 .text 12 .align 16 13 .globl main 14 .type main,@function 15 main: 16 0000 55 pushl %ebp 17 0001 89E5 movl %esp,%ebp 18 0003 83EC08 subl $8,%esp 19 0006 83C4F4 addl $-12,%esp 20 0009 68000000 pushl $.LC0 20 00 21 000e E8FCFFFF call printf 21 FF 22 0013 83C410 addl $16,%esp 23 0016 83C4F4 addl $-12,%esp 24 0019 68130000 pushl $.LC1 24 00 25 001e E8FCFFFF call printf 25 FF 26 0023 83C410 addl $16,%esp 27 0026 83C4F4 addl $-12,%esp 28 0029 68300000 pushl $.LC2 28 00 29 002e E8FCFFFF call printf 29 FF 30 0033 83C410 addl $16,%esp 31 0036 31C0 xorl %eax,%eax 32 0038 EB06 jmp .L2 33 003a 8DB60000 .p2align 4,,7 33 0000 34 .L2: 35 0040 89EC movl %ebp,%esp 36 0042 5D popl %ebp 37 0043 C3 ret 38 .Lfe1: 39 .size main,.Lfe1-main GAS LISTING start.s page 2 40 0044 8DB60000 .ident "GCC: (GNU) 2.95.3 20010315 (SuSE)" 40 00008DBF 40 00000000 GAS LISTING start.s page 3 DEFINED SYMBOLS *ABS*:00000000 start.c start.s:3 .text:00000000 gcc2_compiled. start.s:15 .text:00000000 main UNDEFINED SYMBOLS printf
Der so erzeugte Objektcode ist aber noch nicht auf einer konkreten Maschine lauffähig. In ihm werden z.B. Routinen aufgerufen ('printf'), für die es noch keine Implementierung gibt. Diese fehlenden Code-Teile sowie die Einbindung dieses Codes in eine Ablaufumgebung, diese müssen noch hinzugefügt werden. Diese Aufgabe übernimmt der Linker 'ld'.
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2> ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o start /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i486-suse-linux/2.95.3/crtbegin.o /usr/lib/gcc-lib/i486-suse-linux/2.95.3/crtend.o /usr/lib/crtn.o start.o -lcDem Linker 'ld' wird mit der Option '-m elf_i386' gesagt, dass er eine Datei im Linux-Elf Format für Intel386-Architektur erstellen soll. Die Optionen '-dynamic-linker' und '/lib/ld-linux.so.2' besagen, dass shared Libraries (so) für dynamisches Linken geladen werden sollen. '-o start' legt fest, dass die endgültige Objektdatei 'start' heissen soll. Die nachfolgend aufgeführten '*.o'-Dateien sind sogenannte 'wrapper_Dateien', die die Einbindung des Objektcodes in die Ablaufumgebung sicherstellen sollen.
Will man wissen, wiviel Speicherplatz das endgültge Programm wirklich benötigt, dann kann man dies auch erfahren:
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2 > size starttext data bss dec hex filename 1035 224 24 1283 503 start
Insgesamt benötigt das Programm 1283 Bytes, davon alleine 1035 für Text, 224 für Daten und 24 Bytes für nichtinitialisierte Daten.
Will man wissen, wie der endgültige Objektkode mit allen Ergänzungen aussieht und wie er sich im Speicher verteilt, dann kann man sich mit dem Programm 'objdump' mit der Option '-d' für 'disassemble' den aktuellen Objectcode wieder 'rückübersetzen' lassen:
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2 > objdump -d startstart: file format elf32-i386 Disassembly of section .init: 08048298 <_init>: 8048298: 55 push %ebp 8048299: 89 e5 mov %esp,%ebp 804829b: 83 ec 14 sub $0x14,%esp 804829e: 53 push %ebx 804829f: e8 00 00 00 00 call 80482a4 <_init+0xc> 80482a4: 5b pop %ebx 80482a5: 81 c3 80 12 00 00 add $0x1280,%ebx 80482ab: e8 84 00 00 00 call 804833480482b0: e8 1b 01 00 00 call 80483d0 80482b5: e8 56 01 00 00 call 8048410 <__do_global_ctors_aux> 80482ba: 5b pop %ebx 80482bb: c9 leave 80482bc: c3 ret Disassembly of section .plt: 080482c0 <.plt>: 80482c0: ff 35 28 95 04 08 pushl 0x8049528 80482c6: ff 25 2c 95 04 08 jmp *0x804952c 80482cc: 00 00 add %al,(%eax) 80482ce: 00 00 add %al,(%eax) 80482d0: ff 25 30 95 04 08 jmp *0x8049530 80482d6: 68 00 00 00 00 push $0x0 80482db: e9 e0 ff ff ff jmp 80482c0 <_init+0x28> 80482e0: ff 25 34 95 04 08 jmp *0x8049534 80482e6: 68 08 00 00 00 push $0x8 80482eb: e9 d0 ff ff ff jmp 80482c0 <_init+0x28> 80482f0: ff 25 38 95 04 08 jmp *0x8049538 80482f6: 68 10 00 00 00 push $0x10 80482fb: e9 c0 ff ff ff jmp 80482c0 <_init+0x28> 8048300: ff 25 3c 95 04 08 jmp *0x804953c 8048306: 68 18 00 00 00 push $0x18 804830b: e9 b0 ff ff ff jmp 80482c0 <_init+0x28> Disassembly of section .text: 08048310 <_start>: 8048310: 31 ed xor %ebp,%ebp 8048312: 5e pop %esi 8048313: 89 e1 mov %esp,%ecx 8048315: 83 e4 f0 and $0xfffffff0,%esp 8048318: 50 push %eax 8048319: 54 push %esp 804831a: 52 push %edx 804831b: 68 a0 84 04 08 push $0x80484a0 8048320: 68 98 82 04 08 push $0x8048298 8048325: 51 push %ecx 8048326: 56 push %esi 8048327: 68 50 84 04 08 push $0x8048450 804832c: e8 bf ff ff ff call 80482f0 <_init+0x58> 8048331: f4 hlt 8048332: 89 f6 mov %esi,%esi 08048334 : 8048334: 55 push %ebp 8048335: 89 e5 mov %esp,%ebp 8048337: 83 ec 14 sub $0x14,%esp 804833a: 53 push %ebx 804833b: e8 00 00 00 00 call 8048340 8048340: 5b pop %ebx 8048341: 81 c3 e4 11 00 00 add $0x11e4,%ebx 8048347: 8b 83 1c 00 00 00 mov 0x1c(%ebx),%eax 804834d: 85 c0 test %eax,%eax 804834f: 74 02 je 8048353 8048351: ff d0 call *%eax 8048353: 5b pop %ebx 8048354: c9 leave 8048355: c3 ret 8048356: 89 f6 mov %esi,%esi 8048358: 90 nop 8048359: 90 nop 804835a: 90 nop 804835b: 90 nop 804835c: 90 nop 804835d: 90 nop 804835e: 90 nop 804835f: 90 nop 08048360 <__do_global_dtors_aux>: 8048360: 55 push %ebp 8048361: 89 e5 mov %esp,%ebp 8048363: 83 ec 08 sub $0x8,%esp 8048366: 83 3d 0c 95 04 08 00 cmpl $0x0,0x804950c 804836d: 75 3e jne 80483ad <__do_global_dtors_aux+0x4d> 804836f: eb 12 jmp 8048383 <__do_global_dtors_aux+0x23> 8048371: a1 08 95 04 08 mov 0x8049508,%eax 8048376: 8d 50 04 lea 0x4(%eax),%edx 8048379: 89 15 08 95 04 08 mov %edx,0x8049508 804837f: 8b 00 mov (%eax),%eax 8048381: ff d0 call *%eax 8048383: a1 08 95 04 08 mov 0x8049508,%eax 8048388: 83 38 00 cmpl $0x0,(%eax) 804838b: 75 e4 jne 8048371 <__do_global_dtors_aux+0x11> 804838d: b8 e0 82 04 08 mov $0x80482e0,%eax 8048392: 85 c0 test %eax,%eax 8048394: 74 0d je 80483a3 <__do_global_dtors_aux+0x43> 8048396: 83 c4 f4 add $0xfffffff4,%esp 8048399: 68 10 95 04 08 push $0x8049510 804839e: e8 3d ff ff ff call 80482e0 <_init+0x48> 80483a3: c7 05 0c 95 04 08 01 movl $0x1,0x804950c 80483aa: 00 00 00 80483ad: 89 ec mov %ebp,%esp 80483af: 5d pop %ebp 80483b0: c3 ret 80483b1: eb 0d jmp 80483c0 80483b3: 90 nop 80483b4: 90 nop 80483b5: 90 nop 80483b6: 90 nop 80483b7: 90 nop 80483b8: 90 nop 80483b9: 90 nop 80483ba: 90 nop 80483bb: 90 nop 80483bc: 90 nop 80483bd: 90 nop 80483be: 90 nop 80483bf: 90 nop 080483c0 : 80483c0: 55 push %ebp 80483c1: 89 e5 mov %esp,%ebp 80483c3: 83 ec 08 sub $0x8,%esp 80483c6: 89 ec mov %ebp,%esp 80483c8: 5d pop %ebp 80483c9: c3 ret 80483ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 080483d0 : 80483d0: 55 push %ebp 80483d1: 89 e5 mov %esp,%ebp 80483d3: 83 ec 08 sub $0x8,%esp 80483d6: b8 d0 82 04 08 mov $0x80482d0,%eax 80483db: 85 c0 test %eax,%eax 80483dd: 74 12 je 80483f1 80483df: 83 c4 f8 add $0xfffffff8,%esp 80483e2: 68 e4 95 04 08 push $0x80495e4 80483e7: 68 10 95 04 08 push $0x8049510 80483ec: e8 df fe ff ff call 80482d0 <_init+0x38> 80483f1: 89 ec mov %ebp,%esp 80483f3: 5d pop %ebp 80483f4: c3 ret 80483f5: 8d 74 26 00 lea 0x0(%esi,1),%esi 80483f9: 8d bc 27 00 00 00 00 lea 0x0(%edi,1),%edi 08048400 : 8048400: 55 push %ebp 8048401: 89 e5 mov %esp,%ebp 8048403: 83 ec 08 sub $0x8,%esp 8048406: 89 ec mov %ebp,%esp 8048408: 5d pop %ebp 8048409: c3 ret 804840a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 08048410 <__do_global_ctors_aux>: 8048410: 55 push %ebp 8048411: 89 e5 mov %esp,%ebp 8048413: 83 ec 14 sub $0x14,%esp 8048416: 53 push %ebx 8048417: bb 14 95 04 08 mov $0x8049514,%ebx 804841c: 83 3d 14 95 04 08 ff cmpl $0xffffffff,0x8049514 8048423: 74 0c je 8048431 <__do_global_ctors_aux+0x21> 8048425: 8b 03 mov (%ebx),%eax 8048427: ff d0 call *%eax 8048429: 83 c3 fc add $0xfffffffc,%ebx 804842c: 83 3b ff cmpl $0xffffffff,(%ebx) 804842f: 75 f4 jne 8048425 <__do_global_ctors_aux+0x15> 8048431: 5b pop %ebx 8048432: 89 ec mov %ebp,%esp 8048434: 5d pop %ebp 8048435: c3 ret 8048436: 8d 76 00 lea 0x0(%esi),%esi 8048439: 8d bc 27 00 00 00 00 lea 0x0(%edi,1),%edi 08048440 : 8048440: 55 push %ebp 8048441: 89 e5 mov %esp,%ebp 8048443: 83 ec 08 sub $0x8,%esp 8048446: 89 ec mov %ebp,%esp 8048448: 5d pop %ebp 8048449: c3 ret 804844a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 08048450 : 8048450: 55 push %ebp 8048451: 89 e5 mov %esp,%ebp 8048453: 83 ec 08 sub $0x8,%esp 8048456: 83 c4 f4 add $0xfffffff4,%esp 8048459: 68 c4 84 04 08 push $0x80484c4 804845e: e8 9d fe ff ff call 8048300 <_init+0x68> 8048463: 83 c4 10 add $0x10,%esp 8048466: 83 c4 f4 add $0xfffffff4,%esp 8048469: 68 d7 84 04 08 push $0x80484d7 804846e: e8 8d fe ff ff call 8048300 <_init+0x68> 8048473: 83 c4 10 add $0x10,%esp 8048476: 83 c4 f4 add $0xfffffff4,%esp 8048479: 68 f4 84 04 08 push $0x80484f4 804847e: e8 7d fe ff ff call 8048300 <_init+0x68> 8048483: 83 c4 10 add $0x10,%esp 8048486: 31 c0 xor %eax,%eax 8048488: eb 06 jmp 8048490 804848a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 8048490: 89 ec mov %ebp,%esp 8048492: 5d pop %ebp 8048493: c3 ret 8048494: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 804849a: 8d bf 00 00 00 00 lea 0x0(%edi),%edi Disassembly of section .fini: 080484a0 <_fini>: 80484a0: 55 push %ebp 80484a1: 89 e5 mov %esp,%ebp 80484a3: 83 ec 14 sub $0x14,%esp 80484a6: 53 push %ebx 80484a7: e8 00 00 00 00 call 80484ac <_fini+0xc> 80484ac: 5b pop %ebx 80484ad: 81 c3 78 10 00 00 add $0x1078,%ebx 80484b3: 90 nop 80484b4: e8 a7 fe ff ff call 8048360 <__do_global_dtors_aux> 80484b9: 5b pop %ebx 80484ba: c9 leave 80484bb: c3 ret
Ruft man den erzeugten Objektkode mit Namen 'start' jetzt auf der Kommandozeile auf, dann, oh Wunder:
gerd@turing:~/WEB-MATERIAL/fh/I-EDV/VL2 > start Jetzt kommt es: Das berühmte erste Hallo... !!!!!!!!!!!!!
Das Programm funktioniert. Die Maschine 'versteht' schliesslich, was gemeint ist....
Man kann erkennen, dass der ursprüngliche Kode jetzt durch einige Abschnitte mit 'neuem' Kode ergänzt wurde. dies ist jener Kode, der bei jedem Linkvorgang automatisch hinzugefügt wird, um das angezielte Kodefragment in der jeweiligen Umgebung zum Laufen zu bringen.
5. Ein Mikroprozessor und seine unmittelbare Umgebung
Es stellt sich jetzt die Frage, wie denn die Hardware, hier spezieller der Mikroprozessor, diese Bitfelder verarbeitet. Das erste Bild zeigt stark vereinfacht den Aufbau eines PCs (die folgenden Grafiken sind dem in der Literaturliste angegebenen Buch von TANENBAUM/GOODMAN entnommen).
CPU mit HW-Kontext und BUS-Verbindungen
Man sieht die CPU mit Ansätzen einer inneren Struktur sowie einigenden zusätzlichen Komponenten. Alle Komponenten sind über einen 'Bus' miteinander verknüpft. Ein 'Bus' ist letztlich ein Bündel von elektrischen Leitungen, die ganz bestimmten physikalischen Anforderungen genügen müssen. Wie schon diese Grafik andeutet, gibt es aufgrund der grossen Bandbreite an Anforderungen nicht nur ein einziges Bus-System. Sowohl in der CPU selbst gibt es interne Busse, wie auch zwischen den Hauptkomponenten eines Computers.
Busse im PC
Über einen Bus werden Signale gesendet, die durch die Hardware als 'High (:= 1)' bzw. 'Low (:= 0)' interpretiert werden. Diese Signale können Adressen kodieren, Daten, Befehle oder sonstige Steuersignale. Die eigentliche Interpretation dieser Bitfelder sowie ein Teil der notwendigen Verarbeitung erfolgt in der CPU. Die drei wichtigsten Komponenten einer CPU sind ihre internen Register (samt einem internen Stack), die Steuereinheit zur Interpretation der Befehle sowie die Arithmetisch-Logische Einheit (ALU), die konkrete Daten verarbeiten kann.
Das nächste Bild zeigt nochmals vergrössert einen Teil der eigentlichen CPU, die arithmetisch-logische Einheit ('arithmetical logical unit, ALU). Wie aus den vorausgehenden Assembler-Beispielen ersichtlich ist, kann eine Alu elmentare Operationen ausführen wie z.B.: 'Addieren', 'Subtrahieren', 'Vergleichen', 'Kopieren', 'Shiften', 'Adressieren', 'Push' und 'Pop'.
Arithmetisch-Logische Einheit (Unit)
Grafikausgabe und Kommunikation über ein Model sind Beispiele, wie die CPU mittels zusätzlicher Komponenten Aufgaben lösen kann. Über Bitmuster werden spezielle Komponenten wie Grafikkarte oder UART ('Universal Asynchronous Receiver Transmitter') adressiert und mit Daten beliefert.
Grafikausgabe
Kommunikation über Modem
Versuchen sie, anhand eigener kleiner C-programme, die Übersetzung dieser Programme in Assembler-Sprache und Binärcode zu realisieren.