gpt4 book ai didi

assembly - ASM 如何知道算术运算是有符号的还是无符号的?

转载 作者:行者123 更新时间:2023-12-04 16:42:40 25 4
gpt4 key购买 nike

我正在使用 MASM 14.0 进行组装,但我对以下代码的输出感到困惑。

TITLE Exercise 4 from chapter 4

; Author : Saad Ahmed

INCLUDE Irvine32.inc

.code
main PROC

mov eax, 0
mov al, 255
add al, 1
call DumpRegs ; Display registers

mov al, 127
add al, 1
call DumpRegs ; Display registers

exit
main ENDP
END main

两种算术运算都是在无符号整数 255 和 127 上完成的。

但是,CPU 将第一个操作 255 视为无符号整数并设置进位标志,当您将 1 添加到无符号 255 时会发生这种情况。

完整的状态标志为 CF=1 SF=0 ZF=1 OF=0 AF=1 PF=1,eax 为 0

但是,第二个操作将 127 视为一个有符号整数,因为它正在设置溢出标志,如果将 1 添加到 +127 就会发生这种情况。

完整的状态标志为 CF=0 SF=1 ZF=0 OF=1 AF=1 PF=0,eax 为 0。

问题是 CPU 如何决定第一个操作是在无符号 255 上完成的,而另一个是在有符号整数上完成的?

最佳答案

对于使用二进制补码的加法(和减法),就逻辑而言,没有有符号或无符号的概念。乘除,是的,由于需要符号扩展。

取从 000 到 111 的所有 3 位数字组合,并将它们添加到所有 3 位数字组合中,这是可以管理的。如果您愿意,可以编写程序或手动完成。或者只是做极端情况。对于每个操作数,使用二进制补码检查每个操作数是有符号还是无符号。您会注意到相同的添加有效。 1 + 110 = 111。现在是 1 + (-2) = -1 还是 1 + 6 = 7。两者都有效。

进位标志是 UNSIGNED 溢出,V 标志是 SIGNED 溢出,这就是我们计算两者的原因,以便知道这些是有符号数还是无符号数的用户可以选择正确的条件。这就是为什么你在大于或等于时有符号跳转与大于或等于无符号跳转的原因。

使这一切奏效的是二元互补的美丽。

乘(和除)是不同的,因为你必须对扩展进行符号化。二进制乘法有一个很好的特点,如果你考虑一下

   abcd
* 0011
=======
abcd
abcd
0000
0000
=======

一位是 1 或 0,因此您将顶部数字乘以 1 或 0,您可以将其添加或不添加。但也要注意,你很快就会溢出。我们从小学就知道 n^x * n^y = n^(x+y)。如果您的寄存器是 Z 位宽,则操作数的最高有效位位置在添加时不能大于 Z,否则会溢出。四位 0010*0010 应该可以工作,但 0010*1000 会溢出。正确的方法是结果是操作数的两倍宽。

那么如果我想乘以 1111 * 0010 呢?

那基本上是
    0000
1111
0000
+0000
========
0011110

等等,是 15 (0b1111) 还是 -1 (0b1111)? -1 * 2 = -2 这不是我们上面得到的,我们做了一个无符号乘法来做一个有符号乘法我们必须符号扩展并从左边扔掉位
 11..1111
*00..0010
=========
00000000
1111111
000000
00000
=========
11111110

这给出了两个四位寄存器 1111 和 0010 的有符号乘法的正确答案。

加法有效,因为您只关心一列。每列都有一个进位,两个操作数一个结果和一个进位。然后您可以根据需要将其级联。对于单个位,您有 0 和 1。零只是零,而不是正负零,1 可以是 +1 或 -1。我发现处理多于一列的组合更容易,但可以做到。另外,进位是 0,所以我不需要表示它操作数 a、操作数 b、进位和结果
00 00  0 + 0 = 0
01 01 0 + 1 = 1; 0 + (-1) = -1
10 01 1 + 0 = 1; (-1) + 0 = -1
11 10 1 + 1 = 0 unsigned overflow. -1 + 1 = 0, 1 + -1 = 0, -1 + -1 = 0 signed overflow

从技术上讲,在最后一种情况下,所有有符号的都是有符号溢出,这是您处理任意位数的特殊情况,取三位寄存器 100 + 100 = 000 + 进位 1 是 4 + 4 = 0 无符号溢出还是带有符号溢出的 -4 + -4 = 0?这就是为什么当您使用一些位并通过组合抛出 1 和所有零的问题案例时更容易看到的原因。

有符号溢出是指最高有效列的进位与进位不匹配。无符号溢出是当 msbit 的进位为 1 时。

逻辑中的减法是通过加法完成的,我们从小学就知道 a - b = a + (-b) 并且我们从编程类(class)中知道使用二进制补码取负数,您可以反转并加一。嗯,效果很好,我们可以反转第二个操作数并反转 lsbit 的进位,使其为 1 或反转并加 1。这就是它的工作原理。从 alu 出来的进位有时会反转以表示借位。您必须查看标志组合才能弄清楚这一点,有些处理器会反转执行某些不执行的操作。有时可以通过借用减法判断您的 ISA 是否有该指令。

我知道 TL:DR...涵盖的比你问的要多。

关于assembly - ASM 如何知道算术运算是有符号的还是无符号的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38194478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com