You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
zadania/compile/compile.md

3.9 KiB

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;
  • 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.
  2. to samo, co w punkcie 1, tylko dwie funkcje. W pliku 2.txt zawrzyj komunikaty o błędzie.
  3. 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.
  4. 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?