/* memblock.c Written by Tanya Amert for Fall 2024 This program generates a specific block of 32 bytes in memory. These correspond to a table that, on paper, looks like this: 0x60 3F 24 07 00 12 00 00 00 0x68 75 00 00 00 00 00 00 00 <-- different in this program 0x70 59 41 31 00 00 43 61 54 0x78 20 3B 29 00 00 00 00 00 Compile as usual: gcc -Wall -Werror -g -o memblock memblock.c Run with no command-line arguments: ./memblock */ #include #include int main(int argc, char *argv[]) { // We'll build a 4x8 table (four rows, each depicting eight bytes) int num_bytes = 32; char *mem = (char *)malloc(sizeof(char) * num_bytes); // Row 1 (0x60) *((int *)mem) = 0x7243F; *((short *)mem + 2) = 0x12; *((short *)mem + 3) = 0xCA; // Row 2 (0x68) *((char**)mem + 1) = mem+0x15; // 0x75 // Row 3 (0x70) *((int *)mem + 4) = 0x314159; mem[20] = 0x00; mem[21] = 0x43; mem[22] = 0x61; mem[23] = 0x54; // Row 4 (0x78) mem[24] = 0x20; mem[25] = 0x3B; mem[26] = 0x29; mem[27] = 0x00; mem[28] = 0x00; mem[29] = 0x00; mem[30] = 0x00; mem[31] = 0x00; // Print out the memory for (int i = 0; i < num_bytes; i++) { if (i % 8 == 0) { printf("%p ", mem + i); } printf("%.2x ", mem[i] & 0xFF); if ((i+1) % 8 == 0) printf("\n"); } printf("\n"); // Now onto the questions! int *num_addr = (int *)mem; // we can't actually hard-code the address, but we know it relative to mem printf("a) 0x%x\n", *num_addr); // a short two_byte_num = (short) *num_addr; printf("b) 0x%x\n", two_byte_num & 0xFFFF); // b char c = mem[1]; printf("c) %c %d\n", c, c); // c char **str_addr = (char **)(mem + 0x8); printf("d) %p\n", str_addr); // d char *str = *str_addr; printf("e) '%s' at %p\n", str, str); // e printf("f) %p\n", str + 4); // f printf("g) %p\n", num_addr + 3); // g printf("h) %p\n", str_addr + 1); // h char *ch_addr = &(str[2]); printf("i) %c %p\n", *ch_addr, ch_addr); // i // Don't forget to free the memory! free(mem); return 0; }