Sistemski softver/Probni testovi 2022

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

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 odnosno sizeof(StructTypeB) iznosi 48.
  • Pomeraj do polja fB4.fA1 gledano od početka strukture StructTypeB 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 strukture StructTypeB.
  • 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 funkciju foo prilikom njenog poziva.
  • Parametar param1 prosleđuje se kao xmm0 u funkciju foo prilikom njenog poziva.
  • Parametar param2 prosleđuje se kao stackPushII u funkciju foo prilikom njenog poziva.
  • Parametar param3 prosleđuje se kao rdx u funkciju foo prilikom njenog poziva.
  • Parametar param4 prosleđuje se kao stackPushI u funkciju foo prilikom njenog poziva.
  • Parametar param5 prosleđuje se kao xmm1 u funkciju foo prilikom njenog poziva.
  • Parametar param6 prosleđuje se kao rcx u funkciju foo 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?

  1. Da, jer nadalje pozvane funkcije neće menjati sadržaj memorije koji odgovara vrhu steka.
  2. Da, usled postojanja implicitne alokacije steka prilikom ulaska u funkciju.
  3. Da, zbog postojanja "crvene zone".
  4. 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
  1. Nije moguće dobiti izvršnu datoteku executable zato što u proces linkovanja nisu uključene C runtime objektne datoteke.
  2. Nije moguće dobiti izvršnu datoteku executable zato što u proces linkovanja nije uključena standardna C biblioteka.
  3. Program se regularno izvršava i ispisuje poruku Hello World! na standardni izlaz.
  4. Program se regularno izvršava, ali neće ispisati poruku Hello World! zato što se vrti u beskonačnoj petlji.
  5. 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 prefiksom 0x (nakon prefiksa ne ispisuju se vodeće nule).
  • Format "%#x" služi za ispis neoznačenog celog broja u heksadecimalnom formatu sa prefiksom 0x (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];
}