gpt4 book ai didi

c - 为什么 strlen 的 REPNE SCASB 实现有效?

转载 作者:太空宇宙 更新时间:2023-11-04 01:20:58 25 4
gpt4 key购买 nike

为什么这段代码有效?

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

最佳答案

问题中的代码是 32 位版本的 strlen,它只能在 64b 环境中部分工作,有点“偶然”(因为大多数 SW 在现实中工作,无论如何 ;))。

64b 环境的一个意外影响是(在 64b linux 操作系统使用的 System V ABI 中,其他 64b 平台可能遵循不同的调用约定,使它无效!),函数调用中的第一个参数被传递rdi 注册,scasb 在 64b 模式下使用 es:rdi,所以这很自然地结合在一起(正如 Jester 的回答所说)。

其余的 64b 环境效果不太好,该代码将返回 4+G 长字符串的错误值(我知道,在实际使用中极不可能发生,但可以通过提供这么长的字符串的综合测试来尝试)。

修复了 64b 版本(例程结束时利用 rax=0 在单条指令中执行 neg ecxmov eax,ecx):

global  mystrlen
mystrlen:
xor ecx,ecx ; rcx = 0
dec rcx ; rcx = -1 (0xFFFFFFFFFFFFFFFF)
; rcx = maximum length to scan
xor eax,eax ; rax = 0 (al = 0 value to scan for)
repne scasb ; scan the memory for AL
sub rax,rcx ; rax = 0 - rcx_leftover = scanned bytes + 1
sub rax,2 ; fix that into "string length" (-1 for '\0')
ret

关于c - 为什么 strlen 的 REPNE SCASB 实现有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42655541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com