Metody Programowania - Lista 8


Zadanie 1

Poniżej podaję (uproszczony) fragment (jedną funkcję) programu syslog. Funkcja `logmsg' zapisuje tekst komunikatu do pliku. `iscntrl' sprawdza czy znak jest znakiem sterującym (<32). Ustalić co robi podana niżej funkcja. Znaleźć błąd.
printline(hname, msg)
        char *hname;
        char *msg;
{
        char *p, *q;
        int c;
        char line[MAXLINE + 1];

        p = msg;
        q = line;

        while ((c = *p++ & 0177) != '\0' &&
            q < &line[sizeof(line) - 1])
                if (iscntrl(c)) {
                        if (c == '\n')
                                *q++ = ' ';
                        else if (c == '\r')
                                *q++ = ' ';
                        else if (c == '\t')
                        else {
                                *q++ = '^';
                                *q++ = c ^ 0100;
                        }
                }
                else
                        *q++ = c;

        *q = '\0';
        logmsg(line, hname, 0);
}

Zadanie 2

Sprawdzić jaki kod asemblerowy produkuje kompilator `gcc -S -fverbose-asm' dla kilku prostych funkcji. Wypróbować kompilację z opcjami `-O', `-O2' i `-O3'. Jaki efekt daje zmiana typów zmiennych (`char', `short', `int', `long', `float', `double') i modyfikatory (`signed', `unsigned'). Porównać wynik z tym co daje `objdump --disassemble' na odpowiednim pliku wynikowym. Przeprowadzić kompilację z opcją `-g' i uruchomić `objdump --disassemble --source'.

Zadanie 3

Napisać w asemblerze procesora 386 procedurę dodawania poczwórnej precyzji tzn. procedura ma dodawać liczby 128-bitowe. Argumentami procedury mają być wskaźniki do argumentów i wskaźnik do wyniku.

Zadanie 4

Funkcja:

int sss(int * a)
{
        int suma = a[0]+a[1]+a[2];
        return suma;
}
przekompilowana poleceniem `gcc -fomit-frame-pointer -S -O2' daje:
sss:
        movl    4(%esp), %edx
        movl    (%edx), %ecx
        movl    4(%edx), %eax
        addl    %ecx, %eax
        movl    8(%edx), %ecx
        addl    %ecx, %eax
        ret
Prześledzić zawartość stosu przy wykonaniu tej funkcji.
Porównać z wersją kompilowaną przez `gcc -S'.

Zadanie 5

Napisać procedurę(y) w języku asemblera procesora i386 która: zamieni miejscami liczby całkowite wskazywane przez argumenty (argumentami są dwa wskaźniki do liczb całkowitych), powiększy liczbę całkowitą wskazywaną przez argument o 1 (argumentem jest wskaźnik do liczby całkowitej), zwróci podwojoną wartość swojego argumentu (argument jest liczbą całkowitą), zwróci wartość argumentu powiększoną o dwa (argumentem jest liczba całkowita).

Zadanie 6

Modyfikując podany przykład (`maly2.c') i analizując tekst asemblerowy wyprodukowany przez kompilator ustalić sekwencję instrukcji asemblerowych realizującą wywołanie wywołań systemowych `open', `read', `close'.

Zadanie 7

Napisać program(y) w jezyku asemblera (nie używając biblioteki C) który: powiększy liczbę całkowitą (bez znaku, maksymalnie trzycyfrową) odczytaną ze standartowego wejścia i wypisze wynik na standartowym wyjściu, przekopiuje dane z wejścia na wyjście.