Question 4 of 6: Calling Conventions and Unsigned Arithmetic
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Notes on this paper
98-Comp-A3, Computer Architecture — National Exams, May 2013. Open-book, 3 hours; six questions of equal value (20 marks each); FIVE constitute a complete exam (all six answered below as a complete study resource).
Reference texts: Patterson & Hennessy, Computer Organization and Design, 6th ed. — instruction encoding & the stored-program principle (Ch.2, Q1), memory addressing & data representation (Ch.2, Q2), cache organization & memory hierarchy (Ch.5, Q3 & Q6), procedure-call conventions & unsigned arithmetic (Ch.2–3, Q4), and CPU performance / the multicycle datapath (Ch.1 & Ch.4, Q5) — covering all six questions.
Question 4: Calling Conventions and Unsigned Arithmetic (20 marks)
Given. A processor with a standard register-based calling convention; unsigned integers A and B on an $n$-bit machine (arithmetic performed modulo $2^n$).
Find. (a) the caller-saved / callee-saved distinction and when each is preferable; (b) the advantage of register-based argument passing and whether ALL arguments can always be passed that way; (c) whether $A+B>A$ and $A-B\lt A$ hold for all unsigned $A,B$.
Approach. (a)/(b) argue from the calling-convention cost tradeoff (who pays the save/restore, and how many physical registers exist); (c) reason from modulo-$2^n$ unsigned arithmetic and construct explicit counterexamples.
Part (a) — caller-saved vs. callee-saved registers. These are two conventions for who is responsible for preserving a register's value across a function call. Caller-saved ("volatile"/scratch registers): the CALLING routine must save the register itself, before the call, if it still needs that value afterward — the callee is free to overwrite these without saving or restoring them. Callee-saved ("preserved" registers): the CALLED routine must save the register on entry and restore it before returning if it uses that register at all — the caller can then rely on those registers holding their pre-call values right after the call, at no effort of its own. When is one better? Caller-saved is cheaper for values that are short-lived and NOT needed after most calls — the (common) caller with no live value in that register pays nothing, whereas a callee-saved convention would force every callee touching the register to save/restore even when no caller ever needed the old value kept. Callee-saved is cheaper for values that stay live across MANY calls (loop counters, frame/base pointers) — one save/restore in the single callee that uses the register beats every caller along the chain saving it before every call it makes.
Part (b) — register vs. stack argument passing. Passing arguments in registers avoids a store-then-load round trip through memory on every call: the callee reads its arguments straight out of registers instead of computing stack-frame offsets and issuing memory operations — fewer instructions and lower latency (no memory/cache access on the argument path), which matters most for small, frequently-called (e.g. leaf) functions where argument setup is a large fraction of total call cost.
Can ALL arguments always be passed through registers? No. A processor reserves only a small, fixed number of argument registers (real ISAs typically 4–8), so a call with more arguments than that has nowhere left but the stack for the excess. Variadic functions (argument count not fixed at compile time) and large aggregates/structs passed by value (bigger than one register, or than all remaining argument registers combined) also cannot be fully register-resident. Real calling conventions therefore use a hybrid rule: the first few scalar arguments go in registers, everything beyond that — or anything too large — goes on the stack.