一个懒人专用文章归档神器,如果你不能成为压路机的一部分,那么你就只能成为道路的一部分 Bala~bala~

MOVSX/MOVZX的解释

汇编 懒人 1608℃ 0评论

MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
符号扩展的意思是,当用跟多的内存存储某一个有符号数时,由于符号位位于该数的第一位,扩展之后,符号位仍然需要位于第一位,所以,当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0.
比如一个用一个8位二进制表示-1,则是10000001
如果把这个书用16位二进制表示时,则为11111111 10000001 高位全都是1,这个叫做符号扩展,主要用于对其操作数。
零扩展就是全补零。不论其符号位是多少,高8位全都补0.
最后一句是r/m8后做符号扩展为16位后,送到reg16

——————————————————-

movsx:
汇编语言数据传送指令MOV的变体。带符号扩展,并传送。

例如:
1.MOV BL,80H
MOVSX AX,BL
运行完以上汇编语句之后,AX的值为FF80H。由于BL为80H=1000 0000,最高位也即符号位为1,在进行带符号扩展时,其扩展的高8位均为1,故赋值AX为1111 1111 1000 0000,即AX=FF80H。
2.mov CL, 50H
MOVSX AX, CL
50H=0101 0000,最高位为0,则AX为0000 0000 0101 0000
结果AX = 50H

movzx:
movzx一般用于将较小值拷贝到较大值中。 这个指令是非常有用的,大家以后学程序设计的话,如果需要处理windows中的消息,例如WM_COMMAND消息,这个消息结构的wParam的高16位是通知码,而低16位则是命令id。有时候需要判断命令id的话,则需要将这个wparam的低16位扩展成32位的,并且其余位用0填充。这就用到了movzx。

 

——————————————————-

比如
MOVSX EAX, BYTE PTR [00401000]

MOVZX EAX, BYTE PTR [00401000]
C语言中应该如何表达啊?
比如定义一个全局变量
BYTE bt = 101;
DWORD dw;
应该如何把bt赋值到dw中. 并且功能与MOVSX/MOVZX相同? 谢谢!

 

——————————————————-

你只要读懂程序的行为,或者说功能。

汇编语言与c语言的语言构件不同,并不是一定能转成完全等价的C语言的代码的。

对于以上代码,可以这样理解:

movsx    ====>    dw = (DWORD) ( (signed  char)    (bt) )
movzx    ====>    dw = (DWORD) ( (unsigned char)  (bt) )

movzx是把高位全部用0填充,而movsx是把原来数的最高位扩展成超出的位。

对于bt=101,也就是0x65,八位二进制是“01100101”,因为它的最高位是0,因此这两种情况,dw都等于0x00000065

换一个,比如bt=247,也就是0xF7,八位二进制是“11111110”它的最高位是1,那么movsx后,dw等于0xfffffff7,而movzx后,dw等于0x000000f7

转载请注明:懒人档案室 » MOVSX/MOVZX的解释

喜欢 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址