【问题标题】:Integer overflow before add, but not after?整数在添加之前溢出,但不是之后?
【发布时间】:2017-01-22 05:42:28
【问题描述】:

我有两个变量要求用户输入:

number_1    DWORD   ?
number_2    DWORD   ?
sum         DWORD   ?

据我了解,DWORD 是一个无符号的 32 位整数数据,可以存储从 0 到 4,294,967,295 的整数。

但是,当我输入 2,147,483,648 或比有符号整数范围多 1 时,请使用以下代码:

call    readInt
mov     number_1, eax

我在命令提示符中收到<32-bit integer overflow> 警告。

但是,我可以将 2,147,483,647 输入到 number_1number_2add 并毫无问题地存储在 sum 中。当它显示时,它会显示 4,294,967,294,就像它应该显示的那样。

EAX 寄存器是否只能接受带符号的 32 位整数的最大值?

【问题讨论】:

  • eax 可以保存 32 位,无论数据被认为是有符号还是无符号。我不确定为什么会这样。
  • 您所说的“输入”究竟是什么意思,您是如何“接收”警告的,具体信息是什么?
  • 什么是readInt
  • 它一定是我们一直在使用的 Kip Irvine(我们的教科书作者)库中的一个函数——没有意识到它不是一个实际的汇编语言函数。这可能就是错误发生的地方。
  • 确实如此。我在Irvine32.inc 中找到了以下内容:“ReadInt PROTO ; 从控制台读取有符号十进制整数”。看起来它是为读取有符号整数而设计的。

标签: assembly masm


【解决方案1】:

EAX 寄存器可以接受任何可以用 32 位表示的值。

当您收到“32 位整数溢出”警告时,编写readInt 库函数的程序员决定将值视为有符号量。范围为 [-2GB,+2GB-1]。他检查并标记了错误。

当你自己编写以下代码时:

mov  eax, 2147483647
mov  ebx, 2147483647
add  eax, ebx

完全由您做出同样的决定。

对于必须执行add eax, ebx 指令的处理器来说,这无关紧要。结果 4294967294 非常适合可用的 32 位。即使真正的总和大于 4294967295,CPU 也会 - 毫无怨言 - 将结果的最低 32 位放入EAX 寄存器,并将第 33 位放入进位标志。

【讨论】:

    猜你喜欢
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2015-03-02
    相关资源
    最近更新 更多