IDA学习笔记
+ -

x64 汇编中 MOV、MOVZX 和 MOVSX 的区别

2025-04-11 2 0

1. MOV 指令

功能

  • 通用的数据传送指令。
  • 操作数大小必须相同(例如 mov eax, ebx 合法,但 mov eax, bl 非法)。

高位处理

  • 如果操作寄存器的一部分(如 ALAX),直接复制低位数据,不修改高位
  • 高位可能残留旧值,导致不可预测的结果。

示例

mov  al, 0xFF    ; AL = 0xFF(8位)
mov  ax, al      ; AX = 0x??FF(假设 AX 原值为 0x1234,则结果为 0x12FF)

2. MOVZX 指令(零扩展)

功能

  • 将较小的无符号数传送到较大的目标,并用零填充高位
  • 适用于无符号数扩展(例如 0xFF 视为 255)。

规则

  • 源操作数 < 目标操作数(如 BYTEDWORD)。

示例

mov  bl, 0xFF    ; BL = 0xFF(8位)
movzx eax, bl    ; EAX = 0x000000FF(32位,高位清零)

3. MOVSX 指令(符号扩展)

功能

  • 将较小的有符号数传送到较大的目标,并用符号位填充高位
  • 适用于有符号数扩展(例如 0xFF 视为 -1)。

规则

  • 源操作数 < 目标操作数(如 BYTEDWORD)。

示例

mov  bl, 0xFF    ; BL = 0xFF(8位,有符号数 -1)
movsx eax, bl    ; EAX = 0xFFFFFFFF(32位,符号位填充)

对比总结

特性 MOV MOVZX MOVSX
操作数大小 必须相同 源 < 目标 源 < 目标
高位处理 不修改高位(可能残留旧值) 强制清零高位 用符号位填充高位
用途 通用数据传输 无符号数扩展 有符号数扩展
安全性 不安全(高位未定义) 安全(明确清零) 安全(明确符号扩展)

关键示例对比

场景:将 BYTE 类型的 0xFF 扩展到 DWORD

mov   bl, 0xFF     ; BL = 0xFF

; 使用 MOV(非法)
; mov eax, bl      ; 编译错误!

; 使用 MOVZX(无符号扩展)
movzx eax, bl      ; EAX = 0x000000FF(十进制 255)

; 使用 MOVSX(有符号扩展)
movsx eax, bl      ; EAX = 0xFFFFFFFF(十进制 -1)

何时使用?

  1. MOV

    • 源和目标操作数大小完全相同(例如 mov eax, ebx)。
  2. MOVZX

    • 扩展无符号数(例如图像像素值 0x800x00000080)。
  3. MOVSX

    • 扩展有符号数(例如 -10xFFFFFFFF)。

总结

  • MOV:基础数据传输,操作数大小需一致。
  • MOVZX:无符号数扩展,高位填零。
  • MOVSX:有符号数扩展,高位填符号位。

理解这些指令的区别,可避免数据截断或符号错误导致的隐蔽问题。


movsx和movsxd指令区别详解

根据一些资料,movsxd实际上是movsx的一种特定形式,专门处理32位到64位的扩展。在早期的x86架构中,movsx可以处理字节到字、字到双字,但在64位模式下,当需要将双字扩展到四字时,引入了movsxd指令。可能的原因是原有的movsx在操作数大小上可能不够明确,或者编码不同。

movsxd(Move with Sign-Extension Doubleword to Quadword)和 movsx(Move with Sign-Extension)是 x86/x86-64 指令集中用于符号扩展的指令,但它们的应用场景和操作数大小有所不同:


1. movsx 指令

  • 功能:将较小尺寸的源操作数(8/16/32 位)符号扩展到较大尺寸的目标操作数(16/32/64 位)。
  • 支持的扩展类型
    • 8 位 → 16/32/64 位(例如:movsx eax, byte [mem]
    • 16 位 → 32/64 位(例如:movsx rax, word [mem]
    • 32 位 → 64 位(仅在 x86-64 模式下,需用 movsxd,见下文)。
  • 适用模式
    • 32 位模式(扩展至 16/32 位)。
    • 64 位模式(扩展至 16/32/64 位,但 32→64 需用 movsxd)。

2. movsxd 指令

  • 功能:专用于在 x86-64 模式下将 32 位操作数符号扩展到 64 位。
  • 支持的扩展类型
    • 32 位 → 64 位(例如:movsxd rax, dword [mem])。
  • 适用模式
    • 仅限 64 位模式(x86-64)。

关键区别

特性 movsx movsxd
操作数大小 8→16/32/64,16→32/64,32→64(需显式) 仅 32→64
编码/助记符 通用符号扩展(多种组合) 专用于 32→64 扩展
64 位模式必需性 支持多种扩展,但 32→64 必须用 movsxd 唯一合法用于 32→64 的指令

示例

; 在 64 位模式下:
movsx  rax,  bl   ; 8位 → 64位(符号扩展)
movsx  eax,  bx   ; 16位 → 32位(符号扩展)
movsxd rax, ebx   ; 32位 → 64位(符号扩展)

; 错误用法:
; movsx rax, ebx  ; 不合法!必须用 movsxd

总结

  • movsx:通用符号扩展指令,支持多种源和目标大小组合。
  • movsxd:x86-64 专用指令,仅处理 32→64 位的符号扩展。
  • 在 64 位代码中,将 32 位值扩展到 64 位时,必须使用 movsxd

0 篇笔记 写笔记

x64 汇编中 MOV、MOVZXMOVSX 的区别
1. MOV 指令功能通用的数据传送指令。操作数大小必须相同(例如 mov eax, ebx 合法,但 mov eax, bl 非法)。高位处理如果操作寄存器的一部分(如 AL → AX),直接复制低位数据,不修改高位。高位可能残留旧值,导致不可预测的结果。示例mov al, 0xFF ......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!