CSSE 132 Mini-reading · Exam preparation
Exam 1 Review: Reason Through Numbers, Memory, and Code
Use this review to connect the current course topics and practice explaining your reasoning on paper. Work through one section at a time; follow its resource links when you need more practice.
Why This Matters
One bit pattern can be a number, part of an address, or an instruction. Knowing which interpretation applies lets you connect C expressions, memory pictures, and ARM64 code. Practice showing intermediate steps: an explanation helps you catch mistakes that a final answer alone can hide.
1. Numbers: Bits, Bases, and Signed Values
Core idea: A byte contains 8 bits. Each hex digit represents 4 bits, so two hex digits represent one byte. An unsigned n-bit value ranges from 0 through 2n − 1. For two’s complement, the highest bit has weight −2n−1; the other bits keep their positive weights.
On paper: Convert between bases, keep the specified width, and explain how signed and unsigned interpretations differ.
Use place values
0x6D = 0110 1101₂
= 6 × 16 + 13
= 109₁₀
The grouping checks the hex conversion; place values check the decimal result.
Check a negative value
8-bit signed: 1110 1011₂
= −128 + 64 + 32 + 8 + 2 + 1
= −21
To encode −21, start with 0001 0101, invert all eight bits,
and add one: 1110 1010 + 1 = 1110 1011.
Common mistakes: Dropping leading zeros changes the stated width. A leading 1 means negative only when the value is interpreted as signed. There are 256 eight-bit patterns, but the largest unsigned eight-bit value is 255.
Practice: Data Representation, Worksheet 02, Homework 1.
2. Addresses, Offsets, and Endianness
Core idea: In the course’s byte-addressable model, each address selects one byte. An n-bit address has 2n possible patterns. For a multi-byte value, endianness determines which byte goes at the lowest address.
On paper: Label consecutive byte addresses, split a value into bytes, and calculate capacity or an element’s byte offset.
Place two bytes in memory
A 16-bit value 0x4A91 begins at address 0x300:
| Byte order | 0x300 | 0x301 |
|---|---|---|
| Little endian | 0x91 | 0x4A |
| Big endian | 0x4A | 0x91 |
The number stays the same; its byte placement changes. A 10-bit byte-addressable space contains 210 = 1024 bytes, with addresses 0 through 1023.
Common mistakes: Reverse bytes, not individual bits within a byte. Keep address capacity separate from installed memory. In capacity calculations, state whether a large unit uses powers of two.
Practice: Memory Addresses, Worksheet 03, Homework 2 addressing exercise.
3. Read C Expressions and Functions
Core idea: Declarations give variables types; statements change values. A function receives argument values and may return a value. Compilation translates C to assembly, assembly produces object code, and linking combines object code into an executable.
On paper: Trace assignments in order, distinguish comparison from assignment, and match output formats to values.
Trace before printing
int count = 11;
int groups = count / 4;
int leftover = count % 4;
printf("%d %d\n", groups, leftover);
Integer division gives 2 whole groups; the remainder is 3. The output is
2 3. %d prints an int; %c prints a
character and %s prints a null-terminated string.
Common mistakes: =
assigns; == compares. A character uses single quotes; a string uses
double quotes. Updating a function’s local int parameter does not update the
caller’s original variable.
Practice: C Programming Basics, Worksheet 06, Lab 2: Linux.
4. Arrays, Pointers, Strings, and Structs
Core idea: A pointer stores an address; dereferencing accesses
the object there. Pointer arithmetic advances by the pointed-to type’s size.
A C string ends at '\0'. A struct groups fields, which can include
padding between them.
On paper: Distinguish an address from its contents, calculate array offsets, count string storage, and choose dot or arrow for field access.
Calculate an offset
If a four-byte int array starts at 0x500, its element with index
3 starts at 0x500 + 3 × 4 = 0x50C. The index counts elements;
the offset counts bytes.
char label[] = "oak";
This array has four bytes: three letters and the terminator. Its string length is three.
Choose the field operator
struct point { int row; int col; };
struct point spot = {2, 6};
struct point *location = &spot;
spot.col, location->col, and
(*location).col access the same field. A pointer’s size depends
on the platform, not the size of the object it points to.
Common mistakes: p
and *p mean different things. Indexing begins at zero. Use
. for a struct object and -> for a pointer to one;
do not assume every struct size is just the sum of its field sizes.
Practice: Pointers and Arrays, Strings and Structs, Worksheet 07, Worksheet 08.
5. ARM64 Registers, Arithmetic, Loads, and Stores
Core idea: wN is the lower 32-bit view of
xN. Writing wN clears the upper 32 bits of
xN. In our examples, ints use w registers and pointers use x registers.
On paper: Track source and destination registers, identify the accessed address, and distinguish a load from a store.
Separate register changes from memory changes
Suppose x4 holds an int array’s base address, and its second
element contains 14.
ldr w6, [x4, #4]
sub w7, w6, #3
str w7, [x4, #8]
The load reads the second element into w6. Subtraction puts 11
in w7. The store writes 11 into the third element. Neither operation
moves the base address in x4.
Common mistakes: The destination
comes first in arithmetic. ldr w6, [x4] loads four bytes of data
using a 64-bit address; it does not load the address itself. Avoid old ARM32
rN notation.
Practice: Assembly Basics, Worksheet 04, Homework 2 register-width and assembly tasks.
6. Comparisons, Branches, and Tracing
Core idea: cmp sets condition flags without
changing its input registers. A conditional branch reads those flags; an
unconditional b always jumps to its label.
On paper: Follow the executed path rather than reading every line as if it runs. Record values after each change.
Trace a short loop
mov w5, #6
.REPEAT:
sub w5, w5, #2
cmp w5, #0
bgt .REPEAT
The values after subtraction are 4, 2, then 0. The branch is taken twice; it is not taken after the comparison with zero. The body executes three times.
Common mistakes: A label is not an
instruction. A loop’s exit condition may be the opposite of its C continuation
condition. Do not change a value merely because cmp mentions it.
Practice: ARM64 Control Flow, Worksheet 05, Homework 3 assembly practice.
7. Function Arguments, Return Values, and Return Addresses
Core idea: For the simple functions studied in class, the
first int argument uses w0, the second uses w1, and
an int return value uses w0. Pointer arguments use the corresponding
x register. bl saves the next instruction’s address in
x30 and branches; ret returns through that saved address.
On paper: Identify values versus pointers, track an argument into a function, and distinguish the return value from the return address.
Read a leaf function
// int lower_by_two(int amount)
lower_by_two:
sub w0, w0, #2
ret
If its caller passes 9 in w0, subtracting two produces 7.
The returned int is in w0; x30 identifies where
execution resumes. A function making another call must preserve its own return
address before that call overwrites x30.
Common mistakes: b
does not save a return address. x30 holds a code address, not the
function’s numeric result. Passing an int and passing its address are different.
Practice: Stack and Procedure Calls, Worksheet 10, Lab 3: Function Calls with GDB.
8. Memory Hierarchy and Tradeoffs
Core idea: Registers, cache, main memory, and storage serve different purposes. Compare access speed, cost per byte, capacity, and whether data survives loss of power.
On paper: Explain a tradeoff and calculate a weighted access time when a cache strategy is specified.
Separate working memory from saved files
When you edit a document, DRAM holds data the running program uses frequently. Its fast access helps the CPU keep working. The saved document lives on nonvolatile storage such as an SSD, so it remains available after shutdown. An SSD is fast compared with a hard disk, but much slower than DRAM for active working-memory accesses. You do not need to memorize exact timings to explain this difference.
| Property | DRAM | SSD |
|---|---|---|
| Typical role | Active working data | Saved files and programs |
| Access speed | Much faster | Slower than DRAM |
| Without power | Contents are lost (volatile) | Contents persist (nonvolatile) |
| Cost and capacity | Typically higher cost per GB | Typically more storage for the same budget |
Explain, then compare: Name a property and connect it to the job the device does. Speed, persistence, and cost per byte are different properties. “Volatile” and “loses data without power” are two descriptions of one property. Capacity depends on the device and budget, not a rule that DRAM can never hold large amounts of data.
Use the stated cache model
Suppose a cache lookup takes 3 ns, the hit rate is 80%, and a miss requires an additional 40 ns memory access. Every request pays the lookup cost:
average = 0.80 × 3 + 0.20 × (3 + 40)
= 3 + 0.20 × 40 = 11 ns
For a large saved photo collection, nonvolatile storage keeps files after shutdown; DRAM serves active program data. Capacity and persistence matter as well as speed.
Common mistakes: A hit rate is a probability, not a time. Check whether a stated miss time includes the lookup. Faster memory does not automatically replace every other layer.
Practice: Memory Hierarchy, Worksheet 09, Homework 3 hierarchy and cache exercises.
Linux Commands: Find, Select, and Test
Use the terminal on your CSSE132 Linux VM to navigate, inspect files, build, and debug. Review Lab 2: Linux and its mystery cheatsheet for commands and pipes; revisit Lab 3 for GDB practice.
| Command | What it does |
|---|---|
pwd | Print your current directory. |
ls | List entries in the current directory. |
cd exercises / cd .. | Enter a directory / move to its parent. |
head -n 8 practice.txt | Print the first eight lines. |
tail -n 2 practice.txt | Print the last two lines. |
grep 'maple' notes.txt | Print lines containing the text maple. |
Worked example: select a line with a pipe
head -n 8 practice.txt | tail -n 1
head produces lines 1–8. The pipe | sends that
output to tail, which keeps its final line. The result is only
line 8 of practice.txt. Here tail reads the piped
text; it does not read the original file again.
Contents versus position: grep 'maple' notes.txt
searches for a value in the contents, wherever it occurs. It does not select
a numbered line. Use grep -n 'maple' notes.txt to also display
matching line numbers. Plain grep matches text within a line;
grep -x 'maple' notes.txt requires the entire line to match.
Build, run, and debug
make
./practice_runner
gdb ./practice_runner
Run make in the directory containing the provided Makefile.
If it defines a named target, use make target_name. Read the
instructions to find the executable name; ./ runs it from the
current directory. Check the test summary, not just whether it ran.
In GDB, break main sets a breakpoint; run starts
execution; next steps over a source line; step enters
a called function; print total inspects a variable;
continue resumes execution; and quit exits.
Build with debug information as provided by the course Makefile.
Two quick self-checks
- Which original file lines does
head -n 7 practice.txt | tail -n 2print? - A file has
42on line 5 and142on line 9. Doesgrep '42' values.txtselect line 42? Which lines match, and how would you match only the line whose complete contents are42?
Show Linux practice answers
- Lines 6 and 7: take the first seven, then the last two of that output.
- It searches contents, not line numbers. Both lines 5 and 9 match because
both contain the text 42. Use
grep -x '42' values.txtfor the whole-line match.
Quick Reference
| Task | Starting point |
|---|---|
| Signed n-bit range | −2n−1 through 2n−1 − 1 |
| Array element address | base + index × element size |
| Little endian | Least significant byte at lowest address |
| Load / store | Memory → register / register → memory |
| Call / return | bl saves next address; ret resumes there |
Check Yourself
Try these fresh practice prompts before opening the answers.
- Convert
0x35to eight-bit binary and decimal. - Interpret
1111 0110as an eight-bit signed value. - A four-byte int array begins at
0x640. Where does index 2 begin? - In the loop above, change the initial value to 8. How many times does the body execute?
- A function returns an int to its caller. Which register communicates that
value, and what different job does
x30perform?
Show practice answers
0011 0101; 3 × 16 + 5 = 53.- −10: −128 + 64 + 32 + 16 + 4 + 2 = −10.
0x648: add 2 × 4 = 8 bytes.- Four times: 6, 4, 2, 0 after subtraction.
w0communicates the int result;x30holds the return address.
Prepare for the Paper Exam
Start with a blank sheet. Do conversions without a converter, draw byte addresses, and trace code using a small register table. Then check your work against the linked readings and worksheets. For each mistake, explain why the correct result makes sense and try a different example. Use the posted practice paper as broader practice, not as a prediction of the exam’s question layout.
- I can show conversion steps and check signed values at a stated width.
- I can calculate byte addresses and draw either byte order.
- I can explain C expressions, pointer operations, and field access.
- I can track registers and memory separately, following branches by hand.
- I can distinguish function arguments, results, and return addresses.
- I can explain memory tradeoffs and recognize common mistakes.