You were comparing a pointer to 8 bytes of the arg
string.
To compare strings, since you are using the C runtime, you could do it as you would in C: with strcmp
.
.global main
.text
strIArg: .asciz "-i"
strHello: .asciz "Hello.\n"
main:
sub $8, %rsp
#At least two args?
cmp $2, %edi
jb 1f
#2nd arg is equal to strIArg?
mov 8(%rsi), %rdi #argv[1] in RDI
lea strIArg(%rip), %rsi #"-i" in RSI (I'm making a PIE, hence the RIP-relative addressing)
call strcmp
test %eax, %eax #strcmp returns 0 if the two strings are equal
jnz 1f
#OK, arg found
lea strHello(%rip), %rdi
call printf
1:
xor %edi, %edi
call exit
Alternatively, you can shave off the call to strcmp
to improve performance if your argument is short enough and your program is very simple.
.global main
.text
strHello: .asciz "Hello.\n"
main:
sub $8, %rsp
#At least two args?
cmp $2, %edi
jb 1f
#2nd arg is equal to strIArg?
mov 8(%rsi), %rdi
cmpb $0, (%rdi)
je 1f #Empty string?
cmpw $0x692d, (%rdi) #Starts with -i ?
jne 1f
cmpb $0, 2(%rdi) #And then it ends?
jne 1f
#OK, arg found
lea strHello(%rip), %rdi
call printf
1:
xor %edi, %edi
call exit
But I would not recommend it but for the very simplest of cases, since GAS doesn't support string literals as immediates and you need to convert the string your self (taking care of the little-endianness of x86) reducing the readability of the code.
Finally, for more complex programs running on a POSIX system you may want to consider getopt_long
and variants.
Below is an example of a program that greets the names passed on the command line and that takes two optional arguments to modify its behavior.
Note how getopt_long
will take care of reordering the arguments, handling corner cases (e.g. when the user pass -un X
as a short for -u -n X
) and handling --
for us.
.global main
.data
#Name to use for the greetings
name: .quad defaultName
#Greeting string to use
greetings: .quad strHello
#The long options accepted
nameOpt:
.quad nameOptName #name
.quad 1 #has arg
.quad 0 #ptr to flag to update with val (0 to make getopt_long return val instead)
.quad 'n' #val
uppercaseOpt:
.quad uppercaseOptName
.quad 0
.quad 0
.quad 'u'
nullOpt:
.quad 0
.quad 0
.quad 0
.quad 0 #Last option must be null
.text
#Greetings strings
strHello: .asciz "Hello %s from %s!\n"
strHelloUpper: .asciz "HELLO %s FROM %s!\n"
#Default name
defaultName: .asciz "Margaret"
nameOptName: .asciz "name"
uppercaseOptName: .asciz "upper"
#The short options accepted, note how we use "n" and "u" for both the long and short options
#this is to reuse the logic but getopt_long allows to distinguish the two cases
shortOpts: .asciz "n:u"
main:
sub $8, %rsp
#If you return from main, push r12 and r13 (and then pop them)
#Move the args to non-volatile registers
mov %rdi, %r12 #R12 = argc
mov %rsi, %r13 #R13 = argv
parseArgs:
mov %r12, %rdi
mov %r13, %rsi
lea shortOpts(%rip), %rdx
lea nameOpt(%rip), %rcx
xor %r8, %r8
call getopt_long
#Found --name/-n?
cmp $'n', %al
je foundName
#Found --upper/-u?
cmp $'u', %al
je foundUpper
#Everything else is an error or end of option args (-1)
test %eax, %eax
jns parseError
#Args are parsed, optind is the index of the first non optional arg
lea (%r13, %r12, 8), %r12 #R12 = one past the last argument
mov optind(%rip), %ecx #RCX = current index
lea (%r13, %rcx, 8), %r13 #R13 = pointer to pointer to current argument
#Print the greetings
doGreetings:
#Stop?
cmp %r12, %r13
jae end
#Print the current greetings
mov greetings(%rip), %rdi
mov (%r13), %rsi
mov name(%rip), %rdx
call printf
#Next arg
add $8, %r13
jmp doGreetings
end:
xor %edi, %edi
call exit
foundName:
#Here optarg is a pointer to the argument value
#Copy the pointer to name
mov optarg(%rip), %rdx
mov %rdx, name(%rip)
jmp parseArgs
foundUpper:
#This option has no argument, we just set the greetings to strHelloUpper
lea strHelloUpper(%rip), %rcx
mov %rcx, greetings(%rip)
jmp parseArgs
parseError:
#Just return 1
mov $1, %edi
call exit
You can compile this program with GCC and then run it as:
./greet Alice Bob Eve
./geeet Alice --name Bob
./greet Alice --upper
./greet --name Eve --upper Alice
./greet -u Alice
./greet Alice -un Bob