CS 208 s21 — Learning Block #2

Table of Contents

1 Bits and Bytes Practice

  • if our word size is 4 bits, how big is our address space? (how many different bytes can we refer to with the set of possible addresses) 1
  • if the word size of a machine is 64-bits, which of the following is usually true? (pick all that apply) 2
    • 64 bits is the size of a memory address
    • 64 bits is the size of an integer
  • true or false: by looking at the bits stored in memory, I can tell if a particular 4 bytes is being used to represent an integer, floating point number, or string 3
  • for an int stored at address x100, which bytes would it consist of (i.e., which range of memory addresses)? 4
  • We store the value 0x1020304 as a word at address 0x100 in a big-endian, 64-bit machine. What is the byte of data stored at address 0x104?5
    • Note: I have left off any leading zeros for this value

2 Why C?

2.1 Why learn C?

  • It helps you think like an actual computer (abstraction close to machine level) without dealing with raw machine code
  • You'll understand just how much Your Favorite Language provides
  • C is still widely used
  • C's pitfalls still fuel devastating reliability and security failures today (modern relevance, after a sense)

2.2 Why not use C?

  • Probably not the right language for your next personal project
  • It "gets out of the programmer's way" even when the programmer is unwittingly running toward a cliff
  • Advances in programming language design have produced languages that fix C's problems while keeping its strengths
    • Rust is a good example

3 Pointers

3.1 First look

Take a look at this spreadsheet-based Memory diagram. First I'll go over how to read the diagram:

  • I've taken a section of memory 40-bytes long (address 0x00 to 0x27) and laid it out as a grid
    • 10 rows of 4 bytes each
  • Each row goes from left to right, so to read all the bytes in consecutive order, you would follow a zig-zag pattern
    • left to right on the bottom row, then back to the left byte of the next row up, and so on
  • The address of the first byte in each row is shown along the left-most column
  • Along the top is shown a byte offset
  • To get the address of a particular byte/spreadsheet cell, take the row address to the left and add the byte offset for the column
    • So the 4 bytes in the bottom row are at addresses 0x00, 0x01 (0x00 + 0x01), 0x02 (0x00 + 0x02), and 0x03 (0x00 + 0x03)
    • The 4 bytes on the row above that are at 0x04 (0x04 + 0x00), 0x04 (0x04 + 0x01), 0x06 (0x04 + 0x02), and 0x07 (0x04 + 0x03)

Next, let's go through the values in the diagram and what they mean:

  • This is a 32-bit example, meaning that the memory addresses are 32-bit (4 bytes) wide
  • I'm using little-endian byte ordering
  • The number 496 is stored at address 0x20 (240 = 0x1f0 = 0xf0 01 00 f0 using little endian)
  • A pointer stored at address 0x08 and points to the contents at address 0x20
  • A pointer to a pointer is stored at address 0x00
  • The number 12 is stored at address 0x10. Is it a pointer? How do we know values are pointers or not?
    • Remember: everything is bits, what the value at 0x10 means depends on interpretation/context

3.2 C example

c-assignment.png

In C, think of assignment statements as having the above structure: a memory location on the left and a value to write to that location on the right.

int* p; // p: 0x04
int x = 5; // x: 0x14, store 5 at 0x14
int y = 2; // y: 0x24, store 2 at 0x24
p = &x; // store 0x14 at 0x04
// load the contents at 0x04 (0x14)
// load the contents at 0x14 (0x5)
// add 1 and store sum at 0x24
y = 1 + *p;
// load the contents at 0x04 (0x14)
// store 0xF0 (240) at 0x14
*p = 240;

Here's a memory diagram to go along with the example code above. Again, I am using a 32-bit word size. Trace through the C code and make sure you understand how this code makes the changes between the top and bottom diagrams.

3.3 C mystery 6

What will be printed?

int a = 10;
int b = 20;
int *pa = &a;
a += 5;
int *pb = &b;
*pa = *pb - *pa;
*pb += a;
printf("a = %d b = %d\n", a, b);

3.4 Practice

4 Homework

  • Check your understanding of hex and binary with the review quiz on Moodle
  • C Tutor is an excellent resource for getting a feel for C pointers. You can type in some C code and then click Visualize Execution to get a line-by-line visualization of memory as your code executes. Try and think of some tricky situations and then visualize them. Use the Generate permanent link button to get a URL for one of your examples and post it to this forum along with a brief explanation.

Footnotes:

1

With 4-bit addresses, our address space is 16 bytes. This is because 4 bits provide \(2^4 = 16\) unique values.

2

only 64 bits is the size of a memory address is true, the word size does not directly determine the size of an integer

3

FALSE, bits alone do not determine what is stored there. The system or a program can interpret them in various ways.

4

an int takes 4 bytes and the address of a piece of data is always the lowest address, so an int at 0x100 would consist of the four bytes 0x100, 0x101, 0x102, and 0x103.

5

Since we are on a 64-bit machine, 0x1020304 is actually 0x0000000001020304 when you write out all 64 bits. Big endian means that the four most significant bytes, all 0x00, will be stored in 0x100 to 0x103, followed by 0x01 02 03 04 in 0x104 to 0x107. Thus, the byte in 0x104 will be 0x01.

6

It will print a = 5 b = 25. Visualize the code using C Tutor if you want to see how this happens.