diff options
| author | Mike Vink <mike@pionative.com> | 2024-06-14 09:23:32 +0200 |
|---|---|---|
| committer | Mike Vink <mike@pionative.com> | 2024-06-14 09:23:32 +0200 |
| commit | 8092f4c334db547ced59d6f439b558dad35e1ab2 (patch) | |
| tree | fa462fa885efea1ec6095d015286998d632c2c3d | |
| parent | b424517a33bf61aedff29eed74a665402ab496ba (diff) | |
commit for once
20 files changed, 721 insertions, 0 deletions
diff --git a/3/10_control_and_data/00_prog.c b/3/10_control_and_data/00_prog.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/3/10_control_and_data/00_prog.c diff --git a/3/10_control_and_data/01_echo.c b/3/10_control_and_data/01_echo.c new file mode 100644 index 0000000..8ef71e2 --- /dev/null +++ b/3/10_control_and_data/01_echo.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +char* gets(char *s) { + int c; + char *dest = s; + while ((c = getchar()) != '\n' && c != EOF) { + *dest++ = c; + } + if ( c == EOF && dest == s) { + return NULL; + } + *dest++ = '\0'; + return s; +} + +void echo() { + char buf[8]; + gets(buf); + puts(buf); +} + +int main(void) { + echo(); +} diff --git a/3/10_control_and_data/46_get_line.c b/3/10_control_and_data/46_get_line.c new file mode 100644 index 0000000..f1920e8 --- /dev/null +++ b/3/10_control_and_data/46_get_line.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +// char *get_line() +// 400720: 53 push %rbx +// 400721: 48 83 ec 10 sub $0x10,%rsp +// 400725: 48 89 e7 mov %rsp,%rdi +// 400728 e8 73 ff ff ff callq 4006a0 <gets> +char *get_line() { + char buf[4]; + char *result; + gets(buf); + result = malloc(strlen(buf)); + strcpy(result, buf); + return result; +} +int main(void) { + printf("%s\n", get_line()); +} +// A. B. (I mistakingly thought $0x10 was the same as $10...) +// 00 34 33 32 31 30 39 38 return address +// 37 36 35 34 33 32 31 30 callee saved %rbx +// 39 38 37 36 35 34 33 32< sub $rsp - 8 +// 31 30 00 00 00 00 00 40 sub $rsp -16 +// 07 32< return address gets +// +// C. 00 34 33 32 31 30 39 38 +// D. %rbx +// E. Malloc should consider the terminating null (strlen+1) and check for NULL pointer result diff --git a/3/10_control_and_data/47_address_range.c b/3/10_control_and_data/47_address_range.c new file mode 100644 index 0000000..57a3fcb --- /dev/null +++ b/3/10_control_and_data/47_address_range.c @@ -0,0 +1,10 @@ +// +// A. Using bc +// +ibase=16; FFFFB754 +ibase=16; FFFFD754 - FFFFB754 +8192 +2^13 +// B. +2^5 +32 diff --git a/3/10_control_and_data/48_stack_protection.c b/3/10_control_and_data/48_stack_protection.c new file mode 100644 index 0000000..08cb4e8 --- /dev/null +++ b/3/10_control_and_data/48_stack_protection.c @@ -0,0 +1,52 @@ +int len(char *s) { + return strlen(s); +} + +void iptoa(char *s, long *p) { + long val = *p; + sprintf(s, "%ld", val); +} + +// int inlen(long x) +// x in %rdi +// without canary +// +// intlen: +// subq $40, %rsp allocate 5*8 bytes +// movq %rdi, 24(%rsp) put x on the stack +// leaq 24(%rsp), %rsi set &v = &x to the second argument +// movq %rsp, %rdi set buf[12] to %rsp +// call iptoa +// +// 0<rsp+32 <-? +// 0<rsp+24 <-v +// 0<rsp+16 <-? +// 0<rsp+8 <-buf[12] +// 0<rsp <-buf[12] +// +// with canary +// +// intlen: +// subq $56, %rsp +// movq %fs:40, %rax +// movq %rax, 40(%rsp) +// xorl %eax, %eax +// movq %rdi, 8(%rsp) +// leaq 8(%rsp), %rsi +// leaq 16(%rsp), %rdi +// call iptoa +// +// 0<rsp+48 <- +// 0<rsp+40 <-canary +// 0<rsp+32 <- +// 0<rsp+24 <- +// 0<rsp+16 <-buf[12] +// 0<rsp+8 <-v +// 0<rsp <- +int intlen(long x) { + long v; + char buf[12]; + v = x; + iptoa(buf, &v); + return len(buf); +} diff --git a/3/10_control_and_data/49_variable_stack.c b/3/10_control_and_data/49_variable_stack.c new file mode 100644 index 0000000..d72c235 --- /dev/null +++ b/3/10_control_and_data/49_variable_stack.c @@ -0,0 +1,81 @@ +// A. +// vframe: +// pushq %rbp +// movq %rsp, %rbp +// subq $16, %rsp +// leaq 22(,%rdi,8), %rax +// andq $-16, %rax +// +// +// bitlevel representation of -16 +// 1111111111111111111111111111111111111111111111111111111111110000 +// +// rax +// 22 + n*8 +// n=0 0000000000000000000000000000000000000000000000000000000000010110 22 +// n=1 0000000000000000000000000000000000000000000000000000000000011110 30 +// n=2 0000000000000000000000000000000000000000000000000000000000100110 38 +// n=3 0000000000000000000000000000000000000000000000000000000000101110 46 +// n=4 0000000000000000000000000000000000000000000000000000000000110110 54 +// n=5 0000000000000000000000000000000000000000000000000000000000111110 62 +// +// (22 + n*8) & -16 +// n=0 0000000000000000000000000000000000000000000000000000000000010000 16 8n+16 +// n=1 0000000000000000000000000000000000000000000000000000000000010000 16 8n+8 +// n=2 0000000000000000000000000000000000000000000000000000000000100000 32 8n+16 +// n=3 0000000000000000000000000000000000000000000000000000000000100000 32 8n+8 +// n=4 0000000000000000000000000000000000000000000000000000000000110000 48 +// n=5 0000000000000000000000000000000000000000000000000000000000110000 48 +// +// print("{:064b}".format((0*8+22) & -16)) +// print("{:064b}".format((1*8+22) & -16)) +// print("{:064b}".format((2*8+22) & -16)) +// print("{:064b}".format((3*8+22) & -16)) +// print("{:064b}".format((4*8+22) & -16)) +// print("{:064b}".format((5*8+22) & -16)) +// +// B. +// vframe: +// pushq %rbp +// movq %rsp, %rbp +// subq $16, %rsp +// leaq 22(,%rdi,8), %rax +// andq $-16, %rax +// +// subq %rax, %rsp +// +// leaq 7(%rsp), %rax rax <- (rsp+7) = (rsp+(n-1)), n = 8 +// shrq $3, %rax rax <- (floor(rax/8)) +// leaq 0(,%rax,8), %r8 r8 <- ceil(rsp/8)*8 +// +// Important We are growing the stack downwards. +// But the array index grows upwards. +// +// See 2.3.7 for derivation. +// If x%(1<<k) == 0 then the bias has no effect, rounding down does not happen, there is no fraction. +// else +// Since the operation of adding the bias and then flooring happens, +// this results in rounding towards zero, or taking the ceiling. +// +// So if rsp was a multiple of 8 then nothing happens. +// Otherwise the start of the array is set to the first multiple of 8 towards the bottom of the stack (ceil goes towards greater addresses of the bottom). +// +// C. +// +// s_2 = (- s_1 +// (+ (if (odd? n) 8 16) (* n 8) ) +// ) +// +// p = ceil(s2/8)*8 +// e2 = (- p s2) +// e1 = (- s2 s1 e2 8n) +// +// 2065 - (8+5*8) +// +// n s_1 s_2 p e_1 e_2 +// 5 2065 2017 2024 1 7 +// 6 2064 2000 2000 16 0 +// +// D. +// p is 8byte aligned owing to the 8-10 instructions. +// s2 is not guaranteed to be aligned, so 1 byte. (But all we are doing is subtracting multiples of 16 from s1... not sure how this helps) diff --git a/3/11_floating_point/00_float_mov.c b/3/11_floating_point/00_float_mov.c new file mode 100644 index 0000000..dd0379d --- /dev/null +++ b/3/11_floating_point/00_float_mov.c @@ -0,0 +1,11 @@ +// v1 in %xmm0, src in %rdi, dst in %rsi +// float_mov: +// vmovaps %xmm0, %xmm1 Copy v1 +// vmovss (%rdi), %xmm0 Read v2 from src +// vmovss %xmm1, (%rsi) Write v1 to dst +// ret; +float float_mov(float v1, float *src, float *dst) { + float v2 = *src; + *dst = v1; + return v2; +} diff --git a/3/11_floating_point/01_fcvt.c b/3/11_floating_point/01_fcvt.c new file mode 100644 index 0000000..a75ff48 --- /dev/null +++ b/3/11_floating_point/01_fcvt.c @@ -0,0 +1,17 @@ +#include <stdio.h> +double fcvt(int i, float *fp, double *dp, long *lp) { + float f = *fp; double d = *dp; long l = *lp; + *lp = (long) d; // double->long + *fp = (float) i; // int->float + *dp = (double) l; // long->double + return (double) f; // float->double +} + +int main(void) { + float f = 0.5f; double d = 1.0; long l = 1; + + float *fp = &f; double *dp = &d; long *lp = &l; + + fcvt(42, fp, dp, lp); + return 0; +} diff --git a/3/11_floating_point/fcvt.s b/3/11_floating_point/fcvt.s new file mode 100644 index 0000000..c7a3117 --- /dev/null +++ b/3/11_floating_point/fcvt.s @@ -0,0 +1,154 @@ + +./fcvt: file format elf64-x86-64 + + +Disassembly of section .init: + +0000000000401000 <_init>: + 401000: f3 0f 1e fa endbr64 + 401004: 48 83 ec 08 sub $0x8,%rsp + 401008: 48 8b 05 e9 2f 00 00 mov 0x2fe9(%rip),%rax # 403ff8 <__gmon_start__@Base> + 40100f: 48 85 c0 test %rax,%rax + 401012: 74 02 je 401016 <_init+0x16> + 401014: ff d0 call *%rax + 401016: 48 83 c4 08 add $0x8,%rsp + 40101a: c3 ret + +Disassembly of section .plt: + +0000000000401020 <__stack_chk_fail@plt-0x10>: + 401020: ff 35 b2 2f 00 00 push 0x2fb2(%rip) # 403fd8 <_GLOBAL_OFFSET_TABLE_+0x8> + 401026: ff 25 b4 2f 00 00 jmp *0x2fb4(%rip) # 403fe0 <_GLOBAL_OFFSET_TABLE_+0x10> + 40102c: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000401030 <__stack_chk_fail@plt>: + 401030: ff 25 b2 2f 00 00 jmp *0x2fb2(%rip) # 403fe8 <__stack_chk_fail@GLIBC_2.4> + 401036: 68 00 00 00 00 push $0x0 + 40103b: e9 e0 ff ff ff jmp 401020 <_init+0x20> + +Disassembly of section .text: + +0000000000401040 <_start>: + 401040: f3 0f 1e fa endbr64 + 401044: 31 ed xor %ebp,%ebp + 401046: 49 89 d1 mov %rdx,%r9 + 401049: 5e pop %rsi + 40104a: 48 89 e2 mov %rsp,%rdx + 40104d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp + 401051: 50 push %rax + 401052: 54 push %rsp + 401053: 45 31 c0 xor %r8d,%r8d + 401056: 31 c9 xor %ecx,%ecx + 401058: 48 c7 c7 4f 11 40 00 mov $0x40114f,%rdi + 40105f: ff 15 8b 2f 00 00 call *0x2f8b(%rip) # 403ff0 <__libc_start_main@GLIBC_2.34> + 401065: f4 hlt + 401066: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40106d: 00 00 00 + +0000000000401070 <_dl_relocate_static_pie>: + 401070: f3 0f 1e fa endbr64 + 401074: c3 ret + 401075: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40107c: 00 00 00 + 40107f: 90 nop + +0000000000401080 <deregister_tm_clones>: + 401080: b8 10 40 40 00 mov $0x404010,%eax + 401085: 48 3d 10 40 40 00 cmp $0x404010,%rax + 40108b: 74 13 je 4010a0 <deregister_tm_clones+0x20> + 40108d: b8 00 00 00 00 mov $0x0,%eax + 401092: 48 85 c0 test %rax,%rax + 401095: 74 09 je 4010a0 <deregister_tm_clones+0x20> + 401097: bf 10 40 40 00 mov $0x404010,%edi + 40109c: ff e0 jmp *%rax + 40109e: 66 90 xchg %ax,%ax + 4010a0: c3 ret + 4010a1: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1) + 4010a8: 00 00 00 00 + 4010ac: 0f 1f 40 00 nopl 0x0(%rax) + +00000000004010b0 <register_tm_clones>: + 4010b0: be 10 40 40 00 mov $0x404010,%esi + 4010b5: 48 81 ee 10 40 40 00 sub $0x404010,%rsi + 4010bc: 48 89 f0 mov %rsi,%rax + 4010bf: 48 c1 ee 3f shr $0x3f,%rsi + 4010c3: 48 c1 f8 03 sar $0x3,%rax + 4010c7: 48 01 c6 add %rax,%rsi + 4010ca: 48 d1 fe sar %rsi + 4010cd: 74 11 je 4010e0 <register_tm_clones+0x30> + 4010cf: b8 00 00 00 00 mov $0x0,%eax + 4010d4: 48 85 c0 test %rax,%rax + 4010d7: 74 07 je 4010e0 <register_tm_clones+0x30> + 4010d9: bf 10 40 40 00 mov $0x404010,%edi + 4010de: ff e0 jmp *%rax + 4010e0: c3 ret + 4010e1: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1) + 4010e8: 00 00 00 00 + 4010ec: 0f 1f 40 00 nopl 0x0(%rax) + +00000000004010f0 <__do_global_dtors_aux>: + 4010f0: f3 0f 1e fa endbr64 + 4010f4: 80 3d 15 2f 00 00 00 cmpb $0x0,0x2f15(%rip) # 404010 <__TMC_END__> + 4010fb: 75 13 jne 401110 <__do_global_dtors_aux+0x20> + 4010fd: 55 push %rbp + 4010fe: 48 89 e5 mov %rsp,%rbp + 401101: e8 7a ff ff ff call 401080 <deregister_tm_clones> + 401106: c6 05 03 2f 00 00 01 movb $0x1,0x2f03(%rip) # 404010 <__TMC_END__> + 40110d: 5d pop %rbp + 40110e: c3 ret + 40110f: 90 nop + 401110: c3 ret + 401111: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1) + 401118: 00 00 00 00 + 40111c: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000401120 <frame_dummy>: + 401120: f3 0f 1e fa endbr64 + 401124: eb 8a jmp 4010b0 <register_tm_clones> + +0000000000401126 <fcvt>: + 401126: c5 f0 57 c9 vxorps %xmm1,%xmm1,%xmm1 + 40112a: c5 fa 10 06 vmovss (%rsi),%xmm0 + 40112e: 48 8b 01 mov (%rcx),%rax + 401131: c4 61 fb 2c 02 vcvttsd2si (%rdx),%r8 + 401136: 4c 89 01 mov %r8,(%rcx) + 401139: c5 f2 2a d7 vcvtsi2ss %edi,%xmm1,%xmm2 + 40113d: c5 fa 11 16 vmovss %xmm2,(%rsi) + 401141: c4 e1 f3 2a c8 vcvtsi2sd %rax,%xmm1,%xmm1 + 401146: c5 fb 11 0a vmovsd %xmm1,(%rdx) + 40114a: c5 fa 5a c0 vcvtss2sd %xmm0,%xmm0,%xmm0 + 40114e: c3 ret + +000000000040114f <main>: + 40114f: 48 83 ec 28 sub $0x28,%rsp + 401153: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax + 40115a: 00 00 + 40115c: 48 89 44 24 18 mov %rax,0x18(%rsp) + 401161: 31 c0 xor %eax,%eax + 401163: c7 44 24 04 00 00 00 movl $0x3f000000,0x4(%rsp) + 40116a: 3f + 40116b: 48 8b 05 96 0e 00 00 mov 0xe96(%rip),%rax # 402008 <_IO_stdin_used+0x8> + 401172: 48 89 44 24 08 mov %rax,0x8(%rsp) + 401177: 48 c7 44 24 10 01 00 movq $0x1,0x10(%rsp) + 40117e: 00 00 + 401180: 48 8d 4c 24 10 lea 0x10(%rsp),%rcx + 401185: 48 8d 54 24 08 lea 0x8(%rsp),%rdx + 40118a: 48 8d 74 24 04 lea 0x4(%rsp),%rsi + 40118f: bf 2a 00 00 00 mov $0x2a,%edi + 401194: e8 8d ff ff ff call 401126 <fcvt> + 401199: 48 8b 44 24 18 mov 0x18(%rsp),%rax + 40119e: 64 48 2b 04 25 28 00 sub %fs:0x28,%rax + 4011a5: 00 00 + 4011a7: 75 0a jne 4011b3 <main+0x64> + 4011a9: b8 00 00 00 00 mov $0x0,%eax + 4011ae: 48 83 c4 28 add $0x28,%rsp + 4011b2: c3 ret + 4011b3: e8 78 fe ff ff call 401030 <__stack_chk_fail@plt> + +Disassembly of section .fini: + +00000000004011b8 <_fini>: + 4011b8: f3 0f 1e fa endbr64 + 4011bc: 48 83 ec 08 sub $0x8,%rsp + 4011c0: 48 83 c4 08 add $0x8,%rsp + 4011c4: c3 ret diff --git a/3/7_procedures/35_rfun.c b/3/7_procedures/35_rfun.c new file mode 100644 index 0000000..f923366 --- /dev/null +++ b/3/7_procedures/35_rfun.c @@ -0,0 +1,25 @@ +// x in %rdi +// rfun: +// pushq %rbx save rbx, since we use it and in case we are called +// movq %rdi, %rbx %rbx <- x +// movl $0 %rax <- 0 +// testq %rdi, %rdi ZF <- %rdi == 0 +// je .L2 jump to if ZF +// shrq $2, %rdi shift x to the lift by 2 bits (divide by four) +// call rfun +// addq %rbx, %rax add our calculation to the rest +// .L2 +// popq %rbx set rbx back to the value of our caller's calculation +// ret +// +// A> +// The value x is stored in rbx, and each iteration stores (int64_t) x/4 +// B> +long rfun(unsigned long x) { + if (x == 0) { + return 0; + } + unsigned long nx = x>>2; + long rv = rfun(nx); + return x + rv; +} diff --git a/3/8_array_allocation_and_access/36_sizes_and_addresses.c b/3/8_array_allocation_and_access/36_sizes_and_addresses.c new file mode 100644 index 0000000..c9b8056 --- /dev/null +++ b/3/8_array_allocation_and_access/36_sizes_and_addresses.c @@ -0,0 +1,11 @@ +// size total size start address element i +short S[7]; +// 2 14 x_s xs + 2 * i +short *T[3]; +// 8 24 x_t x_t + 8 * i +short **U[6]; +// 8 48 x_u x_u + 8 * i +int V[8]; +// 4 32 x_v x_v + 4 * i +double *W[4]; +// 8 32 x_w x_w + 8 * i diff --git a/3/8_array_allocation_and_access/37_array_arithmetic.c b/3/8_array_allocation_and_access/37_array_arithmetic.c new file mode 100644 index 0000000..c2ecbf2 --- /dev/null +++ b/3/8_array_allocation_and_access/37_array_arithmetic.c @@ -0,0 +1,7 @@ +// S and i in rdx and rcx +// type value assembly +// S+1 short * xs + 2 leaq $2(%rdx), %rax, // leaq since we want to store the address not the value +// S[3] short M[xs+6] movw $6(%rdx), %ax +// &S[i] short * xs+2i leaq (rdx, rcx, 2), %rax +// S[4*i+1] short M[xs+8i+2] movw $2(%rdx, %rcx, 8), %ax +// S+i-5 short * xs+2i-10 leaq $-10(%rdx, %rcx, 2), %rax diff --git a/3/8_array_allocation_and_access/38_nested_arrays.c b/3/8_array_allocation_and_access/38_nested_arrays.c new file mode 100644 index 0000000..b53c7be --- /dev/null +++ b/3/8_array_allocation_and_access/38_nested_arrays.c @@ -0,0 +1,18 @@ +#define M 20; +#define N 30; + +long P[5][7]; +long Q[7][5]; + +// i in rdi, j in rsi +// sum_element: +// leaq 0(,%rdi, 8), %rdx %rdx <- 8*i +// subq %rdi, %rdx %rdx <- %rdx - i +// addq %rsi, %rdx %rdx <- %rdx + j +// leaq (%rsi, %rsi, 4), %rax %rax <- 5j +// addq %rax, %rdi %rdi <- %rax + %rdi // rdi <- 5j + i +// movq Q(, %rdi, 8), %rax %rax <- xq + 8(5j + i) +// addq P(, %rdx, 8), %rax %rax <- %rax + xp + 8(7i + j) +long sum_element(long i, long j) { + return P[i][j] + Q[j][i]; +} diff --git a/3/8_array_allocation_and_access/39_explain_rows_cols.c b/3/8_array_allocation_and_access/39_explain_rows_cols.c new file mode 100644 index 0000000..7304f23 --- /dev/null +++ b/3/8_array_allocation_and_access/39_explain_rows_cols.c @@ -0,0 +1,8 @@ +// addq %rdx, %rdi Aptr = xa + 64i +// fix_matrix = int[16][16], so each int is 4 bytes and we need to multiple by the number of columns to find the +// i row, A + L(C*i + j) <=> A + 4(16*i) +// +// leaq (%rsi, %rcx, 4), %rcx Bptr = xb + 4k, this one is simple B + L(C*i + j) <=> B + 4(j), find the first row of the column j +// +// leaq 1024(%rcx), %rsi Bend = xb + 4k + 1024, find the N row of column k, +// B + 4(16*16 + k) <=> B + 1024 + 4k diff --git a/3/8_array_allocation_and_access/40_diagonal_elements.c b/3/8_array_allocation_and_access/40_diagonal_elements.c new file mode 100644 index 0000000..ab541db --- /dev/null +++ b/3/8_array_allocation_and_access/40_diagonal_elements.c @@ -0,0 +1,48 @@ +// A in rdi, val in rsi +// fix_set_diag: +// movl $0, %eax +// .L13 +// movl %esi, (%rdi, %rax) +// addq $68, %rax +// cmpq $1088, %rax +// jne .L13 +// rep; ret +#include <stdio.h> +#define N 16 +typedef int fix_matrix[N][N]; + +void fix_set_diag(fix_matrix A, int val) { + long i; + for (i = 0; i < N; i++) { + A[i][i] = val; + } +} + +void fix_set_diag_opt(fix_matrix A, int val) { + int *Aptr = &A[0][0]; + int *Aend = &A[N][N]; + do { + *Aptr = val; + Aptr += N; // Next row + Aptr ++; // Next column + } while (Aptr != Aend); +} + +int main(void) { + int i, j; + fix_matrix A; + for (i=0; i < N; i++) { + for (j=0; j < N; j++) { + A[i][j] = 0; + } + } + + i, j = 0, 0; + fix_set_diag_opt(A, 1); + for (i=0; i < N; i++) { + for (j=0; j < N; j++) { + printf("%ld", A[i][j]); + } + printf("\n"); + } +} diff --git a/3/9_data_structures/41_struct_test.c b/3/9_data_structures/41_struct_test.c new file mode 100644 index 0000000..1816b31 --- /dev/null +++ b/3/9_data_structures/41_struct_test.c @@ -0,0 +1,30 @@ +struct test { + short *p; + struct { + short x; + short y; + } s; + struct test *next; +} + +// A. +// p: 0, it's at the beginning of the struct +// s.x: (length p) <- 8 +// s.y: (length p) + (length s.x) <- 10 +// next: (length p) + (length s.x) + (length s.y) <- 12 +// B. +// total bytes should be 20. pointer + short + short + pointer +// C. +// st in %rdi +// st_init: +// movl 8(%rdi), %eax +// movl %eax, 10(%rdi) +// leaq 10(%rdi), %rax +// movq %rax, (%rdi) +// movq %rdi, 12(%rdi) +// ret +void st_init(struct test *st) { + st->s.y = st->s.x; + st->p = &(st->s.y); + st->next = st; +} diff --git a/3/9_data_structures/42_ace_structure.c b/3/9_data_structures/42_ace_structure.c new file mode 100644 index 0000000..8b4e92d --- /dev/null +++ b/3/9_data_structures/42_ace_structure.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +struct ACE { + short v; + struct ACE *p; +}; + +// B. it's a linked list of short values that are multiplied. +short test(struct ACE *ptr) { + short v = 1; + while (ptr) { + v *= ptr->v; + ptr = ptr->p; + } + return v; +} + +int main(void) { + struct ACE a = {2, NULL}; + struct ACE b = {3, NULL}; + a.p = &b; + printf("%d\n", test(&a)); +} diff --git a/3/9_data_structures/43_dest.c b/3/9_data_structures/43_dest.c new file mode 100644 index 0000000..67bb630 --- /dev/null +++ b/3/9_data_structures/43_dest.c @@ -0,0 +1,43 @@ +#define type long; + +typedef union { + struct { + long u; + short v; + char w; + } t1; + struct { + int a[2]; + char *p; + } t2; +} u_type; + +// Kinda confused when I'm moving a memory address +// Forgot it was a union +// Also forgot I had to move to dest +// +// up and dest in rdi and rsi +// +// expr type code +// +// up->t1.u long movq (%rdi), %rax +// movq %rax, (%rsi) +// +// up->t1.v short movw 8(%rdi), %ax +// movw %ax, (%rsi) +// +// &up->t1.w char* addq 10, %rdi +// movq %rdi, (%rsi) +// +// up->t2.a int * movq %rdi, (%rsi) +// +// up->t2.a[up->t1.u] int movq (%rdi), %rax // What's interesting: rdi is the t2.a int* and the t1.u long, and they are being used in the same expression! +// movl (%rdi, %rax, 4), %eax +// movl %eax, (%rsi) +// +// *up->t2.p char movq 8(%rdi), %rax +// movb (%rax), %al // Remember, you cannot have Memory -- Memory moves! +// movb %al, (%rsi) +void get(u_type *up, type *dest) { + *dest = ___; +} diff --git a/3/9_data_structures/44_gaps.c b/3/9_data_structures/44_gaps.c new file mode 100644 index 0000000..1162895 --- /dev/null +++ b/3/9_data_structures/44_gaps.c @@ -0,0 +1,86 @@ +// A. +struct P1 { + int i; + char c; + int j; + char d; +}; +// Largest primitive is 4, so the local alignment value must be 4 +// |int 4| char 1|gap 3 |int 4 |char 1|gap 3| +// |-----|--------------|------|------------| +// 4 4 4 4 +// i 0 +// c 4 +// j 8 +// d 12 +// +// total 16 +// +// B. +struct P2 { + int i; + char c; + char d; + long j; +}; +// Largest primitive is 8, so the local alignment value must be 8 +// |int 4|char 1| char 1|gap 2|long 8| +// |--------------------------|------| +// 8 8 +// i 0 +// c 4 +// d 5 +// j 8 +// +// total 16 +// +// C. +struct P3 { + short w[3]; + char c[3]; +}; +// Largest primitive is 2, so the local alignment value must be 2 +// |short 2|short 2|short 2|char 1|char 1|char 1|gap 1| +// |-------|-------|-------|-------------|------------| +// 2 2 2 2 2 +// +// w[0] 0 +// w[1] 2 +// w[2] 4 +// c[0] 6 +// c[1] 7 +// c[2] 8 +// +// total 10 +// +// D. +struct P4 { + short w[5]; + char *c[3]; +}; +// Largest primitive is 8, so the local alignment value must be 8 +// |short 2|short 2|short 2|short 2|short 2|gap 6|char* 8|char* 8|char* 8| +// |-------------------------------|-------------|-------|-------|-------| +// 8 8 8 8 8 +// +// w[0] 0 +// w[1] 2 +// w[2] 4 +// w[3] 6 +// w[4] 8 +// c[0] 16 +// c[1] 24 +// c[2] 32 +// +// total 40 +// E. +struct P5 { + struct P3 a[2]; + struct P2 t; +}; +// Largest primitive is 8, so the local alignment value must be 8 +// |P3 10|P3 10|gap 4|P2 16| +// +// a[0] 0 +// a[1] 10 +// t 24 diff --git a/3/9_data_structures/45_rec.c b/3/9_data_structures/45_rec.c new file mode 100644 index 0000000..f04ac0e --- /dev/null +++ b/3/9_data_structures/45_rec.c @@ -0,0 +1,42 @@ +struct { + char *a; + short b; + double c; + char d; + float e; + char f; + long g; + int h; +} rec; +// A. +// |char* 8|short 2|gap 6|double 8|char 1|float 4|char 1|gap 2|long 8|int 4|gap 4| +// |-------|-------------|--------|---------------------------|------|-----------| +// 8 8 8 8 8 8 +// +// a 0 +// b 8 +// c 16 +// d 24 +// e 25 +// f 29 +// g 32 +// h 40 +// +// B. +// 48 +// +// C. +// |char* 8|short 2|char 1|float 4|char 1|double 8|long 8|int 4|gap 4| +// |-------|-----------------------------|--------|------|-----------| +// 8 8 8 8 8 +// +// a 0 +// b 8 +// c 16 +// d 10 +// e 11 +// f 15 +// g 24 +// h 32 +// +// total 40 |
