今天,小伙伴问我这样一个问题

mov  AX 0FFFEH

NEG AX

NOT AX

求指令执行完后,AX的值是多少。


其中出现了两个汇编指令NEG和NOT,下面我们来看一下这两个指令的计算方式


NEG是汇编指令中的求补指令,NEG指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数。求补运算也可以表达成:将操作数按位取反后加1;

格式:NEG OPR

执行的操作:(OPR)<-- —(OPR)

亦即把操作数按位求反后末位加1,因而执行的操作也可表示为:

(OPR)<-- 0FFFFH — (OPR) + 1

NEG指令对标志的影响与用零作减法的SUB指令一样。
取反指令是not,也就是“非”指令,取反就是把所有的“1”变成“0”,所有的“0”变成“1”


了解这两个指令之后,我们开始计算
NEG AX
原码1111 1111 1111 1110
补码0000 0000 0000 0010
NOT AX
原码0000 0000 0000 0010
取反1111 1111 1111 1101


即可得AX 的值最终为0FFFDH!!


这样想的话,就错了。


计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。在计算机系统中,数值一律用补码来表示和存储。


那么,对于0FFFDH这个数,在计算机里应该存储为补码!!

原码1111 1111 1111 1101
补码0000 0000 0000 0011

即3!!


那么问题来了,正确的结果是-3,我的计算是3,这里是为什么呢??


事实上,我们在求补码的时候,是将符号位不变,其余位按位变反再末尾加1.因此对于0FFFEH来说,NEG指令不会改变它的符号位,而NOT指令改变了它的符号位,此时结果是个负数。也就有了,最后AX为-3