【问题标题】:Substraction in assembly 8086 sets wrong flags汇编 8086 中的减法设置错误标志
【发布时间】:2015-04-10 11:31:06
【问题描述】:

我正在尝试做一个简单的数学计算。这是我的代码:

mov al, 128
sub al, -128

我需要知道子指令设置了哪些标志。我的计算是这样的。从sub+(- your number) 相同的想法开始。从 mov, al 128 开始,我们有这个:

这里是AL

128 = 0x80 = 1000 0000b

第二步,得到-128,也就是128的第二补码,也就是说:

 128 = 1000 0000b
-128 = 0111 1111b (1st complement) + 1 = 1000 0000b

所以...我们得到了相同的数字...现在我们必须将它们相加,因为这就是 sub 所做的,而不是真正的减法,而是与负数相加。

最终的结果是:

 1000 0000b +
 1000 0000b
 ----------
10000 0000b

这表明设置了以下标志:CF(有进位)、ZF(AL 中的 0)和 PF (从 d0 到 d3 的偶数个 1)。

如果我运行相同的代码,又是这样:

mov al, 128
sub al, -128

它只会设置ZFPF,但没有CF。问题是为什么? 我做错了什么?

【问题讨论】:

    标签: assembly binary cpu cpu-registers x86-16


    【解决方案1】:

    sub 与 +(- your number) 相同。

    对于 CPU 来说,这是不正确的。你的第一个数字和第二个数字相等。您作为人类了解第二个数字是负数这一事实对处理器没有影响。它将减去 2 个相等的数字,因此不需要借位。

    【讨论】:

    • ok,但是指令是sub al,-128,CPU怎么理解这个?他做的是负数,得到它基本上是相同的数字,只是 128 - 128 = 0,是吗?这意味着 sub 与 + (-number) 相同是不正确的,即使对于人类也是如此。
    • 是您的汇编程序将值 -128 转换为字节内容 0x10000000。之后 CPU 只看到 2 个相等的数字。您的基本想法确实适用于人类,因为我们不限于(在这种情况下)8 位数据。
    • @user1812076 CPU 正在做什么,你在问题中写下的内容。它将创建 2 的补码并添加数字。此操作将创建进位,但进位将被反转/取反,因为使用了减法操作码。您通过在示例中选择“128”使其变得更加复杂,这已经超出了 8 位中 2k 的范围:-128 =
    【解决方案2】:

    当您将两个数字相加时,进位标志会在发生最重要的进位时设置。但是,当您减去两个数字时,进位标志在 x86 中会反转。在您的示例中,您在进行减法时有进位,因此未设置 cf。

    cpu 这样做是因为在做减法时它使用进位标志作为借位标志。并且当您通过添加 2s 补码进行减法时,当发生最高有效位的进位时,您没有借位。反之亦然:没有执行 msb 意味着发生了借位,因此 x86 cpu 设置 cf = 1。起初听起来有点奇怪,但对于使用借位操作码进行减法非常有用,例如:sbb

    【讨论】:

    • 无需对真相投反对票。至少评论一下原因。 :P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    相关资源
    最近更新 更多