# x86-64 machine code, 12 bytes This is a function, callable with args `n=RCX`, `k=ESI`. 32-bit return value in `EAX`. Callable from C with the x86-64 System V calling convention with dummy args to get the real args into the right registers. `uint32_t factk(int, uint32_t k, int, uint64_t n);` I couldn't just use Windows x64 because 1-operand `mul` clobbers RDX, and we don't want REX prefixes to access R8/R9. `n` must not have any garbage in the high 32 bits so JRCXZ works, but other than that it's all 32-bit. NASM listing (relative address, machine code, source) 1 factk: 2 00000000 6A01 push 1 3 00000002 58 pop rax ; retval = 1 4 00000003 E306 jrcxz .n_zero ; if (n==0) return 5 .loop: ; do { 6 00000005 F7E1 mul ecx ; retval *= n (clobbering RDX) 7 00000007 29F1 sub ecx, esi ; n -= k 8 00000009 77FA ja .loop ; }while(sub didn't wrap or give zero) 9 .n_zero: 10 0000000B C3 ret 0xc = 12 bytes --- Test caller that passes `argc` as `k`, with `n` hard-coded. ``` align 16 global _start _start: mov esi, [rsp] ;main: mov ecx, 9 call factk mov esi, eax mov edx, eax lea rdi, [rel print_format] xor eax, eax extern printf call printf extern exit call exit section .rodata print_format: db `%#x\t%u\n` ```