Master the fundamental concepts of code generation through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksEvery compiled function needs a prologue to set up the stack frame and an epilogue to tear it down. x86-64 SysV ABI: push rbp; mov rbp, rsp; sub rsp, N in prologue; mov rsp, rbp; pop rbp; ret in epilogue. Clang and GCC emit these around every function body.
Save caller's frame pointer. Establish new frame pointer. Allocate space for locals and spilled registers. On return, reverse the sequence and restore callee-saved registers.
asmLoading…
Production compilers embed this step inside a longer pipeline. GCC flows through cpp, cc1, assembly, and ld; Clang uses the driver, Sema, LLVM IR passes, and a target backend. LLVM bitcode, JVM bytecode, and WASM are other familiar IRs at the same layer. The exercise isolates one pass so you can test it alone before chaining it to the next stage.
You will generate function prologue and epilogue assembly. This exercise asks you to emit stack frame setup and teardown instructions that bracket the function body per the target ABI.
Generate the prologue and epilogue of x86-64 functions under the System V ABI: save the frame pointer and any callee-saved registers, reserve an aligned frame, spill register arguments to their home slots, and undo it all on the way out.
One function per line:
cLoading…
locals(...) and saves(...) may be empty or missing. Every parameter and local is 8 bytes. Callee-saved registers come from rbx r12 r13 r14 r15.
push rbp, mov rbp, rsp. At this point rsp is 16-byte aligned.k-th one lives at [rbp-8k].rdi rsi rdx rcx r8 r9 and get home slots, then the locals get slots, continuing downward: the first slot is just below the last saved register.[rbp+16], [rbp+24], … and are not copied.N bytes with sub rsp, N, where N is the smallest value ≥ 8 × (slots) such that 8 × saves + N is a multiple of 16, so rsp is aligned for any call the body makes. Omit the sub when N is 0.mov [rbp-OFF], REG.Epilogue: if registers were saved, lea rsp, [rbp-8×saves] then pop them in reverse order; otherwise mov rsp, rbp. Then pop rbp and ret.
For each function (a blank line between functions):
cLoading…
The frame line lists parameters in order, then locals; S is the number of bytes below rbp (8 × saves + N). Instructions are indented 4 spaces.
Input:
cLoading…
Output:
cLoading…
(4 slots = 32 bytes; 8 + 32 = 40 is not a multiple of 16, so N becomes 40.)
N) before printing anything.rsp from rbp before popping, so it is correct whatever the body did to the stack.Hidden tests cover more than six parameters, functions with no locals or no saved registers, several saved registers, and a function with nothing to save or store at all.