Sistemski softver/Probni testovi 2022
Probni testovi 2022 bili su dati na Moodle kursu predmeta.
- Za pitanja sa više odgovora, tačni odgovori su podebljani i uokvireni
- Za pitanja za koje se odgovori unose, tačni odgovori su podvučeni i sakriveni, tako da se prikažu kada izaberete taj tekst (primer: ovako)
- Pritisnite levo dugme ispod za sakrivanje i otkrivanje svih odgovora, ili desno dugme za uključivanje i isključivanje interaktivnog režima:
K1 - teorija
1. zadatak
U nastavku su date definicije nekih tipova podataka StructTypeA
i StructTypeB
:
typedef struct
{
char fA1;
long fA2;
short fA3;
} StructTypeA;
typedef struct
{
int fB1;
int fB2;
short fB3;
StructTypeA fB4;
char fB5;
short fB6;
} StructTypeB;
Dopuniti sledeće konstatacije ukoliko se posmatra amd64 arhitektura i System V ABI konvencija:
- Veličina strukture
StructTypeB
izraženo u bajtovima odnosnosizeof(StructTypeB)
iznosi 48. - Pomeraj do polja
fB4.fA1
gledano od početka struktureStructTypeB
iznosi 16 izraženo u broju adresibilnih jedinica (bajtova). - Najduži kontinualni niz neiskorišćenih odnosno padding bajtova u okviru strukture
StructTypeB
počinje na pomeraju 17 izraženo u broju adresibilnih jedinica (bajtova) gledano od početka struktureStructTypeB
. - Struktura
StructTypeB
sadrži ukupno 24 neiskorišćenih odnosno padding bajtova.
Napomene:
- Sve odgovore treba uneti u decimalnom formatu.
2. zadatak
U nastavku je data deklaracija funkcije foo
i definicije pratećih tipova podataka:
typedef struct
{
long f1;
long f2;
long f3;
} StructType;
extern StructType foo(
char param0,
double param1,
StructType param2,
void * param3,
StructType param4,
float param5,
long param6);
Dopuniti sledeće konstatacije ukoliko se posmatra amd64 arhitektura i System V ABI konvencija:
- Povratna vrednost funkcije
foo
prosleđuje se kao memorijski prostor alociran od strane pozivaoca nazad do pozivaoca.
- Parametar
param0
prosleđuje se kao rsi u funkcijufoo
prilikom njenog poziva. - Parametar
param1
prosleđuje se kao xmm0 u funkcijufoo
prilikom njenog poziva. - Parametar
param2
prosleđuje se kao stackPushII u funkcijufoo
prilikom njenog poziva. - Parametar
param3
prosleđuje se kao rdx u funkcijufoo
prilikom njenog poziva. - Parametar
param4
prosleđuje se kao stackPushI u funkcijufoo
prilikom njenog poziva. - Parametar
param5
prosleđuje se kao xmm1 u funkcijufoo
prilikom njenog poziva. - Parametar
param6
prosleđuje se kao rcx u funkcijufoo
prilikom njenog poziva.
Napomene:
- Odgovor kombinacija GP predstavlja određenu kombinaciju (više od jednog) isključivo General Purpose registara.
- Odgovor kombinacija SSE predstavlja određenu kombinaciju (više od jednog) isključivo Streaming SIMD Extension registara.
- Odgovor kombinacija GP/SSE predstavlja određenu kombinaciju (više od jednog) General Purpose i Streaming SIMD Extension registara.
- Odgovor stackPush<roman-numeral>, gde je <roman-numeral> rimski broj, predstavlja argument koji se prosleđuje preko steka pri čemu rimski broj označava međusobni poredak push operacija odnosno redosled stavljanja datog argumenta na vrh steka u odnosu na druge argumente koji se takođe prosleđuju preko steka.
3. zadatak
Da li funkcija, koja tokom svog izvršavanja poziva druge funkcije, sme bez prethodne alokacije da koristi stek za čuvanje lokalnih promenljivih ukoliko se posmatra amd64 arhitektura i System V ABI konvencija?
- Da, jer nadalje pozvane funkcije neće menjati sadržaj memorije koji odgovara vrhu steka.
- Da, usled postojanja implicitne alokacije steka prilikom ulaska u funkciju.
- Da, zbog postojanja "crvene zone".
- Ne.
4. zadatak
U nastavku je dat sadržaj datoteke syscall.s sa izvornim asemblerskim kodom:
.intel_syntax noprefix
.data
message:
.asciz "Hello World!\n"
.text
loop:
jmp loop
entry:
mov rax, 1
mov rdi, 1
mov rsi, offset message
mov rdx, offset 13
syscall
mov rax, 60
mov rdi, 0
syscall
.end
Posmatra se amd64 arhitektura i System V ABI konvencija, a pokrenute su sledeće komande:
as -o syscall.o syscall.s ld --entry=entry -o executable syscall.o ./executable
- Nije moguće dobiti izvršnu datoteku executable zato što u proces linkovanja nisu uključene C runtime objektne datoteke.
- Nije moguće dobiti izvršnu datoteku executable zato što u proces linkovanja nije uključena standardna C biblioteka.
- Program se regularno izvršava i ispisuje poruku Hello World! na standardni izlaz.
- Program se regularno izvršava, ali neće ispisati poruku Hello World! zato što se vrti u beskonačnoj petlji.
- Nije moguće dobiti izvršnu datoteku executable zato što simbol koji predstavlja ulaznu tačku nije vidljiv linkeru.
5. zadatak
Posmatra se program opisan sadržajem dela memorije i segmentom izvornog C koda.
Inicijalni sadržaj dela memorije (dat u "školskom" formatu prikazanom na auditornim vežbama):
+7 +6 +5 +4 +3 +2 +1 +0 | 0xAA | 0xAA | 0xAA | 0xAA | 0x99 | 0x99 | 0x99 | 0x99 | <--- 0x8000004500 + 0x20 | 0x88 | 0x88 | 0x88 | 0x88 | 0x77 | 0x77 | 0x77 | 0x77 | <--- 0x8000004500 + 0x18 | 0x66 | 0x66 | 0x66 | 0x66 | 0x55 | 0x55 | 0x00 | 0x00 | <--- 0x8000004500 + 0x10 | 0x00 | 0x80 | 0x00 | 0x00 | 0x45 | 0x02 | 0x33 | 0x33 | <--- 0x8000004500 + 0x08 | 0x22 | 0x22 | 0x22 | 0x22 | 0x11 | 0x11 | 0x11 | 0x11 | <--- 0x8000004500 + 0x00
Segment izvornog C koda:
#include <stdio.h>
#include <stdint.h>
extern uint64_t identifier;
void main()
{
printf("%#lx", identifier);
uint64_t *a = (uint64_t *)identifier;
printf("%p", a);
printf("%#lx", a[0]);
printf("%#lx", a[1]);
uint64_t *b = (uint64_t *)&identifier;
printf("%p", b);
printf("%#lx", b[0]);
printf("%#lx", b[1]);
}
Dopuniti sledeće konstatacije ukoliko se posmatra amd64 arhitektura i System V ABI konvencija, a simbol identifier
ima vrednost 0x800000450A
:
- Naredba
printf("%#lx", identifier);
ispisuje 0x8000004502. - Naredba
printf("%p", a);
ispisuje 0x8000004502. - Naredba
printf("%#lx", a[0]);
ispisuje 0x3333222222221111. - Naredba
printf("%#lx", a[1]);
ispisuje 0x8000004502. - Naredba
printf("%p", b);
ispisuje 0x800000450A. - Naredba
printf("%#lx", b[0]);
ispisuje 0x8000004502. - Naredba
printf("%#lx", b[1]);
ispisuje 0x7777666666665555.
Napomene:
- Ukoliko neku vrednost nije moguće odrediti na osnovu datog sadržaja dela memorije kao odgovor treba uneti znak pitanja (?)
- Sve odgovore za uspešno određene vrednosti treba uneti u istom formatu kakvom ih program ispisuje.
- Format
"%p"
služi za ispis vrednosti pokazivača u heksadecimalnom formatu sa prefiksom0x
(nakon prefiksa ne ispisuju se vodeće nule). - Format
"%#x"
služi za ispis neoznačenog celog broja u heksadecimalnom formatu sa prefiksom0x
(nakon prefiksa ne ispisuju se vodeće nule).
K1 - zadatak
Postavka
U nastavku je dat segment izvornog asemblerskog koda napisan za amd64 arhitekturu prema System V ABI konvenciji:
.intel_syntax noprefix
.extern bar
.text
.global foo
.type foo, @function
foo:
endbr64
sub rsp, 72
mov rdi, rsp
mov r8d, DWORD PTR 132[rsp]
mov ecx, 9
mov edx, DWORD PTR 96[rsp]
mov esi, 2
call bar
mov eax, DWORD PTR 44[rsp]
add eax, DWORD PTR 28[rsp]
add rsp, 72
ret
Napisati segment izvornog C koda, koji odgovara navedenom segmentu izvornog asemblerskog koda, tako da sadrži samo sledeće elemente:
- definicije potencijalno potrebnih tipova podataka,
- deklaraciju funkcije
bar
i - definiciju funkcije
foo
.
Napomene:
- Ukoliko se tekstualni editor Ace ne učita na ispravan način treba osvežiti internet stranicu odnosno izvršiti refresh (prethodno uneti odgovori na druga pitanja čuvaju se na serveru i neće biti izgubljeni usled osvežavanja internet stranice).
- Klikom na dugme za proveru rešenja moguće je odmah, čak i pre predaje, ispitati ispravnost rešenja. Penalty regime definiše iznos kazne odnosno penala za svaku proveru rešenja izraženo u procentima maksimalnog mogućeg broja poena za ovo pitanje. U skladu sa vrednošću Penalty regime penali za proveru rešenja redom iznose 0%, 0%, 0%, 30%, 40%, 50% i 60%. Dakle, samo prve tri provere rešenja ne uzrokuju nikakav penal, četvrta provera rešenja uzrokuje penal od 30%, peta penal od 40%, šesta penal od 50%, dok svaka provera rešenja počev od sedme uzrokuje penal od 60% (potpuno tačno rešenje koje je proveravano sedam ili više puta biće ocenjeno sa (100 - 60)% poena).
Rešenje
typedef struct
{
int array[16];
} StructType;
extern StructType bar(int a, int b, int c, int d);
int foo(StructType param)
{
StructType result = bar(2, param.array[4], 9, param.array[13]);
return result.array[7] + result.array[11];
}