section .data
format db '%d', 0x0a, 0
section .text
global ft_strlen
ft_strlen:
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
mov eax, 0
loop:
mov cl, [ecx + eax]
inc eax
cmp cl, 0
jne loop
mov esp, ebp
pop ebp
ret
当我使用 cl 寄存器时,程序正常工作,但是当我使用 al 时,它给了我一个无限循环,当我使用 bl 时,它给了我一个 SEGV。 实际上这很奇怪,因为其中三个是8位寄存器。
当我使用
注册时,程序可以正常工作,但是当我使用cl
时,它会给我一个无限循环al
这两个选项同样错误,但它们所产生的效果大多是巧合!
在
mov cl, [ecx + eax]
中,ECX是字符串的基地址,EAX是字符串的偏移量。您不应将字符串中的字节加载到 CL 中,因为 CL 是较大 ECX 寄存器的最低 8 位,同样,您不应将字节加载到 AL 中,因为 AL 是较大 EAX 寄存器的最低 8 位。
当我使用
时,它会给我一个 SEGV。bl
一旦保留了 BL 预先存在的值(在堆栈上),使用 BL 就会成为一种选择。那是因为 EBX 需要“调用保留”。
其实很奇怪,因为其中三个是8位寄存器。
x86 架构没有单独的 8 位寄存器。我们所认为的 8 位寄存器始终是更大寄存器的一部分。
ft_strlen:
mov ecx, [esp+4] ; Base
xor eax, eax ; Offset
.loop:
movzx edx, byte [ecx + eax]
inc eax
test dl, dl
jnz .loop
dec eax ; Don't include zero-terminator
ret
您的代码在返回的计数中包含零终止符。通常,我们不会这样做...