繁体   English   中英

当结果对于寄存器来说太大时进位和溢出标志如何表现

[英]How does the carry and overflow flag behave when result is to big for register

以下示例应同时设置进位和溢出标志:

mov eax, -120
add al, 140

add al, 140会类似于下面的操作:

 10001000
+10001100
---------
= 100010100

所以结果有 9 位,而可以放入al的最大位数是 8。但我理解overflow-flag的方式只有在操作结果为“错误”时才设置。 例如,将一个正数与一个正数相加,但随后设置了sign-flag ,因此它会产生一个负数结果。

关于我到目前为止所做的例子中的进位标志,我只在我从一个较大的值中减去一个较小的值时才设置它。

所以我的问题归结为当操作的大小不能在寄存器中表示时进位和溢出标志的行为。

好的,您在这里遇到的问题是与计算机数据类型的工作方式和您正在做的事情不匹配。

通常,计算机可以处理(即添加)有符号数据类型或无符号数据类型——但要求计算机将有符号值添加到无符号值可能会有问题。

此处,-120 为负数,因此必须使用带符号的表示形式。

但是,140 本身不适合用 8 位有符号表示,所以在 8 位中,必须使用无符号表示。

硬件不支持这种组合——虽然加法会产生截断的结果,但如果您执行 8 位加法,硬件将不会在标志中为您提供有意义的信息。

(如果两个操作数都是 8 位有符号的,或者如果两个操作数都是 8 位无符号的,则 8 位加法的标志是有意义的,但是当混合两种数据类型时,它们并不总是有意义:特别是当涉及的值是足够大以至于高位被使用,就像 -120 signed 8 bit和 140 unsigned 8 bit的情况一样)

在这里获得正确结果的方法是将两个数字转换为更大的数据大小,以容纳两个数字(它将是一个带符号的数据类型,因此它可以容纳 -120,当然,转换方法会有所不同两个操作数,因为它们是不同的数据类型)。

因此,通过符号扩展将 -120 从 8 位转换为 16 位(或更大)。

并且,通过零扩展将 140 从 8 位转换为 16 位(或更大)。

然后你可以执行加法并得到一个带符号的结果,带有一个有意义的溢出标志。 当然,特定计算不会在 16 位中溢出——事实上,以两个 8 位值开头的 16 位加法不会溢出。

但是,如果您想将其恢复为 8 位,您可以检查它是否适合该大小和数据类型。 出于所有实际目的,在这种情况下,16 位结果的高 8 位包含有关低 8 位结果的感兴趣的溢出信息,而不是标志中的信息(溢出/进位)。

首先,确定要检查的 8 位数据类型:有符号或无符号。 有几种可行的方法,但一个简单的方法是将 16 位值截断为 8 位,然后将其从 8 扩展回 16,然后查看新扩展的 16 是否等于原始 16 位结果。

对于带符号的 8 位,您会将 16 位结果截断为 8 位,然后将其符号扩展回 16 位,然后与原始 16 位值进行比较。 如果不同,则该值不适合 8 位签名。

与无符号8位相同:将16位结果截断为8位并将其零扩展回16位以与原始值进行比较,如果比较不相等则它不适合8位无符号。

或者,您可以从 16 位原始结果中检查低 8 位值的符号位和高 8 位的值。 如果所有高位与低 8 位的符号位的位值相同,则 16 位结果将适合 8 位带符号而不会丢失。

对于无符号数,如果高 8 位为 0,则低 8 位将适合 8 位无符号数而不会丢失。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM