汇编语言MOVZX和MOVSX指令

尽管 MOV 指令不能直接将较小的操作数复制到较大的操作数中,但是程序员可以想办法解决这个问题。假设要将 count(无符号,16 位)传送到 ECX(32 位),可以先将 ECX 设置为 0,然后将 count 传送到 CX:

  .data  count WORD 1  .code  mov ecx,0  mov cx,count

如果对一个有符号整数 -16 进行同样的操作会发生什么呢?

  .data  signedVal SWORD -16      ; FFF0h (-16)  .code  mov ecx,0  mov cx,signedVal         ; ECX = 0000FFF0h(+ 65,52 0)

ECX 中的值(+65 520)与 -16 完全不同。但是,如果先将 ECX 设置为 FFFFFFFFh,然后再把 signedVal 复制到 CX,那么最后的值就是完全正确的:

  mov ecx,0FFFFFFFFh  mov cx,signedVal    ;ECX = FFFFFFF0h(-16)

本例的有效结果是用源操作数的最高位(1)来填充目的操作数 ECX 的高 16 位,这种技术称为符号扩展(sign extension)。当然,不能总是假设源操作数的最高位是 1。幸运的是,Intel 的工程师在设计指令集时已经预见到了这个问题,因此,设置了 MOVZX 和 MOVSX 指令来分别处理无符号整数和有符号整数。

MOVZX 指令

MOVZX 指令(进行全零扩展并传送)将源操作数复制到目的操作数,并把目的操作数 0 扩展到 16 位或 32 位。这条指令只用于无符号整数,有三种不同的形式:

MOVZX reg32,reg/mem8
MOVZX reg32,reg/mem16
MOVZX reg16,reg/mem8

在三种形式中,第一个操作数(寄存器)是目的操作数,第二个操作数是源操作数。注意,源操作数不能是常数。下例将二进制数 1000 1111 进行全零扩展并传送到 AX:

  .data  byteVal BYTE 10001111b  .code  movzx ax,byteVal ;AX = 0000000010001111b

下图展示了如何将源操作数进行全零扩展,并送入 16 位目的操作数。

汇编语言MOVZX和MOVSX指令

下面例子的操作数是各种大小的寄存器:

扫描二维码关注公众号,回复: 6585891 查看本文章
  mov bx, 0A69Bh  movzx eax, bx     ;EAX = 0000A69Bh  movzx edx, bl     ;EDX = 0000009Bh  movzx cx, bl     ;CX = 009Bh

下面例子的源操作数是内存操作数,执行结果是一样的:

  .data  byte1 BYTE  9Bh  word1 WORD 0A69Bh  .code  movzx eax, word1 ;EAX = 0000A69Bh  movzx edx, byte1 ;EDX = 0000009Bh  movzx ex, byte1     ;CX = 009Bh

MOVSX 指令

MOVSX 指令(进行符号扩展并传送)将源操作数内容复制到目的操作数,并把目的操作数符号扩展到 16 位或 32 位。这条指令只用于有符号整数,有三种不同的形式:

MOVSX reg32, reg/mem8
MOVSX reg32, reg/mem16
MOVSX reg16, reg/mem8

操作数进行符号扩展时,在目的操作数的全部扩展位上重复(复制)长度较小操作数的最高位。下面的例子是将二进制数 1000 1111b 进行符号扩展并传送到 AX:

  .data  byteVal BYTE 10001111b  .code  movsx ax,byteVal      ;AX = 1111111110001111b

如下图所示,复制最低 8 位,同时,将源操作数的最高位复制到目的操作数高 8 位的每一位上。

汇编语言MOVZX和MOVSX指令

如果一个十六进制常数的最大有效数字大于 7,那么它的最高位等于 1。如下例所示,传送到 BX 的十六进制数值为 A69B,因此,数字“A”就意味着最高位是 1。(A69B 前面的 0 是一种方便的表示法,用于防止汇编器将常数误认为标识符。)

4.1 操作数类型
4.2 MOV指令
4.3 MOVZX和MOVSX指令
4.4 LAHF和SAHF指令
4.5 XCHG指令
4.6 直接偏移量操作数
4.7 汇编语言数据传送示例
4.8 加法和减法详解
4.9 OFFSET运算符
4.10 ALIGN伪指令
4.11 PTR运算符
4.12 TYPE运算符
4.13 LENGTHOF运算符
4.14 LABEL伪指令
4.15 间接寻址
4.16 JMP和LOOP指令
4.17 64位MOV指令
4.18 64位加法和减法

猜你喜欢

转载自blog.csdn.net/Javaxuxuexi/article/details/93401413