算术运算未产生预期结果

问题描述

以下代码打印值:-83396
在这里做的计算是Z2 = (var3 – var2 - 1000) + (var1 – 500)
所以 Z2 = (FFFF0000h - 4000h- 1000) + (24 - 500)
我不确定结果是-83396?我只是存储值
在寄存器中用于 var2,用于计算的 var3

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword

INCLUDE Irvine32.inc

.data
var1    byte    24
var2    word    4000h
var3    dword   0FFFF0000h
Z1    dword    ?
Z2    dword    ?
Z3    dword    ?
Z4    dword    ?

.code
main proc
xor eax,eax
xor ebx,ebx

mov eax,var3
movzx ebx,var2
sub eax,ebx
xor ebx,ebx
sub eax,1000

xor ebx,ebx
movzx ebx,var1
sub ebx,500
add eax,ebx
mov Z2,eax
call writeint




clc
invoke ExitProcess,0
main endp
end main

解决方法

这是因为您的结果值被视为二进制补码数。

作为二进制补码的值 ffff000016-65,536。减去 400016 (16,384),然后减去另一个 1,000。然后加上24并减去500。这为您提供了-83,396正是您所看到的。

但是,即使它们一路上都是无符号的,将 result 视为有符号的(1) 会给你同样的问题(这些都是十六进制数字除了括号中的那些):

  ffff0000
-     4000  (16,384)
==========
  fffec000
-      3e8  (1,000)
==========
  fffebc18
+       18  (24)
==========
  fffebc30
-      1f4  (500)
==========
  fffeba3c

在 32 位 2 的补码中,最终值将是(所有十六进制):

  - (100000000 - fffeba3c)
= - 145c4

145c41683,396


(1) 二进制补码的一大特点是加减位的操作方式与相同大小的无符号值完全相同。