A Checked Array Project¶
Combine the previous lessons into a signed-array report with an explicit result pointer. Test the empty case, mixed signs and wider accumulation against an independent C implementation.
Course examples on GitHub
Before you start¶
Complete GDB debugging. You can trace a load, prove a finite loop and describe a function boundary.
Outcome: implement a sum-and-negative-count operation, check caller-side validation and explain its bounds. Use a fresh directory on the Pi. This project uses fixture arrays, not sensor data.
Agree on the public contract¶
The assembly function accepts a readable array of n signed 32-bit values and a writable eight-byte count pointer that does not overlap the input. For n=0, the input may be null, but the count pointer must still be valid. It returns the signed 64-bit sum and stores the number of negative elements.
The C wrapper accepts n <= 1024 and rejects null pointers for nonempty inputs. It cannot prove that an arbitrary non-null pointer is valid; storage extent and lifetime remain caller obligations. The bound keeps every allowed mathematical sum within int64_t.
Implement the core¶
Notice the order of flag uses: CSET consumes the comparison with zero; B.NE consumes the subsequent decrement. Interchanging them would test a different fact.
Test with an independent oracle¶
Each run should print:
The oracle uses a different expression of the algorithm, but passing these fixtures is not proof for every accessible array. Compiler sanitizers do not automatically instrument memory accesses inside hand-written assembly.
Part 3 checkpoint¶
Explain why the empty call still writes a count; why a null output must be rejected; why INT32_MIN must be sign-extended; and why an int32_t sum would be too narrow.
Add an all-negative fixture and a case with a sum larger than INT32_MAX. Keep the oracle independent. If a test fails, use the GDB loop invariant rather than changing the expected answer.
Extend by a requirement, not an instruction count¶
A minimum/maximum report needs an explicit empty-result policy. A checked-overflow variant needs a different contract. A hardware input adapter needs separate I/O error handling. None follows automatically from adding more assembly.
Check your understanding¶
Can checked_summary validate a dangling non-null pointer? What is the loop invariant?
Compare your reasoning
No; the caller must supply live storage. Before each iteration the sum/count summarize exactly the consumed prefix and the pointer/count describe the unread suffix.
Continue the course¶
Previous: Debugging with GDB · Course roadmap · Next: NEON and Scalar Tails