diff options
Diffstat (limited to 'CSAPP/chap2')
| -rw-r--r-- | CSAPP/chap2/2_12.c | 12 | ||||
| -rw-r--r-- | CSAPP/chap2/2_26.c | 9 | ||||
| -rw-r--r-- | CSAPP/chap2/bittruncate.c | 9 | ||||
| -rw-r--r-- | CSAPP/chap2/casting.c | 36 | ||||
| -rw-r--r-- | CSAPP/chap2/char_endian.c | 6 | ||||
| -rw-r--r-- | CSAPP/chap2/datatype.c | 15 | ||||
| -rw-r--r-- | CSAPP/chap2/detect_overflow.c | 54 | ||||
| -rw-r--r-- | CSAPP/chap2/encoding.c | 25 | ||||
| -rw-r--r-- | CSAPP/chap2/endianess.c | 17 | ||||
| -rw-r--r-- | CSAPP/chap2/hello.c | 7 | ||||
| -rw-r--r-- | CSAPP/chap2/not.c | 14 | ||||
| -rw-r--r-- | CSAPP/chap2/shift_big.c | 40 | ||||
| -rw-r--r-- | CSAPP/chap2/shifts.c | 39 | ||||
| -rw-r--r-- | CSAPP/chap2/show_types.c | 11 | ||||
| -rw-r--r-- | CSAPP/chap2/string.c | 11 |
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; +} |
