.intel_syntax noprefix .extern main .section .text .global _start _start: # On entry, the stack contains: # [rsp] = argc (argument count) # [rsp+8] = argv[0] (program name) # [rsp+16] = argv[1] (first argument) # ... # Get argc from stack mov rdi, [rsp] # rdi = argc # Calculate space needed for our array structure # We need: 8 bytes (length) + argc * 8 bytes (pointers) mov rax, rdi # rax = argc shl rax, 3 # rax = argc * 8 (each pointer is 8 bytes) add rax, 8 # rax = 8 + argc * 8 (add space for length) # Allocate space on stack (align to 16 bytes) add rax, 15 # Round up to nearest 16 and rax, -16 # Align to 16 bytes sub rsp, rax # Allocate space # Store array length at beginning mov [rsp], rdi # Store argc as array length # Copy argv pointers to our array lea rsi, [rsp + 8] # rsi points to start of argv in stack lea rdi, [rsp + 8] # rdi points to our array data (after length) mov rcx, [rsp] # rcx = argc (loop counter) copy_loop: test rcx, rcx # Check if we're done jz done_copying mov rax, [rsi] # Load argv[i] pointer mov [rdi], rax # Store in our array add rsi, 8 # Move to next argv entry add rdi, 8 # Move to next array slot dec rcx # Decrement counter jmp copy_loop done_copying: # Now rsp points to our array: [length][ptr0][ptr1]...[ptrN-1] mov rdi, rsp # Pass array pointer to main call main # Clean up stack (restore original rsp) # Calculate how much we allocated mov rdi, [rsp] # Get argc back shl rdi, 3 # argc * 8 add rdi, 8 # + 8 for length add rdi, 15 # Round up and rdi, -16 # Align add rsp, rdi # Restore stack # Exit with main's return value mov rdi, rax # rax contains main's return value mov rax, 60 # sys_exit syscall