Master the fundamental concepts of instruction set architecture through this focused micro-challenge.
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 worksOn Linux and macOS, compiled C functions follow the System V AMD64 ABI. The first six integer or pointer arguments arrive in registers; additional args sit on the stack. Return values land in RAX (integer) or XMM0 (float).
| Arg | Register |
|---|---|
| 1st | RDI |
| 2nd | RSI |
| 3rd | RDX |
| 4th | RCX |
| 5th | R8 |
| 6th | R9 |
cLoading…
For this exercise, you will trace a function call in assembly and label which registers hold arguments and return values. This task asks you to read the ABI the way Ghidra does when it recovers main's parameters from a stripped binary.
Keep the relevant datasheet, ISA manual, or architecture textbook chapter open while you implement. When your output disagrees with the reference trace on the same program, the bug is usually a mis-decoded opcode, a stale register read, or a flag bit left unchanged after arithmetic.
For this exercise, you will use those habits while implementing the requirement in the starter code. Microarchitectural product names change across CPU generations, but the control ideas (fetch, bypass, cache lines, vector lanes) stay stable enough to debug from first principles.
Write the part of a compiler that decides where each argument lives under the x86-64 System V ABI, the calling convention used on Linux, macOS and the BSDs. Given C function prototypes, print the register or stack slot each parameter arrives in, using the correctly sized register name. Also print where the return value goes and how much stack the caller must reserve.
char, short, int, long, long long, their unsigned forms, and any pointer T *): the first six go in rdi, rsi, rdx, rcx, r8, r9, in that order.float, double): the first eight go in xmm0: xmm7.f(int, double, int) uses edi, xmm0, esi.[rsp+8] ([rsp] holds the return address), the next at [rsp+16], and so on.char), 2 (short), 4 (int, float), 8 (long, long long, pointers, double).| 64-bit | 32-bit | 16-bit | 8-bit |
|---|---|---|---|
| rdi | edi | di | dil |
| rsi | esi | si | sil |
| rdx | edx | dx | dl |
| rcx | ecx | cx | cl |
| r8 | r8d | r8w | r8b |
| r9 | r9d | r9w | r9b |
al/ax/eax/rax by size; float/double → xmm0; void → none.One prototype per line, e.g. long f(int a, double b, char *s);. Every parameter has a name. () and (void) mean no parameters. Types use the keywords above, optionally with const (kept in the printed type, no effect on the class), and * may touch the name (char *s, char* s, char*s).
cLoading…
M is N rounded up to a multiple of 16, because rsp must be 16-byte aligned at the call. Print a blank line between functions. For the void return, print return (void) -> none.
Input:
cLoading…
Output:
cLoading…
Hidden tests cover more than six integer arguments, more than eight floating-point arguments, char/short/unsigned sizes, void and float returns, and (void) parameter lists.