问题描述
以下代码打印值:-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
而 145c416
是 83,396
。
(1) 二进制补码的一大特点是加减位的操作方式与相同大小的无符号值完全相同。