这个问题在这里已有答案:
我正在调试以下功能:
_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]
进行零扩展?
写入16位寄存器时,只更改相应64位寄存器的这16位。但是,当您写入32位寄存器时,相应的64位寄存器的另一个32位被清零。这是在长模式(64位模式)中引入的怪癖之一。