---
# System prepended metadata

title: 'Lista 5 (01.04.2021), grupa pwit'
tags: [pwit, ask21, ćwiczenia]

---

# Lista 5 (01.04.2021), grupa pwit

###### tags: `ask21` `ćwiczenia` `pwit`

## Deklaracje

Gotowość rozwiązania zadania należy wyrazić poprzez postawienie X w odpowiedniej kolumnie! Jeśli pożądasz zreferować dane zadanie (co najwyżej jedno!) w trakcie dyskusji oznacz je znakiem ==X== na żółtym tle.

**UWAGA: Tabelkę wolno edytować tylko wtedy, gdy jest na zielonym tle!**




:::danger
|                      | 1   | 2   | 3   | 4   |  5  |
| --------------------:| --- | --- | --- | --- |:---:|
|Wojciech Adamiec      |  X  |     |     |  X  |  X  |
|Kacper Bajkiewicz     |  X  |  X  |  X  |==X==|  X  |
|Bartłomiej Hildebrandt|  X  |  X  |  X  |  X  |  X  |
|Dominik Komła         |  X  |  X  |  X  |  X  |  X  |
|Aleksandra Kosińska   |  X  |  X  |     |     |     |
|Oleś Kulczewicz       |  X  |  X  |  X  |  X  |  X  |
|Damian Lukas          |  X  |  X  |  X  |  X  |     |
|Michał Mikołajczyk    |  X  |  X  |     |  X  |  X  |
|Mateusz Opala         |  X  |  X  |  X  |  X  |  X  |
|Łukasz Orawiec        |  X  |  X  |  X  |  X  |  X  |
|Szymon Pielat         |  X  |  X  |     |  X  |  X  |
|Łukasz Pluta          |  X  |  X  |  X  |  X  |  X  |
|Kamil Puchacz         |  X  |  X  |  X  |  X  |  X  |
|Magdalena Rzepka      |     |     |     |     |     |
|Cezary Stajszczyk     |  X  |  X  |     |     |     |
|Jakub Szajner         |  X  |  X  |  X  |  X  |  X  |
|Bartosz Troszka       |  X  |  X  |  X  |  X  |  X  |
|Miłosz Urbanik        |  X  |  X  |  X  |  X  |  X  |



:::

