Computer Systems Fundamentals

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

//
// use a union to alias uint16_t, uint32_t,uint64_t types
// to an array of bytes so we can see order (endian-ness)
// bytes of integer type stored in memory
//
// what this program prints vary between platforms:
// https://en.wikipedia.org/wiki/Endianness
// CSE machines are little-endian
//

union overlay {
    uint16_t s;
    uint32_t i;
    uint64_t l;
    uint8_t  bytes[8];
};

void print_bytes(char *message, void *v, int n);

int main(void) {
    union overlay u = {.l = 0};

    u.s = 0x1234;
    print_bytes("uint16_t s = 0x1234            ", u.bytes, 2); // @cse prints 34 12
    u.i = 0x12345678;
    print_bytes("uint32_t i = 0x12345678        ", u.bytes, 4); // @cse prints 78 56 34 12
    u.l = 0x123456789abcdef0;
    print_bytes("uint64_t l = 0x123456789abcdef0", u.bytes, 8); // @cse prints f0 de bc 9a 78 56 34 12

    if (u.bytes[0] == 0xf0) {
        printf("little-endian machine\n");
    } else if (u.bytes[0] == 0x01) {
        printf("big-endian machine\n");
    } else {
        printf("unusual machine\n");
    }
}


void print_bytes(char *message, void *v, int n) {
    uint8_t *p = v;
    printf("%s, bytes[0..%d] = ", message, n - 1);
    for (int i = 0; i < n; i++) {
        printf("%02x ", p[i]);
    }
    printf("\n");
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>


int main(void) {
    double array[10];

    for (int i = 0; i < 10; i++) {
        printf("&array[%d]=%p\n", i, &array[i]);
    }

    printf("\nexample computation for address of array element \\n\n");

    uint64_t a = (uint64_t)&array[0];
    printf("&array[0] + 7 * sizeof (double) = 0x%lx\n",     a + 7 * sizeof (double));
    printf("&array[0] + 7 * %lx               = 0x%lx\n", sizeof (double), a + 7 * sizeof (double));
    printf("0x%lx + 7 * %lx          = 0x%lx\n", a, sizeof (double), a + 7 * sizeof (double));
    printf("&array[7]                       = %p\n", &array[7]);
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

void print_bytes(void *v, int n);

struct s1 {
    uint8_t    c1;
    uint64_t   l1;
    uint8_t    c2;
    uint64_t   l2;
    uint8_t    c3;
    uint64_t   l3;
    uint8_t    c4;
    uint64_t   l4;
};

struct s2 {
    uint64_t   l1;
    uint64_t   l2;
    uint64_t   l3;
    uint64_t   l4;
    uint8_t    c1;
    uint8_t    c2;
    uint8_t    c3;
    uint8_t    c4;
};

int main(void) {
    struct s1 v1;
    struct s2 v2;

    printf("sizeof v1 = %lu\n", sizeof v1);
    printf("sizeof v2 = %lu\n", sizeof v2);

    printf("alignment rules mean struct s1 is padded\n");

    printf("&(v1.c1) = %p\n", &(v1.c1));
    printf("&(v1.l1) = %p\n", &(v1.l1));
    printf("&(v1.c2) = %p\n", &(v1.c2));
    printf("&(v1.l2) = %p\n", &(v1.l2));

    printf("struct s2 is not padded\n");

    printf("&(v2.c1) = %p\n", &(v2.l1));
    printf("&(v2.l1) = %p\n", &(v2.l2));
}