当前位置: 代码迷 >> 汇编语言 >> 汇编move授命的疑惑
  详细解决方案

汇编move授命的疑惑

热度:1355   发布时间:2013-02-26 00:00:00.0
汇编move指令的疑惑
如下图所示:





源操作数是8位,目的操作数是16位,为什么这条传送指令是错误的呢?
难道不可以把源操作数的8位传送至目的操作数的低8位吗?
传送指令move具体是怎么进行处理的,为什么这样不行呢?
------解决方案--------------------------------------------------------
难道不可以,为什么这样不行,很好的斥责,所以,现在已经有了 movzx/movsx ax, bl 这样的指令了,虽然需要在程序的开头加上
; 这是 dos16 类程序的语句顺序;对 Win32 类的两语句必须顺序互换
.model small
.386

------解决方案--------------------------------------------------------
早期的指令可能没有,后来新模式下,新指令补充了缺失却又很实用的功能。
------解决方案--------------------------------------------------------
引用:
源操作数是8位,目的操作数是16位,为什么这条传送指令是错误的呢?
难道不可以把源操作数的8位传送至目的操作数的低8位吗?
传送指令move具体是怎么进行处理的,为什么这样不行呢?


LZ是从一般常识逻辑推理出mov ax,bl应该可行,其实并不那么简单。
因为寄存器中的数据既可以扮演带符号数的角色,又可以充当无符号数的角色。
(寄存器中的数据是死的,但是这个数据是作为带符号数看待还是作为无符号数看待,是由程序员决定的)
这是两个不同质的数。那么问题来了,比如当bl=11111111B时,将它赋给ax中的低八位,而ax的高八位为0时,
ax中的数据是00000000 11111111B,此时作为无符号数的值没变,也就是说,这是可行的;
但是如果bl用来表示的是带符号数,那么此时ax中的值与bl中的值是不同的。
所以这才有了movzx(传送数据时进行无符号扩展)和movsz(传递数据时进行有符号扩展)两条指令,供程序员选用。也就是说,如果bl中的11111111B是作为无符号数使用的,那么就选用movzx ax,bl 指令,指令执行后ax=0000000011111111B;如果是作为带符号数使用的,那么就选用movsx ax,bl指令,指令执行后ax=1111111111111111B.
仅供参考。

------解决方案--------------------------------------------------------
个人理解:
为什么MOV AX,BL 是错误的 ?假如CPU能自动把BL存入AX的低八位也就是AL,那么指令既然操作了AX,所以对AH高八位应该也有所改变.
那么如何改变的呢?莫不如填充0或者填充1了,那么AH应该也就是OOH或者FFH了.但是如果一但这样做,就可能改变了AX的符号,填充00H的话AX是个正数,填充FFH的话则是个负数,这样的话AX就完全没有意义了。
所以才有了MOVSX和MOVZX扩展传送指令 这样让程序员人为控制对高8位的填充 降低了程序的出错几率
------解决方案--------------------------------------------------------
使用字转化成字节的强制转化操作就正确了啊!MOV  BYTE PTR AX,BL
------解决方案--------------------------------------------------------
很简单的原因。AH和AL被设计用来独立使用:
mov ah,5
mov al,9
......    ;其它代码

如果
mov ax,bl

是允许的,那么,它将破坏AH中的内容。这对于那些希望用AH和AL分别保存不同内容的程序员来说,是一个可怕的情况。
------解决方案--------------------------------------------------------
【mov ax,bl】以前没有见过,真的很奇妙,学习了。
那么这个时候的mov是不是相当于movzx之类的功能呢?
------解决方案--------------------------------------------------------
CPU保存的数字符号是未知的ax,al也好.al如果等于-1,以char来说是-1,uchar来说是255,short的话是-1
ushort的话是65535,所以并不对应。。模棱两可的指令要避免。
  相关解决方案