Системски софтвер/Пробни тестови 2022

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

Пробни тестови 2022 били су дати на Moodle курсу предмета.

  • За питања са више одговора, тачни одговори су подебљани и уоквирени
  • За питања за које се одговори уносе, тачни одговори су подвучени и сакривени, тако да се прикажу када изаберете тај текст (пример: овако)
  • Притисните лево дугме испод за сакривање и откривање свих одговора, или десно дугме за укључивање и искључивање интерактивног режима:

К1 - теорија

1. задатак

У наставку су дате дефиниције неких типова података StructTypeA и 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;

Допунити следеће констатације уколико се посматра amd64 архитектура и System V ABI конвенција:

  • Величина структуре StructTypeB изражено у бајтовима односно sizeof(StructTypeB) износи 48.
  • Померај до поља fB4.fA1 гледано од почетка структуре StructTypeB износи 16 изражено у броју адресибилних јединица (бајтова).
  • Најдужи континуални низ неискоришћених односно padding бајтова у оквиру структуре StructTypeB почиње на померају 17 изражено у броју адресибилних јединица (бајтова) гледано од почетка структуре StructTypeB.
  • Структура StructTypeB садржи укупно 24 неискоришћених односно padding бајтова.

Напомене:

  • Све одговоре треба унети у децималном формату.

2. задатак

У наставку је дата декларација функције foo и дефиниције пратећих типова података:

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);

Допунити следеће констатације уколико се посматра amd64 архитектура и System V ABI конвенција:

  • Повратна вредност функције foo прослеђује се као меморијски простор алоциран од стране позиваоца назад до позиваоца.
  • Параметар param0 прослеђује се као rsi у функцију foo приликом њеног позива.
  • Параметар param1 прослеђује се као xmm0 у функцију foo приликом њеног позива.
  • Параметар param2 прослеђује се као stackPushII у функцију foo приликом њеног позива.
  • Параметар param3 прослеђује се као rdx у функцију foo приликом њеног позива.
  • Параметар param4 прослеђује се као stackPushI у функцију foo приликом њеног позива.
  • Параметар param5 прослеђује се као xmm1 у функцију foo приликом њеног позива.
  • Параметар param6 прослеђује се као rcx у функцију foo приликом њеног позива.

Напомене:

  • Одговор комбинација GP представља одређену комбинацију (више од једног) искључиво General Purpose регистара.
  • Одговор комбинација SSE представља одређену комбинацију (више од једног) искључиво Streaming SIMD Extension регистара.
  • Одговор комбинација GP/SSE представља одређену комбинацију (више од једног) General Purpose и Streaming SIMD Extension регистара.
  • Одговор stackPush<roman-numeral>, где је <roman-numeral> римски број, представља аргумент који се прослеђује преко стека при чему римски број означава међусобни поредак push операција односно редослед стављања датог аргумента на врх стека у односу на друге аргументе који се такође прослеђују преко стека.

3. задатак

Да ли функција, која током свог извршавања позива друге функције, сме без претходне алокације да користи стек за чување локалних променљивих уколико се посматра amd64 архитектура и System V ABI конвенција?

  1. Да, јер надаље позване функције неће мењати садржај меморије који одговара врху стека.
  2. Да, услед постојања имплицитне алокације стека приликом уласка у функцију.
  3. Да, због постојања "црвене зоне".
  4. Не.

4. задатак

У наставку је дат садржај датотеке syscall.s са изворним асемблерским кодом:

.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

Посматра се amd64 архитектура и System V ABI конвенција, а покренуте су следеће команде:

as -o syscall.o syscall.s
ld --entry=entry -o executable syscall.o
./executable
  1. Није могуће добити извршну датотеку executable зато што у процес линковања нису укључене C runtime објектне датотеке.
  2. Није могуће добити извршну датотеку executable зато што у процес линковања није укључена стандардна C библиотека.
  3. Програм се регуларно извршава и исписује поруку Hello World! на стандардни излаз.
  4. Програм се регуларно извршава, али неће исписати поруку Hello World! зато што се врти у бесконачној петљи.
  5. Није могуће добити извршну датотеку executable зато што симбол који представља улазну тачку није видљив линкеру.

5. задатак

Посматра се програм описан садржајем дела меморије и сегментом изворног C кода.

Иницијални садржај дела меморије (дат у "школском" формату приказаном на аудиторним вежбама):

    +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

Сегмент изворног C кода:

#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]);
}

Допунити следеће констатације уколико се посматра amd64 архитектура и System V ABI конвенција, а симбол identifier има вредност 0x800000450A:

  • Наредба printf("%#lx", identifier); исписује 0x8000004502.
  • Наредба printf("%p", a); исписује 0x8000004502.
  • Наредба printf("%#lx", a[0]); исписује 0x3333222222221111.
  • Наредба printf("%#lx", a[1]); исписује 0x8000004502.
  • Наредба printf("%p", b); исписује 0x800000450A.
  • Наредба printf("%#lx", b[0]); исписује 0x8000004502.
  • Наредба printf("%#lx", b[1]); исписује 0x7777666666665555.

Напомене:

  • Уколико неку вредност није могуће одредити на основу датог садржаја дела меморије као одговор треба унети знак питања (?)
  • Све одговоре за успешно одређене вредности треба унети у истом формату каквом их програм исписује.
  • Формат "%p" служи за испис вредности показивача у хексадецималном формату са префиксом 0x (након префикса не исписују се водеће нуле).
  • Формат "%#x" служи за испис неозначеног целог броја у хексадецималном формату са префиксом 0x (након префикса не исписују се водеће нуле).

К1 - задатак

Поставка

У наставку је дат сегмент изворног асемблерског кода написан за amd64 архитектуру према System V ABI конвенцији:

.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

Написати сегмент изворног C кода, који одговара наведеном сегменту изворног асемблерског кода, тако да садржи само следеће елементе:

  • дефиниције потенцијално потребних типова података,
  • декларацију функције bar и
  • дефиницију функције foo.

Напомене:

  • Уколико се текстуални едитор Ace не учита на исправан начин треба освежити интернет страницу односно извршити refresh (претходно унети одговори на друга питања чувају се на серверу и неће бити изгубљени услед освежавања интернет странице).
  • Кликом на дугме за проверу решења могуће је одмах, чак и пре предаје, испитати исправност решења. Penalty regime дефинише износ казне односно пенала за сваку проверу решења изражено у процентима максималног могућег броја поена за ово питање. У складу са вредношћу Penalty regime пенали за проверу решења редом износе 0%, 0%, 0%, 30%, 40%, 50% и 60%. Дакле, само прве три провере решења не узрокују никакав пенал, четврта провера решења узрокује пенал од 30%, пета пенал од 40%, шеста пенал од 50%, док свака провера решења почев од седме узрокује пенал од 60% (потпуно тачно решење које је проверавано седам или више пута биће оцењено са (100 - 60)% поена).

Решење

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];
}