## Zadanie 1
:::info
Autor: Szymon Pielat	
:::
![](https://i.imgur.com/Iv2SjQw.png)

```=
%rdi = x %esi = n %eax = res

puzzle: testl %esi, %esi   // ZF = 1 if a&b ==0
        je .L4             // jeśli ZF == 1 
        xorl %edx, %edx    // i = 0
        xorl %eax, %eax    // res = 0
.L3:    movl %edi, %ecx    // %ecx = x (mlodsze 32 bity)
        andl $1, %ecx      // %ecx = x & 1
        addl %ecx, %eax    // res += x & 1
        sarq %rdi          // x = x >> 1
        incl %edx          // i += 1
        cmpl %edx, %esi    // cmp(n, i)
        jne .L3            // n != i -> loop .L3
        ret                // return %eax (res)
.L4:    movl %esi, %eax    // res = n
        ret                // return %eax (res)
```
```c=
%rdi = x %esi = n %eax = res

// zwraca liczbę zapalonych bitów w n najmłodszych bitach x
int puzzle(long x, unsigned n) { 
    if (n == 0) 
        return 0;
    else {
      int res = 0;
      for(unsigned i = 0; i != n; ++i)
          res += 1 & x;
          x = x >> 1;
      }
      return res;
    }
}

```

## Zadanie 2
:::info
Autor: Michał Mikołajczyk	
:::

:::info
Poniżej zamieszczono kod procedury o sygnaturze «long puzzle2(char *s, char *d)». Wyznacz bloki podstawowe oraz narysuj graf przepływu sterowania. Przetłumacz tę procedurę na język C, a następnie jednym zdaniem powiedz co ona robi.
:::
```c=
char *res   = %rax (%al)
char *s     = %rdi (%dil)
char *d     = %rsi (%sil)
char  s_chr = %r9b
char *s_ptr = %r8  (%r8b)
char *d_ptr = %rdx (%dl)
char  d_chr = %cl

puzzle2:
        movq  %rdi, %rax   // B1, res = s
.L3:    movb  (%rax), %r9b // B2, s_chr = *res
        leaq  1(%rax), %r8 //     s_ptr = res+1
        movq  %rsi, %rdx   //     d_ptr = d
.L2:    movb  (%rdx), %cl  // B3, d_chr = *d_ptr
        incq  %rdx         //     d_ptr++
        testb %cl, %cl     //     ZF = 1 if a & b == 0
        je    .L4          //     d_chr == 0 (null char) => goto .L4
        cmpb  %cl, %r9b    // B4, cmp(s_chr, d_chr)
        jne   .L2          //     s_chr != d_chr => goto .L2
        movq  %r8, %rax    // B5, res = s_ptr
        jmp   .L3          //     goto .L3
.L4:    subq  %rdi, %rax   // B6, res = s
        ret                //     return (long)res
```


```c=
long puzzle2(char *s, char *d) {
    char *res = s;
    while (true) {
        char s_chr = *res;
        char *s_ptr = res+1;
        char d_chr;
        char *d_ptr = d;         
        do {
            d_chr = *d_ptr;
            d_ptr++;
            if (d_chr == 0) { // d_chr = 0 => koniec d
                res -= s;
                return (long)res;
            }
        } while (s_chr != d_chr);
        res = s_ptr;
    }
}
```
Funkcja puzzle2 zwraca długośc najdłuższego prefiksu s, który zawiera litery występujące w d.

```graphviz
digraph przepływ {
            START -> B1;
            B1 -> B2;
            B2 -> B3;
            B3 -> B6;
            B3 -> B4;
            B4 -> B3;
            B4 -> B5;
            B5 -> B2;
            B6 -> END;
}
``` 

## Zadanie 3
:::info
Autor: Dominik Komła	
:::

```graphviz
digraph g{
    B1->B2;
    B2->B3;
    B2->B4;
    B3->B4;
    B4->B2;
    B4->B5;
    }
```

```=
puzzle3:
        movl %edi, %edi	                #B1
	salq $32, %rsi
	movl $32, %edx
	movl $0x80000000, %ecx
	xorl %eax, %eax
.L3:	addq %rdi, %rdi                #B2
	movq %rdi, %r8              pom = n
	subq %rsi, %r8              pom -= d;
	js .L2
        orl %ecx, %eax			        #B3
	movq %r8, %rdi            n = pom     n -= d
.L2:	shrl %ecx			            #B4
	decl %edx
	jne .L3
        ret				               #B5
```
n - rdi
d - rsi

```c=
uint32_t puzzle3(uint32_t n, uint32_t d)
{
    uint32_t res = 0;
    uint64_t d2 = d;
    d2<<=32;
    uint64_t n2 = n;
    uint32_t m=0x80000000;
    for(int i=32;i>0;i--)
    {
        n2<<=1;
        if(n2 >= d2)
        {
            res |= m;
            n2 -= d2;
        }
        m>>=1;
    }
    return res;
}
```

```
12 / 4 na 5 bitach
n = 12
d = 4
new_d = 0b0100 << 5 == 0b010000000 = 128
edx = 5
ecx = 0b10000 = 2^4 = 16
eax = 0

do:
    new_n = 24
    r8 = 24
    r8 - new_d = bardzo duża lczba na minusie
    nie wchdzi do ifa
    przesuwamy ecx w prawo o 1: ecx = 0b01000 = 8
    edx = 4
do:
    new_n = 48
    r8 = 48
    r8= r8 - new_d - bardzo duża lczba na minusie
    nie wchdzi do ifa
    przesuwamy ecx w prawo o 1: ecx = 0b00100 = 4
    edx = 3
do:
    new_n = 96
    r8 = 96
    r8=r8 - new_d - bardzo duża lczba na minusie
    nie wchdzi do ifa
    przesuwamy ecx w prawo o 1: ecx = 0b000010 = 2
    edx = 2
do:
    new_n = 192
    r8 = 192
    r8 = r8 - new_d = 64 > 0 czyl wchodzi do ifa
    eax było 0 a teraz robimy eax |= ecx czyli eax = 2
    new_n = 64
    ecx = 1
    edx = 1
do:
    new_n = 128
    r8 = 128
    r8 = r8 - new_d = 0 >= 0 czyl wchodzi do ifa
    eax było 2 a teraz robimy eax |= ecx czyli eax = 3
    new_n = 0
    ecx = 0
    edx = 0
    
wychodzimy z pętli
zwracamy eax, które jest równe 3
```

Funkcja liczy $\lfloor\frac{n}{d}\rfloor$ używając dzielenia pisemnego.

"Restoring division"

## Zadanie 4
:::info
Autor: Kacper Bajkiewicz	
:::
a -> %rdi
v -> %rsi
s -> %rdx
e -> %rcx

Przenosimy wartość e do do raxa, odejmujemy od niej s, dzielimy wszystko przez 2 i dodajemy wartość rax do rdx.
Czyli w rax znajduje sie (e-s)/2 + s. Porównujemy rdx < rcx, jeśli tak to wtychdozimy z programu ze zwrotem -1.
Jeśli nie to do %r8 przenosimy wartość z %rdi + %rax * 8, czyli tak naprawdę wartość ze środka tablicy danej wskaźnikiem a.
Jeśli v == tej wartości, to wychodzimy z indeksem w raxie.

Wpp jeśli v < tej wartości, to do rdx (start) przenosimy %rax + 1, czyli środek podtablicy + 1 i wywołujemy procedurę z takimi argumentami:
a -> a
v -> v
s -> (e-s)/2 + s + 1
e -> e
Wpp za e wstawiamy środek - 1, czyli ( e-s )/2 + s - 1 i wywołujemy.

Bloki podstawowe:
```=
puzzle4:  movq %rcx, %rax                            ;B1
          subq %rdx, %rax
          shrq %rax
          addq %rdx, %rax
          cmpq %rdx, %rcx
          jb .L5                                      
          movq (%rdi,%rax,8), %r8                    ;B2
          cmpq %rsi, %r8
          je .L10                                    
          cmpq %rsi, %r8                             ;B3
          jg .L11                                    
          leaq 1(%rax), %rdx                         ;B4
          call puzzle4        
.L10:     ret                                        ;B5
.L11:     leaq -1(%rax), %rcx                        ;B6
          call puzzle4       
          ret          
.L5:      movl $-1, %eax                             ;B7
          ret
```

Kod w C:
```c=
int puzzle4 (long* a, long v, uint64_t s, uint64_t e)
{
    if ( e < s ){
        return -1;
    } 
    uint64_t mid = ( e-s ) / 2 + s;
    long midEl = a[mid];
    
    if ( midEl == v ){
        return mid;
    } 
    if ( v < mid ){
        return puzzle4( a, v, s, mid - 1 );
    } 
    return puzzle4( a, v, mid + 1, e );
}
```
```graphviz
digraph{
B1 -> B2
B2 -> B3
B1 -> B7
B3 -> B4
B2 -> B5
B3 -> B6
B7 -> EXIT
B6 -> EXIT
B5 -> EXIT
B4 -> B5
}
```

## Zadanie 5
:::info
Autor: Mateusz Opala	
:::

x - rdi
n - rsi

```c=
long switch_prob(long x, long n)
{
    switch(n)
    {
        case 60:
            return x * 8;
        case 61:
            return x * 8;
        case 64:
            return x >> 3;
        case 62:
            x *= 15;
        case 65:
            x *= x;
        default:
            return x + 75;
    }
}
```
