Home > database >  Trouble getting command line arguments in x86 assembly
Trouble getting command line arguments in x86 assembly

Time:01-14

I'm trying to write an x86 version of the 'cat' program as a training of syscall calls in assembly.

I'm struggling a lot with command line arguments. I use the main symbol as an entry point, so I thought I would find the argc parameter in %rdi and the argv parameter in %rsi. Actually argc is in %rdi as expected, but I keep segfaulting when trying to pass argv[1] to the open syscall.

Not sure of what I'm doing wrong, here is my assembly code:

main:
    cmp $2, %rdi            // If argc != 2 return 1
    jne .err1

    lea 8(%rsi), %rdi       // Move argv[1] -> %rdi
    xor %rsi, %rsi          // 0 to %rsi -> O_RDONLY
    xor %rdx, %rdx
    mov $2, %rax            // Open = syscall 2
    syscall

    cmp 0, %rax             // If open returns <0 -> exit status 2
    jl .err2

    mov %rax, %rdi          // Move fd to %rdi
    call cat
    ret

.err1:
    mov $1, %rax
    ret
.err2:
    mov $2, %rax
    ret

CodePudding user response:

There are two issues with your code.

First, you use lea 8(%rsi), %rdi to retrieve the second argument. Note that rsi points to an array of pointers to command line arguments, so to retrieve the pointer to the second argument, you have to dereference 8(%rsi) using something like mov 8(%rsi), %rdi.

Second, you forgot the dollar sign in front of 0 in cmp $0, %rax. This causes an absolute address mode for address 0 to be selected, effectively dereferencing a null pointer. To fix this, add the missing dollar sign to select an immediate addressing mode.

When I fix both issues, your code as far as you posted it seems to work just fine.

  •  Tags:  
  • Related