- 您使用比必要的更多说明使这变得过于复杂
a
将是argv[1]
,但您正在加载(按照惯例,程序名称,但如果您的程序是从普通 shell 以外的其他东西argv[0]
调用的,则可能是 NULL 指针或任意字符串)。execve()
- 您正在
"a"
与指针值进行比较,而不是与指向的字符串数据进行比较。
即你写的C版本是
if( (intptr_t)argv[0] == "a" ){
success:
}
对于汇编时间常数索引,您应该只使用位移而不是索引寄存器。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
是 x86-64 System V ABI 中的调用保留寄存器,因此如果您main
返回而不是call exit
,您应该将 R14 保留为与输入时相同的值。 通过 linux x86-64 函数调用保留了哪些寄存器
RDX 是 call-clobbered,因此它是暂存器的不错选择。
它还节省了一个字节的代码大小以使用 RDX 或其他不需要 REX 前缀而不是 R8..15 的暂存寄存器。qwordmov
总是需要一个 REX 前缀,但字节cmp
不需要。