###### tags: `ASK` # Lista 4 ## Zadanie 1 ![](https://i.imgur.com/6HW1xc1.png) Oblicz wartość poniższych operandów źródłowych operacji *movq*: 1. `%rax` $\to$ `0x100` 2. `0x110` $\to$ `0x13` 3. `$0x108` $\to$ `0x108` (`$` - używany do oznaczenia stałych) 4. `(%rax)` $\to$ `0xFF` 5. `8(%rax)` $\to$ `(%rax + 8)` $\to$ `(0x108)` $\to$ `0xAB` 6. `21(%rax,%rdx)` $\to$ `(%rax + %rdx + 21)` $\to$ `(0x100 + 3 + 21)` $\to$ `(0x118)` $\to$ `0x11` 7. `0xFC(,%rcx,4)` $\to$ `(4 * %rcx + 0xFC)` $\to$ `(0x4 + 0xFC)` $\to$ `(0x100)` $\to$ `0xFF` 8. `(%rax,%rdx,8)` $\to$ `(0x100 + 8 * %rdx)` $\to$ `(0x100 + 24)` $\to$ `(0x118)` $\to$ `0x11` 9. `265(%rcx,%rdx,2)` $\to$ `(%rcx + 2 * %rdx + 265)` $\to$ `(1 + 6 + 265)` $\to$ `(272)` $\to$ `(0x110)` $\to$ `0x13` ## Zadanie 2 | instrukcja | adres / rejestr | wartość | | ------------------------ | --------------------- | --------------------------------------------------| | `addq %rcx,(%rax)` | `0x100` | `0xFF + 0x1 = 0x100` | | `subq 16(%rax),%rdx` | `%rdx` |`3 - (0x100 + 16) = 3 - (0x110) = 3 - 0x13 = -0x10`| | `shrq $4,%rax` | `%rax` | `0x100 >> 4 = 0x10` | | `incq 16(%rax)` |`(%rax + 16) = (0x110)`| `0x13 + 0x1 = 0x14` | | `decq %rcx` | `%rcx` | `0x1 - 0x1 = 0x0` | | `imulq 8(%rax)` | `%rax` | `(%rax + 8) * %rax = 0xAB * 0x100= 0xAB00` | |`leaq 7(%rcx,%rcx,8),%rdx`| `%rdx` | `(%rcx + 8 * %rcx + 7) = (0x10) => 0x10` | | `leaq 0xA(,%rdx,4),%rdx` | `%rdx` |`(%rdx * 4 + 0xA) = (0xC + 0xA) = (0x16) => 0x16` | `imul` one-operand form — This form is identical to that used by the MUL instruction. Here, the source operand (in a general-purpose register or memory location) is multiplied by the value in the AL, AX, EAX, or RAX register (depending on the operand size) and the product (twice the size of the input operand) is stored in the AX, DX:AX, EDX:EAX, or RDX:RAX registers, respectively. ## Zadanie 3 - brak $s_0 = x_0$ $s_i = \alpha \cdot x_i + (1 - \alpha) \cdot s_{i-1},\ \ \ i > 0$ ## Zadanie 4 W wyniku deasemblacji procedury `long decode(long x, long y)` otrzymano kod: ```c= decode: leaq (%rdi,%rsi), %rax xorq %rax, %rdi xorq %rax, %rsi movq %rdi, %rax andq %rsi, %rax shrq $63, %rax ret ``` ```c= long decode(long x, long y) { long result = x + y; // leaq (%rdi,%rsi), %rax x = result ^ x; // xorq %rax, %rdi y = result ^ y; // xorq %rax, %rsi result = x; // movq %rdi, %rax result &= y; // andq %rsi, %rax result = (result >> 63) & 1; // shrq $63, %rax return result; // ret } ``` ```c= long decode(long x, long y) { return ((((x + y) ^ x) & ((x + y) ^ y)) >> 63) & 1; } ``` ## Zadanie 5 ![](https://i.imgur.com/v4c7hvp.png) `%di` zawiera dwa młodsze bajty %edi Ponumerujmy bajty w `%edi` jako 1 2 3 4 ```assembly= rorw %di, $8 // 1 2 4 3 rorl %edi, $16 // 4 3 1 2 rorw %di, $8 // 4 3 2 1 movl %edi, %eax ret ``` Tłumaczenie roll: ```c (x & 0xFF000000) >> 24 | (x & 0x00FFFFFF) << 8; ``` Tłumaczenie rorl: ```c (x & 0x000000FF) << 24 | (x & 0xFFFFFF00) >> 8; ``` ## Zadanie 6 ```assembly= addq %rsi, %rcx adc %rdi, %rdx movq %rcx, %rax ret ``` https://stackoverflow.com/questions/4153852/assembly-adc-add-with-carry-to-c ## Zadanie 7 Wiemy, że $x = x_1 \cdot 2^{64} + x_0$ oraz $y = y_1 \cdot 2^{64} + y_0$. Wtedy $x*y = (x_1 \cdot 2^{64} + x_0)\cdot (y_1 * 2^{64} + y_0) = x_1\cdot y_1\cdot 2^{128} + (x_1\cdot y_0 + x_0\cdot y_1)\cdot 2^{64} + x_0\cdot y_0$. Wartość $x_1\cdot y_1\cdot 2^{128}$ jest za duża, więc ją pomijamy. $x_1=\%rdi$ $x_0=\%rsi$ $y_1=\%rdx$ $y_0=\%rcx$ ``` multiply: movq %rdx, %rax mulq %rsi movq %rax, %r8 movq %rdi, %rax mulq %rcx addq %rax, %r8 movq %rsi, %rax mulq %rcx addq %r8, %rdx ret ``` ![](https://i.imgur.com/ta86IfH.png) ![](https://i.imgur.com/df0bBv1.jpg) ## Zadanie 8 Wartości $x$ i $y$ typu `uint64_t` są przekazywane przez rejestry `%rdi` i `%rsi`, a wynik zwracany w rejestrze `%rax` $$ \begin{equation} addu(x,y)= \begin{cases} ULONG\_MAX & \text{dla } x+y\geq ULONG\_MAX\\ x+y & \text{w p.p.} \end{cases} \end{equation} $$ Najpierw rozwiąż zadanie używając instrukcji skoku warunkowego `jnc` $\to$ skok, jeśli nie ma przeniesienia, flaga `CF = 0` ```assembly= addq %rsi, %rdi jnc jump movq $ULONG_MAX, %rdi jump: movq %rdi, %rax ``` Potem przepisz je używając instrukcji `sbb` `sbb A B` - Subtraction with Borrow - działanie $\to$ odejmuje `B` i flagę `CF` od `A` - wynik przechowuje w `A` - `A` $\to$ rejestr lub adres pamięci - `B` $\to$ konkretna wartość, rejestr lub adres pamięci (ale tylko jeśli A również nie jest adresem pamięci). ```assembly= addq %rsi, %rdi // ustawi flagę CF sbbq %rax, %rax // %rax = %rax − (%rax + CF) // %rax = -CF orq %rdi, %rax // dla %rax = -1 zwróci ULONG_MAX // dla %rax = 0 zwróci %rdi ``` ## Zadanie 9 ```cpp long cmp(uint64_t x, uint64_t y); ``` `%rdi := x` pierwszy argument funkcji. `%rsi := y` drugi argument funkcji. Wartość będzie zwracana orzez `%rax`. Wykorzystywać będziemy **Carry Flag**. Flaga będzie ustawiana przez operację `subq` jeżeli będziemy odejmować większą liczbę od mniejszej. `adc Src, Dest` - `Dest := Dest + Src + CF` `sbb Src, Dest` - `Dest := Dest - (Src + CF)` `neg Dest` - `CF := !(Dest == 0)`, `Dest := -Dest` ``` if(Destination == 0) CF = 0; else CF = 1; ``` ```assembly= subq %rsi, %rdi // x = x - y sbbq %rax, %rax negq %rdi // if x != y: CF := 1 adcq %rax, %rax ret ``` 1. `x > y`: - `CF := 0 and %rdi != 0` - `%rax := 0` - `CF := 1` - `%rax := 1` 2. `x < y`: - `CF := 1 and %rdi != 0` - `%rax := -1` - `CF := 1` - `%rax := -1` 3. `x == y`: - `CF := 0 and %rdi := 0` - `%rax := 0` - `CF := 0` - `%rax := 0`