Command Line Arguments in Assembly Language

section .data
    argsWithProg db "Command line arguments with program name:", 0
    argsWithoutProg db "Command line arguments without program name:", 0
    argMsg db "Third argument:", 0
    newline db 10

section .text
    global _start

_start:
    ; Get the command line arguments
    pop rax         ; Get the number of arguments
    mov rbx, rax    ; Store the number of arguments in rbx

    ; Print argsWithProg message
    mov rax, 1
    mov rdi, 1
    mov rsi, argsWithProg
    mov rdx, 46
    syscall

    ; Print all arguments (including program name)
    mov rcx, rbx    ; Set counter to number of arguments
print_loop:
    pop rsi         ; Get next argument
    call print_string
    loop print_loop

    ; Print newline
    mov rax, 1
    mov rdi, 1
    mov rsi, newline
    mov rdx, 1
    syscall

    ; Print argsWithoutProg message
    mov rax, 1
    mov rdi, 1
    mov rsi, argsWithoutProg
    mov rdx, 51
    syscall

    ; Print arguments without program name
    dec rbx         ; Decrease counter to skip program name
    mov rcx, rbx
print_loop2:
    pop rsi         ; Get next argument
    call print_string
    loop print_loop2

    ; Print newline
    mov rax, 1
    mov rdi, 1
    mov rsi, newline
    mov rdx, 1
    syscall

    ; Print third argument (if it exists)
    cmp rbx, 3      ; Check if we have at least 3 arguments
    jl exit         ; If not, exit

    mov rax, 1
    mov rdi, 1
    mov rsi, argMsg
    mov rdx, 15
    syscall

    pop rsi         ; Get program name (discard)
    pop rsi         ; Get first argument (discard)
    pop rsi         ; Get second argument (discard)
    pop rsi         ; Get third argument
    call print_string

    ; Exit program
exit:
    mov rax, 60
    xor rdi, rdi
    syscall

; Function to print a null-terminated string
print_string:
    push rax
    push rdi
    push rdx
    push rcx

    mov rdx, 0
count_loop:
    cmp byte [rsi + rdx], 0
    je done_counting
    inc rdx
    jmp count_loop

done_counting:
    mov rax, 1
    mov rdi, 1
    syscall

    pop rcx
    pop rdx
    pop rdi
    pop rax
    ret

This Assembly Language code demonstrates how to work with command-line arguments. Here’s an explanation of how it works:

  1. The code starts by defining some constant strings in the .data section.

  2. In the _start function, it first retrieves the number of command-line arguments.

  3. It then prints all arguments, including the program name, by looping through the argument list on the stack.

  4. After that, it prints the arguments again, but this time skipping the program name.

  5. Finally, if there are at least three arguments, it prints the third argument separately.

  6. The print_string function is a utility to print null-terminated strings.

To assemble and link this program, you would typically use nasm and ld. For example:

$ nasm -f elf64 command_line_arguments.asm
$ ld -o command_line_arguments command_line_arguments.o
$ ./command_line_arguments arg1 arg2 arg3
Command line arguments with program name:./command_line_arguments arg1 arg2 arg3
Command line arguments without program name:arg1 arg2 arg3
Third argument:arg3

Note that Assembly Language is much lower level than high-level languages, so this implementation is more verbose and requires manual memory management and system call invocations.