- You're overcomplicating this with more instructions than necessary
a
will be argv[1]
, but you're loading argv[0]
(by convention the program name, but could be a NULL pointer or arbitrary string if your program is invoked with execve()
from something other than a normal shell).
- you're comparing
"a"
with the pointer value, not with the pointed-to string data.
i.e. the C version of what you wrote is
if( (intptr_t)argv[0] == "a" ){
success:
}
For an assemble-time-constant index, you should just use a displacement instead of an index register. You can write it in a way that looks nice for humans using an assemble-time expression like 1 * 8
or 0 * 8
.
global main
main:
cmp edi, 2
jb too_few_args ; if(argc<2) avoid segfaults in both of the next 2 insns
mov rdx, [rsi + 8*1] ; r14 = argv[1]
cmp byte [rdx], "a" ; argv[1][0] == 'a'
je success
...
success:
xor eax,eax
ret ; return 0
r14
is a call-preserved register in the x86-64 System V ABI, so if your main
returns instead of call exit
, you should leave R14 with the same value it had on entry. What registers are preserved through a linux x86-64 function call
RDX is call-clobbered, so it's a good choice for a scratch register.
It also saves a byte of code-size to use RDX or some other scratch register that doesn't need a REX prefix instead of R8..15. The qword mov
will always need a REX prefix, but the byte cmp
won't.