NASM(64 位 linux):我的 'puts' 程序不适用于我的 'strlen' 程序

NASM (64-bit linux): my 'puts' procedure doesn't work with my 'strlen' procedure

作为序言,我 运行 这是在 64 位 Linux OS 上,因此我使用 64 位 Linux 系统调用。

我的 strlen 过程将 rdi 作为参数,returns rax 中的字符串 excluding [=17=] 的长度。 (您必须输入以 \0 结尾的字符串)。我已经测试了这个程序并且知道它可以正常工作。

我的 puts 程序将 rdi 作为参数,使用 strlen 获取长度,然后使用 write 系统调用。

这是一个(希望如此)最小的可重现示例:

section .data
    msg db "HELLO", 10, 0

section .text
    global _start
_start:
    mov  rdi, msg
    call puts
    mov  rax, 0x3c
    xor  rdi, rdi
    syscall

strlen:
    push rdi
    push rcx
    push rsi

    xor rax, rax
    mov rcx, 0xffffffff
    repnz scasb
    jnz .error
    not rcx
    dec rcx
    mov rax, rcx
.return:
    pop rsi
    pop rcx
    pop rdi
    ret
.error:
    mov rax, -1
    jmp .return

puts:
    mov rsi, rdi
    call strlen
    mov rdx, rax
    mov rax, 1
    mov rdi, rax
    syscall
    ret

我真的很困惑为什么这不起作用。我的 puts 过程实际上只是一个简单的系统调用,所以老实说我不知道​​这里出了什么问题。

I have tested [my strlen] and know it works correctly.

恐怕不会。

mov rcx, 0xffffffff

您似乎认为这会用 -1 加载 rcx,但事实并非如此:0xffffffff-1 作为 32 位有符号整数,但是rcx 是一个 64 位寄存器。 (也许您是从某些 32 位代码复制的?)特别是,mov rcx, 0xffffffff 后跟 not rcx 不会导致 rcx 包含 0,而是 0xffffffff00000000 .因此,您的 strlen returns 是一个严重错误的值。

将此更改为 mov rcx, -1mov rcx, 0xffffffffffffffff