0

我目前正在尝试使用以下公式获得系列的总和:

((endNum * (endNum + 1) / 2) - ((startNum * (startNum - 1) / 2)

第一部分似乎工作正常,但是当我进入第二部分时,它给了我一些问题。

这是我正在做的事情:

; Formula and testing numbers
; -----------------------------
;((x (x+1) / 2) - ((y (y-1) /2)
;
; - x = 8
; - y = -2
; -----------------------------


ReadInt WORD[y]        ; read ending integer from user (8)
ReadInt WORD[x]        ; read starting integer from user (-2)

; ((x * (x + 1) / 2)

mov    AX, [x]  
mov    BX, [x]     
add    BX, 1
mul    BL
shr    AX, 1 
mov    [x], AX


; ((y * (y - 1) / 2)

mov    AX, [y]         ; -2
mov    BX, [y]         ; -2
sub    BX, 1           ; -3
mul    BL              ; <-- comes out with 1112 or some odd large number??
shr    AX, 1

sub    [x], AX

我不确定问题是什么,但是当它乘以-2和时似乎会发生-3

有人能指出我在哪里犯错吗?

编辑
意味着要尽快编辑它,因为我只处理无符号数字,我不得不更改我的算法以循环遍历每个数字并添加它们,而不是尝试使用公式。我最初想使用该公式,因为我相信它比循环更有效。

4

1 回答 1

4

我看到的几个问题:

  • 如果数字是有符号的,你必须使用IMUL而不是MUL它们的乘法。
  • 如果数字是有符号的,则不能SHR用作将它们除以 2 的幂的方法。至少它必须是SAR,不是SHR。即便如此,我实际上还是建议使用IDIV来获得对称截断。
  • 我不确切知道哪一部分是错误的,但是如果您的输入数字是 16 位,则执行 8-bit*8-bit=16-bit 乘法是错误的,因为您可能会截断输入值。同样,如果输入数字是 8 位,则将它们读取为 16 位通常是错误的,并且您可能会踩到内存位置而没有内存并崩溃。

而且您绝对必须获得一份 Intel 或 AMD x86 CPU 手册,描述指令的工作原理并阅读您正在使用的指令,并查看它们从哪里获取输入、如何处理它们以及输出到哪里。

于 2012-03-21T21:40:10.797 回答