4.0 KiB
Zadania domowe z kompilowania programów
Rozwiązania proszę umieścić w Waszym repozytorium w katalogu compile/zadX/, gdzie X to numer
zadania. Termin oddawania rozwiązań to 19 października 2022.
Zadanie 1.
Zademonstruj, że potrafisz kompilować programy napisane w wielu plikach:
- napisz program, który wczyta dwa słowa złożone z małych literek alfabetu angielskiego i wypisze ich odległość Levenshtein'a;
- zrób to w dwóch plikach - w jednym niech będzie wczytywanie i wypisywanie, a w drugim cała logika związana z wyliczaniem odległości;
- napisz skrypt, który kompiluje program - powinien najpierw skompilować oba pliki do object files
a potem je skonsolidować. Skrypt powinien się nazywać
build.sh, a wynikowy plik wykonywalny:ldist.e.
Jeśli musisz, możesz przyjąć jakieś ograniczenie na długość słów wejściowych. Jeśli to robisz, to zaimplementuj sprawdzanie długości i w przypadku przekroczenia - wypisz sensowny komunikat o błędzie. Koniecznie zaimplementuj to w kolejnym (trzecim już) pliku źródłowym.
Zadanie 2.
To zadanie składa się wielu punktów i polega na wywoływaniu błędów kompilacji/linkowania:
- spróbuj napisać program, w którym dwa różne pliki definiują tą samą zmienną. Skompiluj go na dwa
sposoby (tzn. tworząc oraz pomijając object files). Komunikaty o błędzie wraz z zaznaczeniem
etapu kompilacji (parsowanie/kompilacja/asemblacja/linkowanie) zapisz do pliku
1.txt. - to samo, co w punkcie 1, tylko dwie funkcje. W pliku
2.txtzawrzyj komunikaty o błędzie. - spróbuj zlinkować ze sobą niekompatybilne object files, np. jeden z nich skompiluj z flagą
-m32. Komunikat o błędzie trafia do pliku3.txt. - napisz program, który próbuje wywołać funkcję, której nie ma, ale tak udolnie, że błąd
pojawia się dopiero na etapie konsolidacji. Program ma być w pliku
4.cca błąd w4.txt.
Programy z punktów 1 - 3 także powinny się znaleźć w rozwiązaniu tego zadania, ale z dowolnymi nazwami.
Wskazówka do punktu 4: https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration
Zadanie 3.
Plik binarny a.o zawiera funkcję magic, która ma następujący prototyp: bool magic(long).
Stwórz plik a.cc, który będzie implementował funkcję bool notmagic(long), która będzie zwracała
dokładnie to samo, co funkcja magic. Twoja implementacja nie może wywoływać funkcji magic, ani
zawierać wstawek assemblerowych.
Zadanie 4.
Pewna drużyna na sesji próbnej pewnego konkursu w programowaniu zespołowym się nudziła. Nudziła
się tak bardzo, że postanowiła jedno z zadań rozwiązać w assemblerze. Zadanie brzmiało tak: Niech
d(x) oznacza liczbę dzielników liczby x. Wczytaj n i wypisz sumę d(1) + d(2) + ... + d(n).
Liczba n spełnia warunki: 1 ≤ n ≤ 10^12. Pójdź w ślady tej drużyny i napisz program
w assemblerze, który rozwiąże to zadanie. Do oceny możesz przedstawić:
- plik
sol.asm, który można zasemblować używając polecenianasm -felf64 sol.asm, a później zlinkować poleceniemld sol.o, lub - plik
sol.s, który można zasemblować i zlinkować używając poleceniagcc -no-pie sol.s, lub - plik
sol.cc, który można skompilować używając poleceniag++ sol.cc.
Jeśli wybierzesz opcję trzecią, oczekuję że program będzie jedną wielką wstawką assemblerową. Jeśli zrobisz opcję pierwszą, zyskasz mój szacunek.
Wskazówka: https://www.felixcloutier.com/x86/, a tak konkretniej instrukcje MOV, ADD, SUB,
MUL, DIV, CMP, Jcc, CALL i pewnie kilka innych.
PS: Ta drużyna rozwiązała to zadanie wysyłając zgłoszenie w ostatniej minucie sesji próbnej.
Co ciekawe, program uruchomiony na komputerze, na którym drużyna pisała program, kończył się błędem
Segmentation fault, a mimo to sprawdzarka uznała zgłoszenie za poprawne. Czy potrafisz zgadnąć,
dlaczego?