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 addressx100
, which bytes would it consist of (i.e., which range of memory addresses)? 4 - We store the value
0x1020304
as a word at address0x100
in a big-endian, 64-bit machine. What is the byte of data stored at address0x104
?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
to0x27
) 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
), and0x03
(0x00
+0x03
) - The 4 bytes on the row above that are at
0x04
(0x04
+0x00
),0x04
(0x04
+0x01
),0x06
(0x04
+0x02
), and0x07
(0x04
+0x03
)
- So the 4 bytes in the bottom row are at addresses
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 address0x20
- 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
- Remember: everything is bits, what the value at
3.2 C example
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
- CSPP practice problem 2.5 (p. 48)
- Exercises 3 and 11 from the w3resource C Pointer practice problems
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:
With 4-bit addresses, our address space is 16 bytes. This is because 4 bits provide \(2^4 = 16\) unique values.
only 64 bits is the size of a memory address is true, the word size does not directly determine the size of an integer
FALSE, bits alone do not determine what is stored there. The system or a program can interpret them in various ways.
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
.
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
.
It will print a = 5 b = 25
. Visualize the code using C Tutor if you want to see how this happens.