-
-
[旧帖]
[原创]研究16位汇编NEG求补指令
0.00雪花
-
发表于:
2009-2-1 16:39
18952
-
[旧帖] [原创]研究16位汇编NEG求补指令
0.00雪花
【文章标题】: 研究16位汇编NEG求补指令
【文章作者】: hzmslx
我是个菜鸟··学16位汇编时看到别人写的3行代码对一个32位数求补,百思不得其解为什么(本人脑袋反应慢··),想了很长时间,终于想出了为什么,对其进行举例子论证,发现真的是这样
看过美丽的破船的帖子,觉得写出来对自己的理解也有好处
所以把我思考过程写出来,说不定对像我这样的菜鸟又一定帮助
NEG是求补指令,把他之后的操作数求补(先求反再加1,地球人都知道)
本指令影响标志位CF、OF、SF、PF、ZF及AF.
有一个32位的数
高16位存储在Dx
低16位存储在Ax,写出指令对其求反
NEG DX
NEG AX
SBB DX,0
NEG后面的操作数,如果值不为0,CF就总为1
让我死都不明白的是为什么NEG指令要这样设置,为什么如果NEG后面操作数不为0就让那个CF等于1?当操作数为0时,取反加1还是0进了一位,当操作数为0的时候CF才应该等于1啊,而其他数求补都没有进位,为什么CF就等于1了呢?
后来发现在这道题中就可以看出这样设置非常正确
我们来举个例子,假如DX和Ax中的数都不为0,
设Dx= 0000 0000 0000 1000
AX= 0000 0000 0000 0010
这个数完整的是
0000 0000 0000 1000 0000 0000 0000 0010
求补
1111 1111 1111 0111 1111 1111 1111 1110
分别求反两个数
则DX=1111 1111 1111 1000
AX=1111 1111 1111 1101
这个数完整写出来
1111 1111 1111 1000 1111 1111 1111 1101
则DX多加了一个1
NEG指令设置的是后面的操作数只要不为0则CF为1
所以在SBB(sub with borrow)的时候,把CF减了进去
我们再来看当其中DX和AX其中一个为0的时候
我们就设DX= 0000 0000 0000 1000
AX=0000 0000 0000 0000 0000
NEG DX
则dx=1111 1111 1111 1000
NEG AX
AX仍然为0,且CF=0
SBB DX,0
DX<- DX-0-CF
DX<- DX-0-0
DX的值不变
得到1111 1111 1111 1000 0000 0000 0000 0000
我们来求补0000 0000 0000 1000 0000 0000 0000 0000 这个数
先求反1111 1111 1111 0111 1111 1111 1111 1111
加1
1111 1111 1111 1000 0000 0000 0000 0000
得出的结果是正确的
其实现在看这个问题不是很难,不过我们知道了为什么NEG指令对后面操作数如果不是0,CF就等于1,和平常的无符号数溢出有点不一样
在高手看来,我这个帖子是小儿戏,但对初学者能灵活掌握这个指令我觉得是有帮助的(先自恋下 )
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课