零扩展寄存器的一部分

时间:2017-12-24 13:31:11

标签: linux assembly x86-64 cpu-registers

我正在调试以下功能:

_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位高部分。为什么会这样?

为什么我们在eax时没有将movzx dx, byte [str_len]归零?

1 个答案:

答案 0 :(得分:2)

当写入16位寄存器时,只更改相应64位寄存器的这16位。但是,当您写入32位寄存器时,相应的64位寄存器的另一个32位被清零。这是长模式(64位模式)中引入的怪癖之一。