Zadania domowe z kompilowania programów === Rozwiązania proszę umieścić w Waszym repozytorium w katalogu `compile/zadX/`, gdzie `X` to numer zadania. 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](https://en.wikipedia.org/wiki/Levenshtein_distance); * 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: 1. 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`. 1. to samo, co w punkcie 1, tylko dwie funkcje. W pliku `2.txt` zawrzyj komunikaty o błędzie. 1. spróbuj zlinkować ze sobą niekompatybilne *object files*, np. jeden z nich skompiluj z flagą `-m32`. Komunikat o błędzie trafia do pliku `3.txt`. 1. 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.cc` a błąd w `4.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 polecenia `nasm -felf64 sol.asm`, a później zlinkować poleceniem `ld sol.o`, lub * plik `sol.s`, który można zasemblować i zlinkować używając polecenia `gcc -no-pie sol.s`, lub * plik `sol.cc`, który można skompilować używając polecenia `g++ 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?*