【发布时间】:2017-03-07 18:22:31
【问题描述】:
为什么这段代码有效?
http://www.int80h.org/strlen/ 表示字符串地址必须在EDI 寄存器中,scasb 才能工作,但这个汇编函数似乎没有这样做。
mystrlen 的汇编代码:
global mystrlen
mystrlen:
sub ecx, ecx
not ecx
sub al, al
cld
repne scasb
neg ecx
dec ecx
dec ecx
mov eax, ecx
ret
C 主要:
int mystrlen(const char *);
int main()
{
return (mystrlen("1234"));
}
编译:
nasm -f elf64 test.asm
gcc -c main.c
gcc main.o test.o
输出:
./a.out
echo $?
4
【问题讨论】:
-
64 位 sysv 调用约定将第一个参数放入
rdi。所以调用者main已经为你完成了这个加载。您可以检查它的汇编代码并亲自查看。 -
cld也是废话/多余的。调用约定要求在函数入口处清除方向标志。 -
@R.. 这是什么意思?我对 asm 真的很陌生
-
我相信这有点意外,那个来源实际上是32b,最多搜索4G字符串长度(如果你给它提供5G长字符串,它会返回错误的答案)。归零
ecx也将清除rcx,但随后not ecx失败(dec rcx会更好)然后ecx的剩余反转也必须调整为rcx,并返回值rax. -
@Ped7g 你是对的,也许可以添加这个作为答案?
标签: c assembly x86-64 calling-convention strlen