零扩展寄存器的一部分

Zero extending a part of register

我正在调试以下函数:

_print_func:
    mov rdx, 0xFFFFFFFFFFFFFFFF
    mov rax, 0x01
    mov rdi, 0x01
    mov rsi, str
    movzx dx, byte [str_len] ; <--- Here
    syscall
    ret

该函数是用

编译的
nasm -g -f elf64 2.asm

我遇到的问题是,在执行 movzx dx, byte [str_len] 行后,rdx 内容为:

rdx            0xffffffffffff000d       -65523

这是合理的。现在,将指令替换为:

_print_func:
    mov rdx, 0xFFFFFFFFFFFFFFFF
    mov rax, 0x01
    mov rdi, 0x01
    mov rsi, str
    movzx edx, byte [str_len] ; dx replaced with edx
    syscall
    ret

现在注册内容是这样的:

rdx            0xd      13

它看起来像移动到 32 位寄存器零以扩展它的 64 位高位部分。为什么会这样?

为什么我们在 movzx dx, byte [str_len] 时不对 eax 进行零扩展?

写入16位寄存器时,只有对应64位寄存器的这16位发生变化。但是,当您写入 32 位寄存器时,对应的 64 位寄存器的其他 32 位将被清除。这是在长模式(64 位模式)中引入的怪癖之一。