15.09.2014 Aufrufe

Aufgaben zur IA32-Assembler-Programmierung - AG Technische ...

Aufgaben zur IA32-Assembler-Programmierung - AG Technische ...

Aufgaben zur IA32-Assembler-Programmierung - AG Technische ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>Aufgaben</strong> <strong>zur</strong> <strong>IA32</strong>-<strong>Assembler</strong>-<strong>Programmierung</strong><br />

Prof. Dr. Ralf Möller<br />

<strong>AG</strong> <strong>Technische</strong> Informatik<br />

<strong>Technische</strong> Fakultät<br />

Universität Bielefeld<br />

www.ti.uni-bielefeld.de<br />

Version 1.19 vom 25. September 2013, WS 2013/14


Insgesamt müssen 100 Punkte erreicht werden. Die <strong>Aufgaben</strong> sind von jedem Studenten einzeln zu bearbeiten; Betrugsversuche<br />

werden geahndet. Es ist nicht gestattet, <strong>Assembler</strong>-Programme aus compilierten hochsprachlichen<br />

Programmen zu erstellen.<br />

Aufgabe: (10 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm add64.asm, welches zwei ganze Zahlen mit<br />

jeweils 64 Bit Breite addiert. Der höherwertige Teil der ersten Zahl soll im Register eax, der niederwertige in ebx<br />

stehen, die zweite Zahl entsprechend in ecx und edx, das Ergebnis in eax und ebx. Arbeiten Sie das Programm<br />

im Debugger gdb schrittweise ab und notieren Sie nach jeder arithmetischen Operation den Zustand der beteiligten<br />

Register und des erweiterten Flag-Registers eflags (es muss keine Ausgabefunktion implementiert werden).<br />

Erklären Sie die Flagstellungen. Hinweis: Alle Statusflags stehen in den unteren 16 Bit des eflags Registers:<br />

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0<br />

OF SF ZF AF PF CF<br />

Verwenden Sie folgende Beispiele als Summanden:<br />

eax ebx ecx edx<br />

0x11111111 0x22222222 0x33333333 0x44444444<br />

0x11111111 0x22222222 0x33333333 0xdddddddd<br />

0x11111111 0x22222222 0x33333333 0xddddddde<br />

0x11111111 0x22222222 0x33333333 0xeeeeeeee<br />

0x11111111 0x22222222 0xeeeeeeee 0xeeeeeeee<br />

Aufgabe: (30 Punkte) Ergänzen Sie das obige Programm add64.asm, so dass die Werte der 4 beteiligten Universalregister<br />

und die Statusflags mittels Aufruf zweier Unterprogramme an beliebiger Stelle im Programm ausgegeben<br />

werden können. Verwenden Sie bei der Ausgabe der Statusflags jeweils kleine Buchstaben für nicht gesetzte<br />

und große Buchstaben für gesetzte Flags. Wiederholen Sie damit Ihre Versuche aus der vorherigen Aufgabe und<br />

überprüfen Sie die Resultate. Beachten Sie, dass Operationen, die für die Ausgabe verwendet werden, die Statusflags<br />

beeinflussen können (die Stack-Befehle für das erweiterte Flag-Register heißen pushf und popf). Beachten<br />

Sie weiterhin, dass es keine bedingten Sprungbefehle gibt, welche das Auxiliary Carry Flag (AF) abfragen (Hinweis:<br />

Der Befehl lahf überführt die Statusflags in das Register ah. Mit bt ax, 12 kann das AF-Flag in das<br />

Carry-Flag kopiert werden.) Sie müssen davon ausgehen, dass sich die Flags vorher in einem undefinierten Zustand<br />

befinden.<br />

Beispiel:<br />

% add64<br />

11111111 22222222 33333333 ffffffff<br />

osZAPc<br />

11111111 22222221 33333333 ffffffff<br />

oszAPC<br />

44444445 22222221 33333333 ffffffff<br />

oszapc<br />

%<br />

Aufgabe: (30 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm namen.asm, welches in einer Zeichenkette mit<br />

einem Personennamen jeweils den ersten Buchstaben als Großbuchstaben, alle anderen Buchstaben als Kleinbuchstaben<br />

darstellt, unabhängig von der Schreibweise in der Eingabe. Die Zeichenkette wird von der Standardeingabe<br />

gelesen, bis ein Zeilenumbruch auftritt, umgewandelt und auf der Standardausgabe ausgegeben. Gelangt die Leseroutine<br />

(Systemruf read) zum Dateiende (Rückkehrwert 0), so wird das Programm beendet. Beispiel (abwechselnd<br />

Eingabe/Ausgabe; die Shell gibt eine Zeichenkette erst dann weiter, wenn diese mit Enter abgeschlossen<br />

wurde):<br />

% namen<br />

Eingabe: JAMES T. kirk<br />

Ausgabe: James T. Kirk<br />

Eingabe: heinrich HEINE<br />

Ausgabe: Heinrich Heine<br />

1


ˆD<br />

%<br />

Aufgabe: (40 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm sgrep.asm (mit ähnlicher Funktion wie das<br />

Unix-Kommando grep), welches in der Standardeingabe nach einer Zeichenkette sucht, die als Kommandozeilenargument<br />

angegeben wurde. Wird die Zeichenkette in einer Zeile (Zeilenabschluss 0x0a) gefunden, so wird<br />

die gesamte Zeile auf der Standardausgabe ausgegeben.<br />

Aufgabe: (40 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm colsel.asm, welches die Standardeingabe<br />

durchmustert und nur eine “Spalte” des Eingabedatenstroms auf der Standardausgabe ausgibt. Die Nummer der<br />

Spalte (beginnend mit 1) wird als Kommandozeilenargument angegeben. Spalten werden von Tabulatoren (0x09)<br />

getrennt, wobei auch mehrere Tabulatoren hintereinander auftreten können. Zeilen enden mit 0x0a.<br />

Aufgabe: (40 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm convert10to16.asm welches eine vorzeichenlose<br />

Dezimalzahl in eine Hexadezimalzahl (32 bit) umwandelt. Die Dezimalzahl wird als Kommandozeilen-<br />

Argument übergeben, nochmals im Original ausgegeben, umgewandelt und als Hexadezimalzahl (mit führenden<br />

Nullen) auf der Standardausgabe ausgegeben. Das Programm soll eine Fehlermeldung ausgeben, wenn ein inkorrektes<br />

Zeichen eingegeben wurde oder der Wertebereich von 32 bit überschritten wird. Beispiel:<br />

% convert10to16 12345<br />

decimal number = 12345<br />

hexadecimal number = 0x00003039<br />

% convert10to16 4294967295<br />

decimal number = 4294967295<br />

hexadecimal number = 0xffffffff<br />

% convert10to16 4294967296<br />

decimal number = 4294967296<br />

invalid decimal number<br />

% convert10to16 12x45<br />

decimal number = 12x45<br />

invalid decimal number<br />

%<br />

Aufgabe: (30 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm convert16to10.asm, welches eine vorzeichenlose<br />

Hexadezimalzahl (max. 8 Stellen) in eine Dezimalzahl umwandelt. Die Hexadezimalzahl wird als Kommandozeilen-Argument<br />

übergeben, nochmals im Original ausgegeben, umgewandelt und als Dezimalzahl (ohne<br />

führende Nullen) auf der Standardausgabe ausgegeben. Das Programm soll eine Fehlermeldung ausgeben, wenn<br />

ein inkorrektes Zeichen oder mehr als 8 Stellen eingegeben wurden. Beispiel:<br />

% convert16to10 3e8<br />

hexadecimal number = 0x3e8<br />

decimal number = 1000<br />

% convert16to10 3g8<br />

hexadecimal number = 0x3g8<br />

invalid hexadecimal number<br />

%<br />

Aufgabe: (40 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm wortzaehl.asm, welches die Anzahl der Zeilen,<br />

der Worte und der Zeichen in einer Text-Datei zählt und diese Angaben auf der Standardausgabe ausgibt (eine<br />

einfache Variante des Unix-Befehls wc, der auch zum Vergleich herangezogen werden sollte). Worte werden von<br />

Leerzeichen (0x20), Tabulatoren (0x09) oder Zeilenumbrüchen (0x0a) getrennt, wobei auch mehrere dieser<br />

Zeichen hintereinander auftreten können. Der Name der Text-Datei soll als Kommandozeilen-Argument übergeben<br />

werden, die Ausgabe der drei Zahlen im Dezimalsystem erfolgt auf der Standardausgabe. Für die Ausgabe wird<br />

ähnlicher Code wie in der Aufgabe convert16to10.asm nötig sein (es wird deswegen auch nur eine Aufgabe<br />

von beiden gewertet).<br />

Aufgabe: (20 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm rot13.asm, welches ASCII-Text von der Standardeingabe<br />

einliest, diesen mithilfe des ROT13-Verfahrens “verschlüsselt” und auf der Standardausgabe ausgibt.<br />

Die ROT13-Chiffrierung verschiebt jeden Buchstaben des Alphabets um 13 Stellen nach vorn oder hinten. Chiffrierung<br />

und Dechiffrierung sind identisch. Das folgende C-Programm realisiert das gewünschte Verhalten:<br />

2


#include<br />

#include<br />

int<br />

main()<br />

{<br />

char c, cc;<br />

while (!feof(stdin)) {<br />

c = fgetc(stdin);<br />

if (c == EOF) break;<br />

cc = c | 0x20;<br />

if ((cc >= ’a’) && (cc = ’n’) && (cc


#include <br />

#include <br />

void<br />

block_ausgabe(long int wert, char einer, char fuenfer, char zehner)<br />

{<br />

long int i;<br />

if (wert == 9)<br />

printf("%c%c", einer, zehner);<br />

else if (wert > 4) {<br />

printf("%c", fuenfer);<br />

for (i = wert; i >= 6; i--)<br />

printf("%c", einer);<br />

}<br />

else if (wert == 4)<br />

printf("%c%c", einer, fuenfer);<br />

else<br />

for (i = wert; i >= 1; i--)<br />

printf("%c", einer);<br />

}<br />

int<br />

main(int argc, char *argv[])<br />

{<br />

long int i, zahl;<br />

}<br />

if (argc != 2) {<br />

fprintf(stderr, "arabic2roman \n");<br />

return -1;<br />

}<br />

zahl = atol(argv[1]);<br />

/* keine Ausgabe fuer 0 oder negative Zahlen */<br />

if (zahl


% bubblesort Dieses Programm sortiert alle Zeichenketten nach Ihrem ASCII-Code.<br />

Deeiss<br />

Pagmmorr<br />

eiorrstt<br />

aell<br />

Zceeeehiknntt<br />

achn<br />

Iehmr<br />

-.ACCIISdeo<br />

%<br />

Beim Bubblesort werden nacheinander jeweils zwei aufeinanderfolgende Elemente verglichen (Index i und i + 1).<br />

Befinden die beiden Elemente sich nicht in der gewünschten Ordnung, so werden sie vertauscht. Dann wird mit<br />

Index i + 1 und i + 2 fortgefahren. Die Sortierung ist beendet, wenn im letzten Durchlauf keine Vertauschung<br />

vorgenommen wurde.<br />

Aufgabe: (40 Punkte) Implementieren Sie das CRC-Verfahren <strong>zur</strong> Checksummen-Berechnung nach der Beschreibung<br />

auf http://de.wikipedia.org/wiki/CRC-32 in einem <strong>Assembler</strong>programm crc.asm. Das Programm<br />

soll die CRC-Checksumme für die Zeichen berechnen, die ihm auf der Standardeingabe übergeben werden<br />

(z.B. durch Umlenken einer Datei auf die Standardeingabe). Beispiel:<br />

% crc < print_args.asm<br />

Checksumme: 0xbe9b56fc<br />

%<br />

Gehen Sie von dem modifizierten Algorithmus aus, der auf obiger Webseite als C-Programm angegeben ist:<br />

#include <br />

#include <br />

#include <br />

#define CRC32POLYREV 0xEDB88320 /* CRC-32 Polynom, umgekehrte Bitfolge */<br />

int datastream[]={1,0,0,0,1,1,0,0}; /* ASCII-"1", LSB zuerst */<br />

int databits=8;<br />

uint32_t crc32_rev; /* Shiftregister */<br />

void calc_crc32_rev(int bit)<br />

{ int lbit;<br />

lbit=crc32_rev & 1;<br />

if (lbit != bit)<br />

crc32_rev=(crc32_rev>>1) ˆ CRC32POLYREV;<br />

else<br />

crc32_rev=crc32_rev>>1;<br />

}<br />

int main(void)<br />

{ int i;<br />

}<br />

crc32_rev=0xffffffff; /* Startwert (111...) */<br />

for (i=0; i


% clock<br />

Es ist 11:27:36<br />

%<br />

Die Uhrzeit kann um 1 oder 2 Stunden von der Mitteleuropäischen (Sommer-)Zeit abweichen.<br />

Aufgabe: (40 Punkte) Schreiben Sie ein <strong>Assembler</strong>-Programm fixedpoint.asm. Dieses soll auf der Standardeingabe<br />

eine Dezimalzahl mit Vor- und Nachkommestellen akzeptieren und auf der Standardausgabe deren<br />

Kodierung als Festkommazahl binär ausgeben. Die Festkommazahl hat 32 Bit und soll jeweils 16 Bit als Vor- und<br />

Nachkommabereich enthalten. Das Programm soll enden, wenn der Systemruf read den Rückgabewert 0 liefert.<br />

% fixedpoint<br />

Type a number: 234.23508<br />

32bit fixed-point number: 00000000111010100011110000101110b<br />

Type a number: 56908.2309482<br />

32bit fixed-point number: 11011110010011000011101100011111b<br />

Type a number: 230983.0984209348<br />

32bit fixed-point number: 11111111111111110001100100110010b<br />

ˆD<br />

%<br />

6

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!