8.6 KiB
Week 7 Quiz: Constants, I²C, Structs, and String Patching
Instructions
Choose the best answer for each question. There is only one correct answer per question.
Questions
Question 1
What is the key difference between #define FAV_NUM 42 and const int OTHER_FAV_NUM = 1337 in terms of how they appear in the compiled binary?
A) #define appears as movs r1, #0x2a (16-bit Thumb) and const appears as movw r1, #0x539 (32-bit Thumb-2) — both are instruction immediates because the compiler optimized away the const variable
B) #define creates a value in the .data section; const creates a value in the .rodata section
C) #define is replaced by the preprocessor so the value appears as an immediate in instructions; const always creates a real variable loaded from flash via ldr
D) #define values are stored in SRAM; const values are stored in flash
📖 Reference: Week 7, Part 9, Step 12 – "Analyze #define vs const in Assembly" (Both end up as instruction immediates:
movs r1, #0x2afor FAV_NUM andmovw r1, #0x539for OTHER_FAV_NUM. The compiler optimized theconstbecause&OTHER_FAV_NUMis never taken.)
Correct Answer: A
Question 2
I²C uses two wires for communication. What are they called and what is each used for?
A) TX (transmit data) and RX (receive data)
B) SDA (serial data) and SCL (serial clock)
C) MOSI (master out) and MISO (master in)
D) VCC (power) and GND (ground)
📖 Reference: Week 7, Part 2 – "The Two I²C Wires" table (SDA = Serial Data, SCL = Serial Clock)
Correct Answer: B
Question 3
Why do I²C bus lines require pull-up resistors?
A) To limit current and protect the devices from damage
B) I²C uses open-drain signals — devices can only pull lines LOW, so pull-ups are needed to bring lines back HIGH
C) The pull-ups provide power to the I²C slave devices
D) Pull-ups increase the data transfer speed by reducing line capacitance
📖 Reference: Week 7, Part 2 – "Why Pull-Up Resistors?" (I²C uses open-drain signals; devices can only pull LOW, pull-ups bring lines back to HIGH)
Correct Answer: B
Question 4
The i2c1_inst struct in SRAM at address 0x2000062c contains two members. What are they?
A) sda_pin = 2 and scl_pin = 3 (the GPIO pin numbers)
B) hw = 0x40098000 (pointer to hardware registers) and restart_on_next = false
C) address = 0x27 (LCD I²C address) and baud_rate = 100000
D) tx_buffer and rx_buffer (data transfer buffers)
📖 Reference: Week 7, Part 8, Step 9 and Part 9, Step 13 – examining
i2c1_instat0x2000062cshows0x40098000(hw pointer) and0x00000000(restart_on_next = false)
Correct Answer: B
Question 5
In the Thumb instruction movs r1, #0x2a, the bytes in the binary are 2A 21. If you want to change FAV_NUM from 42 to 99, what bytes would you write?
A) 63 21 — because 99 in hex is 0x63 and the opcode 21 stays the same
B) 99 21 — because 99 in decimal is written directly
C) 21 63 — because the opcode comes first in big-endian format
D) 63 00 — because the opcode changes when the value changes
📖 Reference: Week 7, Part 10, Step 17 – "How Thumb encoding works" (immediate value is the first byte, opcode
21is the second;movs r1, #imm8)
Correct Answer: A
Question 6
The movw r1, #1337 instruction at 0x10000296 encodes the value 1337 (0x539) in a 32-bit Thumb-2 instruction. The raw bytes are 40 F2 39 51. Where is the lower 8 bits of the immediate value (0x39) located?
A) Byte 0 (0x40) — the immediate is always in the first byte of the instruction
B) Byte 2 (0x39) — the imm8 field is in the third byte (low byte of the second halfword)
C) Byte 3 (0x51) — the immediate is stored in the last byte along with the register
D) The value 0x539 is stored as a separate 4-byte word in the literal pool, not in the instruction
📖 Reference: Week 7, Part 10, Step 18 – "Understand the Encoding" (the
movwencoding diagram shows Byte 2 =0x39= imm8 field, which holds the lower 8 bits of the immediate value)
Correct Answer: B
Question 7
When patching the LCD string "Reverse" to "Exploit" in the binary, why must the replacement string be the same length?
A) The LCD hardware only accepts strings of exactly 7 characters
B) The replacement must fit within the allocated bytes — a longer string would overwrite adjacent data (like the "Engineering" string stored immediately after)
C) The Thumb instruction set cannot encode string addresses of different lengths
D) The Pico SDK validates string lengths at boot and rejects changes
📖 Reference: Week 7, Part 10, Step 19 – "IMPORTANT: The new string must be the same length as the original!" and Key Takeaway 8
Correct Answer: B
Question 8
The LCD string "Reverse" is located at address 0x10003ee8. What is the correct file offset in the .bin file?
A) 0x3EE8 — subtract the base address 0x10000000
B) 0x10003EE8 — the file offset is the same as the memory address
C) 0x7DD0 — multiply by 2 because the binary uses 16-bit alignment
D) 0x3EE0 — round down to the nearest 16-byte boundary
📖 Reference: Week 7, Part 10, Step 16 – "Calculate the File Offset" (file_offset = address − 0x10000000;
0x10003ee8→0x3EE8)
Correct Answer: A
Question 9
What does the macro chain I2C_PORT → i2c1 → &i2c1_inst → hw → 0x40098000 represent?
A) The sequence of function calls during I²C initialization
B) The path from a high-level macro in your code to the physical I²C1 hardware registers, through preprocessor expansion, pointer dereference, and struct member access
C) The I²C data transmission protocol (start, address, data, stop)
D) The order in which the compiler optimizes I²C-related code
📖 Reference: Week 7, Part 4 – "The Macro Chain" diagram and Part 9, Step 13 – tracing the chain from code to
0x40098000
Correct Answer: B
Question 10
The compiler transforms gpio_pull_up(2) into a call to gpio_set_pulls(2, 1, 0). What does each argument represent?
A) Pin number, pull-up resistance value in kΩ, pull-down resistance value in kΩ
B) Pin number, enable pull-up (true), enable pull-down (false)
C) SDA pin, SCL pin, I²C bus number
D) Pin number, direction (1 = input), initial value (0 = LOW)
📖 Reference: Week 7, Key Takeaway 10 – "Compiler optimization changes code —
gpio_pull_upbecomesgpio_set_pulls" and Week 6 reference (inlined function: pin, up=true, down=false)
Correct Answer: B
Answer Key
- A - Both
#defineandconstappear as instruction immediates (movsandmovw) because the compiler optimized theconst— its address is never taken - B - SDA (Serial Data) carries data; SCL (Serial Clock) provides timing
- B - I²C open-drain signals can only pull LOW; pull-ups return lines to HIGH
- B -
hw=0x40098000(hardware register pointer) andrestart_on_next= false - A - Change
2Ato63(99 in hex); opcode21(movs r1, #imm8) remains unchanged - B - The imm8 field (lower 8 bits of the immediate) is in the third byte of the 4-byte
movwinstruction - B - A longer string would overwrite adjacent data in the
.rodatasection - A - File offset = address − base =
0x10003EE8−0x10000000=0x3EE8 - B - The chain traces from a C macro through pointer indirection to physical hardware register addresses
- B - Arguments are: GPIO pin number, pull-up enable (true), pull-down enable (false)
Scoring Guide
- 10 correct: Excellent! You have a strong grasp of Week 7 concepts
- 8-9 correct: Very good! Review the topics you missed
- 6-7 correct: Good start. Go back and review the key concepts
- 5 or fewer: Review the Week 7 material again and try the practice exercises
Topics Covered
This quiz tests your understanding of:
#definepreprocessor macros vsconstvariables: compiler optimization of const to immediates- I²C communication protocol: SDA/SCL wires and pull-up resistor requirements
- Pico SDK
i2c_inst_tstruct layout and hardware register pointers - Thumb instruction encoding:
movs rD, #imm8andmovw rD, #imm16byte layouts - 32-bit Thumb-2
movwencoding: imm8 field location in the instruction - String patching constraints: same-length rule and adjacent data corruption risk
- File offset calculation: memory address minus base address
0x10000000 - SDK macro chain: from
I2C_PORTto0x40098000hardware registers - Compiler optimization:
gpio_pull_upinlined asgpio_set_pulls