【问题标题】:Zero extending a part of register [duplicate]零扩展寄存器的一部分[重复]
【发布时间】:2018-06-06 06:12:24
【问题描述】:

我正在调试以下函数:

_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

【问题讨论】:

  • 写入 32 位 GPR 会将相应 64 位 GPR 的上半部分归零
  • @harold 非常有趣。我在调试器中注意到了这一点。但那是什么原因呢?

标签: linux assembly x86-64 cpu-registers


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多