summaryrefslogtreecommitdiff
path: root/CSAPP/chap2
diff options
context:
space:
mode:
Diffstat (limited to 'CSAPP/chap2')
-rw-r--r--CSAPP/chap2/2_12.c12
-rw-r--r--CSAPP/chap2/2_26.c9
-rw-r--r--CSAPP/chap2/bittruncate.c9
-rw-r--r--CSAPP/chap2/casting.c36
-rw-r--r--CSAPP/chap2/char_endian.c6
-rw-r--r--CSAPP/chap2/datatype.c15
-rw-r--r--CSAPP/chap2/detect_overflow.c54
-rw-r--r--CSAPP/chap2/encoding.c25
-rw-r--r--CSAPP/chap2/endianess.c17
-rw-r--r--CSAPP/chap2/hello.c7
-rw-r--r--CSAPP/chap2/not.c14
-rw-r--r--CSAPP/chap2/shift_big.c40
-rw-r--r--CSAPP/chap2/shifts.c39
-rw-r--r--CSAPP/chap2/show_types.c11
-rw-r--r--CSAPP/chap2/string.c11
15 files changed, 305 insertions, 0 deletions
diff --git a/CSAPP/chap2/2_12.c b/CSAPP/chap2/2_12.c
new file mode 100644
index 0000000..b7f53ac
--- /dev/null
+++ b/CSAPP/chap2/2_12.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int main (void) {
+ int a = 0x87654321;
+
+ printf("Ans A: 0x%.8x\n", (a & 0xff));
+ printf("Ans B: 0x%.8x\n", ((~a) & ((~0) & ~0xff)) | (a & 0xff));
+ printf("Ans B2: 0x%.8x\n", ((~0xff) & (~a)) |(a & 0xff));
+ printf("Ans C: 0x%.8x\n", (a | 0xff));
+
+ return 0;
+}
diff --git a/CSAPP/chap2/2_26.c b/CSAPP/chap2/2_26.c
new file mode 100644
index 0000000..15b605a
--- /dev/null
+++ b/CSAPP/chap2/2_26.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main(void){
+ unsigned a, b;
+ a = 3;
+ b = 5;
+ printf("%d\n", !!(((int)a - (int)b) > 0));
+ return 0;
+}
diff --git a/CSAPP/chap2/bittruncate.c b/CSAPP/chap2/bittruncate.c
new file mode 100644
index 0000000..757a127
--- /dev/null
+++ b/CSAPP/chap2/bittruncate.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main(void) {
+
+ int short a = 0xAA3A;
+ printf("0x%X - 0x%X \n", a, (char)a);
+ return 0;
+}
+
diff --git a/CSAPP/chap2/casting.c b/CSAPP/chap2/casting.c
new file mode 100644
index 0000000..5089802
--- /dev/null
+++ b/CSAPP/chap2/casting.c
@@ -0,0 +1,36 @@
+/*
+ * Shows how the conversion between signed and unsigned are made.
+ * Most machines follow the rule that the underlying bit pattern doesn't change.
+ * Let's see
+ */
+
+#include <stdio.h>
+
+/* 10101010
+ * integers are usually considered signed by default unless we append
+ * the suffix U to the number*/
+#define NUM 0xAA
+int x = -1;
+unsigned u = 2147483648;
+
+int main(void) {
+
+ unsigned char a = NUM;
+ printf("Original unsigned number - HEX: 0x%.2X %d\n", a, a);
+ /* there is no formatter to print a single byte integer, printing it
+ * with %d would result in a cast to integer, printing 4 bytes, so let's
+ * print it only in HEX
+ */
+
+ printf("Signed conversion number - HEX: 0x%.2X DEC: %d\n", (char)a, (signed char)a);
+
+ printf("x = %d - x = %u - 0x%X\n", x, x, x);
+ printf("u = %d - u = %u - 0x%X\n", u, u, u);
+
+ /*
+ * When one of the operands in an equation is unsigned, C will cast the
+ * another operand to unsigned too before making the operation
+ */
+ printf("%X\n", -2147483647);
+ return 0;
+}
diff --git a/CSAPP/chap2/char_endian.c b/CSAPP/chap2/char_endian.c
new file mode 100644
index 0000000..0929a88
--- /dev/null
+++ b/CSAPP/chap2/char_endian.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void) {
+ char *b = "TOMANOCU";
+ return 0;
+}
diff --git a/CSAPP/chap2/datatype.c b/CSAPP/chap2/datatype.c
new file mode 100644
index 0000000..3e43ef1
--- /dev/null
+++ b/CSAPP/chap2/datatype.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+int main(void)
+{
+ int16_t a = 255;
+ int8_t b = 120;
+ uint32_t c = UINT32_MAX;
+
+ printf("A: %" PRId16 "\n", a);
+ printf("B: %" PRId8 "\n", b);
+ printf("C: %" PRIu32 "\n", c);
+ return 0;
+}
diff --git a/CSAPP/chap2/detect_overflow.c b/CSAPP/chap2/detect_overflow.c
new file mode 100644
index 0000000..6badd11
--- /dev/null
+++ b/CSAPP/chap2/detect_overflow.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/*
+ * Determine whether arguments can be added without overflow
+ * Two's complement
+ *
+ * Returns 1 if arguments can be added without overflow
+ * 0 otherwise
+ */
+int tadd_ok(int x, int y)
+{
+// if ((x > 0 && y > 0) && (x + y) < 0 ||
+// (x < 0 && y < 0) && (x + y) > 0)
+// return 0;
+// else if ((x < 0 && y < 0) && (x + y) > 0)
+// return 0;
+// else
+// return 1;
+
+ /* Negative overflow can also be 0 */
+ return !(((x > 0 && y > 0) && (x + y) < 0) ||
+ ((x < 0 && y < 0) && (x + y) >= 0));
+}
+
+int uadd_ok(unsigned x, unsigned y)
+{
+ return ((x + y) >= x);
+ //return ((x + y) < x) ? 0 : 1;
+}
+
+
+
+int main(void)
+{
+ unsigned a = 5;
+ unsigned b = 0;
+ int X = INT_MIN;
+ int Y = INT_MIN;
+ int ret;
+
+ ret = uadd_ok(a, b);
+ printf("SUM: %u\n", a + b);
+ printf("Return is: %d\n", ret);
+
+ ret = tadd_ok(X, Y);
+ printf("Signed values\n");
+ printf("SUM: %d\n", X + Y);
+ printf("Return is: %d\n", ret);
+ return 0;
+}
+
diff --git a/CSAPP/chap2/encoding.c b/CSAPP/chap2/encoding.c
new file mode 100644
index 0000000..7a3b0c9
--- /dev/null
+++ b/CSAPP/chap2/encoding.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+int main(void)
+{
+ int a = 2809;
+ float b = 2809;
+ unsigned char *p;
+ int i = 0;
+
+ /* print int and float values as an hexadecimal unsigned integer */
+ p = (unsigned char *)&a;
+ printf(" Int: 0x");
+ for (i = 0; i < sizeof(int); i++) {
+ printf("%.2x", p[i]);
+ printf("\n");
+ }
+
+ p = (unsigned char *)&b;
+ printf(" Float: 0x");
+ for (i = 0; i < sizeof(int); i++) {
+ printf("%.2x", p[i]);
+ printf("\n");
+ }
+ return 0;
+}
diff --git a/CSAPP/chap2/endianess.c b/CSAPP/chap2/endianess.c
new file mode 100644
index 0000000..c2c08aa
--- /dev/null
+++ b/CSAPP/chap2/endianess.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main(void)
+{
+ unsigned int a = 0xdc3f109a;
+ /* Preferred data type for expressing size of data structures */
+ size_t i;
+ unsigned char *p;
+
+ printf("Current value of variable: %x\n\n", a);
+ for (i = 0, p = (char *)&a; i < sizeof(int); i++) {
+ printf("Address: %p - Value %x\n", p, (unsigned char)*p);
+ p++;
+ }
+
+ return 0;
+}
diff --git a/CSAPP/chap2/hello.c b/CSAPP/chap2/hello.c
new file mode 100644
index 0000000..2581101
--- /dev/null
+++ b/CSAPP/chap2/hello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+ printf("Hello world\n");
+ return 0;
+}
diff --git a/CSAPP/chap2/not.c b/CSAPP/chap2/not.c
new file mode 100644
index 0000000..bb17b7a
--- /dev/null
+++ b/CSAPP/chap2/not.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main(void)
+{
+ struct foo {
+ unsigned int a : 1;
+ };
+
+ struct foo bar;
+ bar.a = 1;
+ printf("%x\n", bar.a);
+ printf("%x\n", ~bar.a);
+ return 0;
+}
diff --git a/CSAPP/chap2/shift_big.c b/CSAPP/chap2/shift_big.c
new file mode 100644
index 0000000..8a54c56
--- /dev/null
+++ b/CSAPP/chap2/shift_big.c
@@ -0,0 +1,40 @@
+/*
+ * What happens when the shift value is bigger than the amount of bits in the
+ * variable?
+ *
+ * Some machines will only use the lower log2 w bits of the shift amount when
+ * shifting a 2-bit falue.
+ *
+ * For example, shifting a 8-bit value by 10, would make the machine shift the
+ * value for only 2 (a k mod w).
+ *
+ * This is not a rule though. Let's test it.
+ *
+ * Looks like linux GCC on 64bit will always shift the exactly number, and crop
+ * only the exactly number of bits for the data type representation.
+ *
+ * For signed integers, if the shift is done right in the printf, gcc will use a
+ * convert it to a signed 32-bits for the conversion.
+ *
+ * Try change the x in printf on line 32, to use "a << 10" directly.
+ */
+#include <stdio.h>
+
+int main(void)
+{
+ /* 10101001 */
+ char x, a = 0xA9;
+ unsigned char y, b = 0xA9;
+
+
+ printf("Signed Original value: 0x%.2x\n", a);
+ x = a << 10;
+ printf("Signed left shift by 10: 0x%.2x\n\n", x);
+
+
+ printf("Unsigned Original value: 0x%.2x\n", b);
+ y = b << 10;
+ printf("Unsigned left shift by 10: 0x%.2x\n", y);
+
+ return 0;
+}
diff --git a/CSAPP/chap2/shifts.c b/CSAPP/chap2/shifts.c
new file mode 100644
index 0000000..836476d
--- /dev/null
+++ b/CSAPP/chap2/shifts.c
@@ -0,0 +1,39 @@
+/*
+ * Shift operations
+ *
+ * Right shifts might use either arithmetic shifts or logical shifts.
+ *
+ * This small piece of code should identify which one is used
+ */
+
+#include <stdio.h>
+
+int main(void)
+{
+ /* Using char so we care for a single byte only */
+ char x, a;
+ unsigned char y, b;
+ /* bin 10101001 */
+ a = b = 0xA9;
+
+ printf("Original signed variable: 0x%.2x\n", a);
+
+ /*
+ * Signed data variables are right shifted using Arithmetic shift. i.e.
+ * left bits are filled with a copy of the most significant bit of the
+ * original value
+ */
+ x = a >> 3;
+ printf("Signed right shift by 3: 0x%.2x\n\n", x);
+
+ printf("Original unsigned variable: 0x%.2x\n", b);
+ /*
+ * Unsigned data variables are right shifted logically. i.e. left bits
+ * are just filled with zeros
+ */
+ y = b >> 3;
+ printf("Unsigned right shift by 3: 0x%.2x\n", y);
+ return 0;
+}
+
+
diff --git a/CSAPP/chap2/show_types.c b/CSAPP/chap2/show_types.c
new file mode 100644
index 0000000..3f78b41
--- /dev/null
+++ b/CSAPP/chap2/show_types.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main(void) {
+ printf("Size of Char: %d\n", sizeof(char));
+ printf("Size of Short: %d\n", sizeof(short));
+ printf("Size of Int: %d\n", sizeof(int));
+ printf("Size of Long: %d\n", sizeof(long));
+ printf("Size of Float: %d\n", sizeof(float));
+ printf("Size of Double: %d\n", sizeof(double));
+ return 0;
+}
diff --git a/CSAPP/chap2/string.c b/CSAPP/chap2/string.c
new file mode 100644
index 0000000..9e783d4
--- /dev/null
+++ b/CSAPP/chap2/string.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main(void)
+{
+ char *a = "12345";
+ int i;
+
+ for (i=0; i < 6; i++)
+ printf("%.2x ", (unsigned int) a[i]);
+ return 0;
+}