diff options
Diffstat (limited to '3')
| -rw-r--r-- | 3/3_data_formats/main.c | 16 | ||||
| -rw-r--r-- | 3/3_data_formats/mstore/mstore.c | 6 | ||||
| -rw-r--r-- | 3/3_data_formats/mstore/mstore.s | 21 | ||||
| -rw-r--r-- | 3/4_register_and_addresses/main.c | 27 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/movq_size.s | 16 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/remdiv.c | 12 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/remdiv.s | 38 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/reverse_assemble.c | 23 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/sarl.c | 11 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/store_uprod.c | 11 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/store_uprod.s | 27 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/xorq_size.c | 5 | ||||
| -rw-r--r-- | 3/5_arith_and_logic/xorq_size.s | 16 | ||||
| -rw-r--r-- | 3/6_control/20_op_bias.c | 10 | ||||
| -rw-r--r-- | 3/6_control/21_test_cmov.c | 20 | ||||
| -rw-r--r-- | 3/6_control/22_loop.c | 51 | ||||
| -rw-r--r-- | 3/6_control/23_reverse_engineer_loop.c | 28 | ||||
| -rw-r--r-- | 3/6_control/24_while_loop.c | 24 | ||||
| -rw-r--r-- | 3/6_control/absdiff_goto.c | 39 | ||||
| -rw-r--r-- | 3/6_control/comp.c | 36 | ||||
| -rw-r--r-- | 3/6_control/cond.c | 6 | ||||
| -rw-r--r-- | 3/6_control/missing.c | 13 |
22 files changed, 456 insertions, 0 deletions
diff --git a/3/3_data_formats/main.c b/3/3_data_formats/main.c new file mode 100644 index 0000000..7fac153 --- /dev/null +++ b/3/3_data_formats/main.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +void multstore(long, long, long *); + +long mult2(long a, long b) { + long s = a * b; + return s; +} + +int main() { + long d; + multstore(2, 3, &d); + printf("2 * 3 --> %ld\n", d); + return 0; +} + diff --git a/3/3_data_formats/mstore/mstore.c b/3/3_data_formats/mstore/mstore.c new file mode 100644 index 0000000..cdcf205 --- /dev/null +++ b/3/3_data_formats/mstore/mstore.c @@ -0,0 +1,6 @@ +long mult2(long, long); + +void multstore(long x, long y, long *dest) { + long t = mult2(x, y); + *dest = t; +} diff --git a/3/3_data_formats/mstore/mstore.s b/3/3_data_formats/mstore/mstore.s new file mode 100644 index 0000000..e215a2b --- /dev/null +++ b/3/3_data_formats/mstore/mstore.s @@ -0,0 +1,21 @@ + .file "mstore.c" + .text + .globl multstore + .type multstore, @function +multstore: +.LFB0: + .cfi_startproc + pushq %rbx + .cfi_def_cfa_offset 16 + .cfi_offset 3, -16 + movq %rdx, %rbx + call mult2@PLT + movq %rax, (%rbx) + popq %rbx + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE0: + .size multstore, .-multstore + .ident "GCC: (GNU) 12.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/3/4_register_and_addresses/main.c b/3/4_register_and_addresses/main.c new file mode 100644 index 0000000..f767ee6 --- /dev/null +++ b/3/4_register_and_addresses/main.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +void decode1(long *xp, long *yp, long *zp) { + long x = *xp; + long y = *yp; + long z = *zp; + + *yp = x; + *zp = y; + *xp = z; +} + +long scale(long x, long y, long z) { + long t = x + 4 * y + 12 * z; + return t; +} + +long scale3(long x, long y, long z) { + long t = 10 * y + z + x * y; + return t; +} + +int main(void) { + char c = 0xC0; + int x = (int) c; + printf("%d", x); +} diff --git a/3/5_arith_and_logic/movq_size.s b/3/5_arith_and_logic/movq_size.s new file mode 100644 index 0000000..3d525df --- /dev/null +++ b/3/5_arith_and_logic/movq_size.s @@ -0,0 +1,16 @@ + .file "xorq_size.c" + .text + .section .text.startup,"ax",@progbits + .p2align 4 + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + movl $0, %eax + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 12.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/3/5_arith_and_logic/remdiv.c b/3/5_arith_and_logic/remdiv.c new file mode 100644 index 0000000..8d3c957 --- /dev/null +++ b/3/5_arith_and_logic/remdiv.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +void remdiv(long x, long y, long *qp, long *rp) { + long q = x/y; + long r = x%y; + *qp = q; + *rp = r; +} + +int main() { + remdiv(0,0,0,0); +} diff --git a/3/5_arith_and_logic/remdiv.s b/3/5_arith_and_logic/remdiv.s new file mode 100644 index 0000000..61c66df --- /dev/null +++ b/3/5_arith_and_logic/remdiv.s @@ -0,0 +1,38 @@ + .file "remdiv.c" + .text + .globl remdiv + .type remdiv, @function +remdiv: +.LFB23: + .cfi_startproc + movq %rdi, %rax + movq %rdx, %r8 + xorq %rdx, %rdx + divq %rsi + movq %rax, (%r8) + movq %rdx, (%rcx) + ret + .cfi_endproc +.LFE23: + .size remdiv, .-remdiv + .globl main + .type main, @function +main: +.LFB24: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + movl $0, %ecx + movl $0, %edx + movl $0, %esi + movl $0, %edi + call remdiv@PLT + movl $0, %eax + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE24: + .size main, .-main + .ident "GCC: (GNU) 12.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/3/5_arith_and_logic/reverse_assemble.c b/3/5_arith_and_logic/reverse_assemble.c new file mode 100644 index 0000000..6413f98 --- /dev/null +++ b/3/5_arith_and_logic/reverse_assemble.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +/* + * x in %rdi, y in %rsi, z in %rdx + * arith3: + * orq %rsi, %rdx + * sarq $9, %rdx + * notq %rdx + * movq %rdx, %bax <------- what is this register?? + * subq %rsi, %rbx + * ret + */ +short arith3(short x, short y, short z) { + short p1 = z | y; + short p2 = p1>>9; + short p3 = ~p2; + short p4 = p3; + return p4; +} + +int main() { + +} diff --git a/3/5_arith_and_logic/sarl.c b/3/5_arith_and_logic/sarl.c new file mode 100644 index 0000000..51e6305 --- /dev/null +++ b/3/5_arith_and_logic/sarl.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +long shift_left4_rightn(long x, long n) { + x <<= 4; + x >>= n; + return x; +} + +int main() { + printf("%d", shift_left4_rightn(15, 5)); +} diff --git a/3/5_arith_and_logic/store_uprod.c b/3/5_arith_and_logic/store_uprod.c new file mode 100644 index 0000000..0009e09 --- /dev/null +++ b/3/5_arith_and_logic/store_uprod.c @@ -0,0 +1,11 @@ +#include <inttypes.h> + +typedef unsigned __int128 uint128_t; + +void store_uprod(uint128_t *dest, uint64_t x, uint64_t y) { + *dest = x * (uint128_t) y; +} + +int main() { + return 0; +} diff --git a/3/5_arith_and_logic/store_uprod.s b/3/5_arith_and_logic/store_uprod.s new file mode 100644 index 0000000..a099e77 --- /dev/null +++ b/3/5_arith_and_logic/store_uprod.s @@ -0,0 +1,27 @@ + .file "store_uprod.c" + .text + .globl store_uprod + .type store_uprod, @function +store_uprod: +.LFB0: + .cfi_startproc + movq %rsi, %rax + mulq %rdx + movq %rax, (%rdi) + movq %rdx, 8(%rdi) + ret + .cfi_endproc +.LFE0: + .size store_uprod, .-store_uprod + .globl main + .type main, @function +main: +.LFB1: + .cfi_startproc + movl $0, %eax + ret + .cfi_endproc +.LFE1: + .size main, .-main + .ident "GCC: (GNU) 12.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/3/5_arith_and_logic/xorq_size.c b/3/5_arith_and_logic/xorq_size.c new file mode 100644 index 0000000..5751590 --- /dev/null +++ b/3/5_arith_and_logic/xorq_size.c @@ -0,0 +1,5 @@ +int main() { + int x = 5; + x ^= x; + return 0; +} diff --git a/3/5_arith_and_logic/xorq_size.s b/3/5_arith_and_logic/xorq_size.s new file mode 100644 index 0000000..ed88d9a --- /dev/null +++ b/3/5_arith_and_logic/xorq_size.s @@ -0,0 +1,16 @@ + .file "xorq_size.c" + .text + .section .text.startup,"ax",@progbits + .p2align 4 + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + xorl %eax, %eax + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 12.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/3/6_control/20_op_bias.c b/3/6_control/20_op_bias.c new file mode 100644 index 0000000..b071eb9 --- /dev/null +++ b/3/6_control/20_op_bias.c @@ -0,0 +1,10 @@ +#define OP < + +// x <- %rdi +// %rbx <- 15 + (x), bias to round towards zero +// ZF, SF <- %rdi & %rdi, check if pos or neg +// %rbx <- x if x >= 0, set to unbiased if pos +// %rbx <- %rbx >> 4, divide by 16 +short arith(short x) { + return x / 16; +} diff --git a/3/6_control/21_test_cmov.c b/3/6_control/21_test_cmov.c new file mode 100644 index 0000000..a90d178 --- /dev/null +++ b/3/6_control/21_test_cmov.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +// Remember that jumps flip conditionals +// Also testq rdi rdi and jge test if the sign bit is set +short test(short x, short y) { + short val = 12 + y; + if (x < 0) { + if (x >= y) + val = x | y; + else + val = x * y; + } else if (y >= 10) { + val = x / y; + } + return val; +} + +int main(void) { + return 0; +} diff --git a/3/6_control/22_loop.c b/3/6_control/22_loop.c new file mode 100644 index 0000000..73c7710 --- /dev/null +++ b/3/6_control/22_loop.c @@ -0,0 +1,51 @@ +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +// do +// body +// while (test); +// +// loop: +// body +// t = test; +// if (t) +// goto loop; + +typedef int64_t fact_t; + +long fact_do(long n) +{ + long result = 1; + do { + result *= n; + n = n-1; + } while (n > 1); + return result; +} + +int tmult_ok(fact_t x, fact_t y) +{ + fact_t p = x*y; + return !x || p/x == y; +} + +fact_t fact_do_int(size_t n) +{ + fact_t result = 1; + do { + if (tmult_ok(result, n)) { + result *= n; + n = n-1; + } else { + printf("would overflow this iter, n=%ld\n", n); + n = 0; + } + } while (n > 1); + return result; +} + +int main(void) { + size_t f = 20; + printf("result: %ld, max: %ld, less: %d", fact_do_int(f), INT64_MAX, fact_do_int(f) < INT64_MAX); + return 0; +} diff --git a/3/6_control/23_reverse_engineer_loop.c b/3/6_control/23_reverse_engineer_loop.c new file mode 100644 index 0000000..922b317 --- /dev/null +++ b/3/6_control/23_reverse_engineer_loop.c @@ -0,0 +1,28 @@ +short dw_loop(short x) +{ + short y = x/9; + short *p = &x; + short n = 4*x; + do { + x += y; + (*p) += 5; + n += 2; + } while (n > 0); + return x; +} + +// x in %rdi +// dw_loop: +// movq %rdi, %rdx # %rbx <- x +// movq %rdi, %rcx # %rcx <- x +// idivq $9, %rcx # %rcx (y) <- x / 9 +// leaq (,%rdi,4), %rdx # %rdx (n) <- x * 4 +// .L2: +// leaq 5(%rbx,%rcx), %rcx # %rbx (x) <- 5 + %rbx (x) + %rcx (y) +// subq $1, %rdx # %rdx (n) <- n - 1 +// testq %rdx, %rdx # n > 0 ? +// jg .L2 # if n > 0, goto .L2 +// rep; ret +// +// A. x in rbx, y in rcx, n in rdx +// B. The pointer is never used besides incrementing the value at the address. So it is replaced by a incrementing instruction in the loop. diff --git a/3/6_control/24_while_loop.c b/3/6_control/24_while_loop.c new file mode 100644 index 0000000..a3367fc --- /dev/null +++ b/3/6_control/24_while_loop.c @@ -0,0 +1,24 @@ +// while (test) +// body +// +// goto test; +// loop: +// body; +// test: +// t = test; +// if (t) +// goto loop; + +short loop_while(short a, short b) +{ + short result = ; + while () { + result = ; + a = ; + } + return result; +} + +int main(void) { + return 0; +} diff --git a/3/6_control/absdiff_goto.c b/3/6_control/absdiff_goto.c new file mode 100644 index 0000000..dfcb3be --- /dev/null +++ b/3/6_control/absdiff_goto.c @@ -0,0 +1,39 @@ +#include <stdio.h> + +// if (!t) +// goto false; +// then- +// goto done; +// false: +// else- +// goto done; +// done: +// ... +long gotodiff_se(long x, long y) +{ + long result; + if (x >= y) + goto x_ge_y; + lt_cnt++; + result = y - x; + return result; + +x_get_y: + ge_cnt++; + result = x - y; + return result; +} + +long gotodiff_se_alternate(long x, long y) +{ + long result; + if (x < y) + goto x_le_y; + ge_cnt++; + result = x - y; + return result; +x_le_y: + lt_cnt++; + result = y - x; + return result; +} diff --git a/3/6_control/comp.c b/3/6_control/comp.c new file mode 100644 index 0000000..beba875 --- /dev/null +++ b/3/6_control/comp.c @@ -0,0 +1,36 @@ +#include <stdio.h> + +typedef char data_t; + +#define COMP <= + +// a in rdx, b in rsi +// +// cmpl %esi, %edi (Compare long (double word, or 4 bytes). (a - b) ) +// setl %al (set lower? %rax return value) +// +// COMP is <, and data_t is 32 bits so maybe int or unsigned int or float +// +// cmpw %si, %di (Compare word (a-b), short) +// setge %al (Greater than or equal >=) +// +// cmpb %sil, %dil (Compare byte (a-b)) +// setbe %al (Comp <=) +// +// cmpq %rsi, %rdi (Compare 8 bytes quad words (long , double, char *)) +// setne %al +int comp(data_t a, data_t b) { + return a COMP b; +} + +#define TEST > + +int test(data_t a) { + return a TEST 0; +} + +int main() { + printf("%x hello world", comp(1, 2)); + return 0; +} + diff --git a/3/6_control/cond.c b/3/6_control/cond.c new file mode 100644 index 0000000..8b647bf --- /dev/null +++ b/3/6_control/cond.c @@ -0,0 +1,6 @@ +void cond(short a, short *p) +{ + if (a && *p < a) { + *p = a; + } +} diff --git a/3/6_control/missing.c b/3/6_control/missing.c new file mode 100644 index 0000000..1b8067b --- /dev/null +++ b/3/6_control/missing.c @@ -0,0 +1,13 @@ +short test(short x, short y, short z) { + short val = (z+y) - x; + if (z > 5) { + if (y > 2) { + val = x/z; + } else { + val = x/y; + } + } else if (z < 3) { + val = z/y; + } + return val; +} |
