今天下午看一个反汇编的代码,并试图跟源代码对上号。

下面的语句组合让我非常费解,花了好久才弄清楚。贴出来,供大家参考。

        neg     r
        sbb     r, r
        and     r, (val1 - val2)
        add     r, val2

 

neg r 指令的结果是设置Carry Flag, 也就是借位的标志位. 因为neg r的操作语义是0 - r, 零减去任何非零的数,都会产生"借位"的. 当然这里r寄存器中的值也被改掉了,不过没关系, 反正它都要被稍后的指令再改掉的.

 

紧接着,sbb r, r 指令设置r为零或者-1. 因为语义为用一个值去减掉它自身, 结果当然是零啰. 但是,这样做会把carry flag一起给减掉的, 该指令的公式是

r – r – CF –>  r 

所以,如果r最开始就是0, 那么sbb r, r的结果是将r设置为0. 如果不是零,那么结果是0-CF = 0-1 = –1 = FFFFFFFF

 

第三个操作是一个mask的操作, 如果r是0的话,任何数与0做与操作都是0. 如果r不是0, 那么任何数与FFFFFFFF做与操作,都会留下那个值.

也就是说, 如果r是0, 那么r为0; 如果不为0, 那么结果为val1 – val2.

 

第四个操作是把val2加到r上,结合之前的结论, 我们可以得出

如果r是0, 那么结果等于val2, 如果r不是0, 那么结果等于val1 – val2 + val2, 结果为val1.

 

总结一下,整个四句指令一起的意思就是, 如果r为0, 那么r中的值为val2, 如果r不为0, 那么r中的值会是val1. 即

r ? val1 : val2