StartingGroovy
StartingGroovy

Reputation: 2860

What is wrong with my algorithm when calculating the sum of a series (x86 Assembly)?

I'm currently trying to get the sum of a series using the following formula:

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

The first part seems to work correctly, however when I get to the second part, it gives me issues.

Here is what I'm doing:

; 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

I'm not sure what the issue is, but it seems to happen when it is multiplying -2 and -3.

Is someone able to point out where I'm making the mistake?

EDIT
Meant to edit this sooner, since I'm only dealing with unsigned numbers, I had to change my algorithm to loop through each number and add them rather than trying to use the formula. I originally wanted to use the formula since I believe it would be more efficient than looping.

Upvotes: 0

Views: 173

Answers (1)

Alexey Frunze
Alexey Frunze

Reputation: 62086

A few problems I'm seeing:

  • If the numbers are signed, you have to use IMUL instead of MUL for their multiplication.
  • If the numbers are signed, you can't use SHR as a way to divide them by a power of two. At the very least it must be SAR, not SHR. And even then I'd actually advise to use IDIV to get symmetric truncation.
  • I don't know exactly which part is wrong, but if your input numbers are 16-bit, doing 8-bit*8-bit=16-bit multiplication is wrong as you're likely truncating the input values. Likewise, if the input numbers are 8-bit reading them as 16-bit is generally wrong as well as you might step on a memory location without memory and crash.

And you absolutely must get an Intel or AMD x86 CPU manual describing how instructions work and read about the instructions you're using and see where they take their inputs from, what do with them and where the outputs go.

Upvotes: 4

Related Questions