summaryrefslogtreecommitdiff
path: root/3
diff options
context:
space:
mode:
Diffstat (limited to '3')
-rw-r--r--3/6_control/27_while_for.c46
-rw-r--r--3/6_control/28_fun_b.c33
-rw-r--r--3/6_control/29_continue.c5
-rw-r--r--3/6_control/30_switch2.c37
-rw-r--r--3/6_control/31_the_switcher.c29
-rw-r--r--3/7_procedures/32_functions.c14
-rw-r--r--3/7_procedures/33_procprob.c21
-rw-r--r--3/7_procedures/34_long_p.c34
8 files changed, 219 insertions, 0 deletions
diff --git a/3/6_control/27_while_for.c b/3/6_control/27_while_for.c
new file mode 100644
index 0000000..f7f73f7
--- /dev/null
+++ b/3/6_control/27_while_for.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+long fact_for(long n) {
+ long i;
+ long result = 1;
+ for (i = 2; i <= n; i++) {
+ result *= i;
+ }
+ return result;
+}
+
+// guarded do
+//
+// init-s
+// t = test-e;
+// if (!t) goto done;
+//
+// loop:
+// body-s
+// update-e;
+// t = test-e;
+// if (t) goto loop;
+//
+// done:
+
+long fact_for_gd_goto(long n) {
+ long i = 2;
+ long result = 1;
+
+ int t = i<=n;
+ if (!t) {
+ goto done;
+ }
+loop:
+ result *= i;
+ i++;
+ t = i<=n;
+ if (t) goto loop;
+done:
+ return result;
+}
+
+int main() {
+ printf("for: %ld, goto: %ld\n", fact_for(5), fact_for_gd_goto(5));
+ return 0;
+}
diff --git a/3/6_control/28_fun_b.c b/3/6_control/28_fun_b.c
new file mode 100644
index 0000000..5ecf7d2
--- /dev/null
+++ b/3/6_control/28_fun_b.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+// x in rdi
+// fun_b:
+// movl $64, %edx i <- 64 (32 bits?, long presumably)
+// movl $0, %eax val <- 0
+// .L10:
+// movq %rdi, %rcx tmp <- x
+// andl $1, %ecx tmp <- tmp & 1
+// addq %rax, %rax val <- val + val
+// orq %rcx, %rax val <- val | tmp
+// shrq %rdi
+// subq $1, %rdx i <- i-1
+// jne .L10 if i != 0 then goto .L10
+// rep; ret
+long fun_b(unsigned long x) {
+ long val = 0;
+ long i;
+ for (i = 64; i!=0; i--) {
+ long tmp = x;
+ tmp &= 1; // check 1 bit
+ val += val; // multiply by two
+ val |= tmp; // add 1 bit if present
+ x >>= 1; // shift next bit into 1 bit
+ }
+ return val;
+}
+
+// Seems to compute the value shifted to the left (63 - nbit), (or in other words the mirror image)
+int main() {
+ printf("val: %ld, computed: %ld, bits: %lb\n", fun_b(10), (long) 10 << 59, 10);
+ return 0;
+}
diff --git a/3/6_control/29_continue.c b/3/6_control/29_continue.c
new file mode 100644
index 0000000..175f57b
--- /dev/null
+++ b/3/6_control/29_continue.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main() {
+ return 0;
+}
diff --git a/3/6_control/30_switch2.c b/3/6_control/30_switch2.c
new file mode 100644
index 0000000..0c8cc85
--- /dev/null
+++ b/3/6_control/30_switch2.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+// x in %rdi
+// switch2:
+// addq $1, %rdi
+// cmpq $8, %rdi
+// ja .L2 if (x + 1) > 8 then goto default
+// jmp *.L4(,%rdi,8) take the address at x*8 from .L4
+void switch2(long x, long *dest) {
+ long val = 0;
+ switch (x) {
+ case -1:
+ printf(".L9");
+ break;
+ case 0:
+ case 7:
+ printf(".L5");
+ break;
+ case 1:
+ printf(".L6");
+ break;
+ case 2:
+ case 4:
+ printf(".L7");
+ break;
+ case 5:
+ printf(".L8");
+ break;
+
+ }
+ *dest = val;
+}
+
+int main(void) {
+ printf("val: %ld\n");
+ return 0;
+}
diff --git a/3/6_control/31_the_switcher.c b/3/6_control/31_the_switcher.c
new file mode 100644
index 0000000..c8b0a4a
--- /dev/null
+++ b/3/6_control/31_the_switcher.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+// a in %rdi, b in %rsi, c in %rdx, dest in %rcx
+void switcher(long a, long b, long c, long *dest) {
+ long val;
+ switch (a) {
+ case 5: /* Case A .L7 */
+ c = 15 ^ a;
+ /* Fall through */
+ case 0: /* Case B .L3 */
+ val = 112 + c;
+ break;
+ case 2: /* Case C .L5 */
+ case 7: /* Case D .L5 */
+ val = (c + b)<<2;
+ break;
+ case 4: /* Case E */
+ val = a;
+ break;
+ default: /* .L2 */
+ val = b;
+ }
+ *dest = val; /* .L6 */
+}
+
+int main(void) {
+ printf("val: %ld\n");
+ return 0;
+}
diff --git a/3/7_procedures/32_functions.c b/3/7_procedures/32_functions.c
new file mode 100644
index 0000000..ebf4405
--- /dev/null
+++ b/3/7_procedures/32_functions.c
@@ -0,0 +1,14 @@
+// Label PC Instruction %rdi %rsi %rax %rsp *%rsp Description
+// M1 400560 callq 10 7fffffffe820 Call first(10)
+//
+// F1 400548 lea 10 7fffffffe818 400565 v <- x + 1
+// F2 40054c sub 10 11 7fffffffe818 400565 u <- x - 1
+// F3 400550 callq 9 11 7fffffffe818 400565 Call last(9, 11)
+//
+// L1 400540 mov 9 11 7fffffffe810 400555 rax <- u
+// L2 400543 imul 9 11 9 7fffffffe810 400555 rax <- rax * v
+// L3 400547 retq 9 11 99 7fffffffe810 400555 return
+//
+// F4 400555 retq 9 11 99 7fffffffe818 400565 return
+//
+// M2 400565 mov 9 11 99 Resume
diff --git a/3/7_procedures/33_procprob.c b/3/7_procedures/33_procprob.c
new file mode 100644
index 0000000..4c68855
--- /dev/null
+++ b/3/7_procedures/33_procprob.c
@@ -0,0 +1,21 @@
+// procprob
+// movslq %edi, %rdi movslq==Move and sign extend 32bit to 64bit two's complement number,
+// Basically seems to convert the first signed argument to 64bit size.
+// A singed 32bit number is an int?
+// addq %rdi, (%rdx) *u <- (long) u + (long) a
+// addb %sil, (%rcx) *v <- (char) *v + (?) b
+// movl $6, %eax sizeof(a) + sizeof(b) = 6 = 4 + 2
+//
+// procprob
+// movslq %edi, %rdi movslq==Move and sign extend 32bit to 64bit two's complement number,
+// Basically seems to convert the first signed argument to 64bit size.
+// A singed 32bit number is an int?
+// addq %rdi, (%rdx) *u <- (long) u + (long) a
+// addb %sil, (%rcx) *v <- (char) *v + (?) b
+// movl $6, %eax sizeof(a) + sizeof(b) = 6 = 2 + 4
+//
+int procprob(int a, short b, long *u, char *v) {
+ *u += a;
+ *v += b;
+ return sizeof(b) + sizeof(b)
+}
diff --git a/3/7_procedures/34_long_p.c b/3/7_procedures/34_long_p.c
new file mode 100644
index 0000000..d058b77
--- /dev/null
+++ b/3/7_procedures/34_long_p.c
@@ -0,0 +1,34 @@
+// long P(long x)
+// x in %rdi
+// bx and bp, r12-15 are callee saved
+//
+// P:
+// pushq %r15
+// pushq %r14
+// pushq %r13
+// pushq %r12
+// pushq %rbp
+// pushq %rbx
+// subq $24, %rsp Allocate 24 extra bytes
+//
+// movq %rdi, %rbx move first arg into rbx
+// leaq 1(%rdi), %r15 move first arg into rbx
+// leaq 2(%rdi), %r14 move first arg into rbx
+// leaq 3(%rdi), %r13 move first arg into rbx
+// leaq 4(%rdi), %r12 move first arg into rbx
+// leaq 5(%rdi), %rbp move first arg into rbx
+// leaq 6(%rdi), %rax move first arg into rbx
+// movq %rax, (%rsp) save %rax in one of the three 8byte spots
+// leaq 7(%rdi), %rdx move first arg into rdx
+// movq %rdx, 8(%rsp) save %rdx in the second of the three 8byte spots
+// movl $0, %eax set ax to zero?
+// call Q
+// ...
+//
+// A. x, x + 1, x + 2, x + 3, x + 4, x + 5
+// B. x + 6, x + 7
+// C. There were more than 6?
+//
+long P(long x) {
+ return 0;
+}