0

現在、次の式を使用してシリーズの合計を取得しようとしています。

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

最初の部分は正しく動作しているように見えますが、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.

誰かが私が間違いを犯している場所を指摘できますか?

EDIT
これをもっと早く編集することを意味しました。私は符号なしの数字しか扱っていないので、数式を使用するのではなく、各数字をループして追加するようにアルゴリズムを変更する必要がありました。ループよりも効率的であると信じているので、私はもともとこの式を使用したいと考えていました。

4

1 に答える 1

4

私が見ているいくつかの問題:

  • 数字が署名されている場合は、乗算IMULの代わりに使用する必要があります。MUL
  • SHR数字が署名されている場合、それらを 2 の累乗で割る方法として使用することはできません。少なくとも、そうでなければなりSARませんSHRIDIVそれでも、対称的な切り捨てを行うために使用することをお勧めします。
  • どの部分が間違っているのか正確にはわかりませんが、入力数値が16ビットの場合、入力値を切り捨てる可能性があるため、8ビット* 8ビット= 16ビットの乗算は間違っています。同様に、入力数値が 8 ビットの場合、それらを 16 ビットとして読み取るのは一般的に間違っています。また、メモリのないメモリ位置を踏んでクラッシュする可能性があります。

また、命令がどのように機能するかを説明した Intel または AMD x86 CPU のマニュアルを絶対に入手し、使用している命令について読んで、命令がどこから入力を取得し、何を行い、出力がどこに行くのかを確認する必要があります。

于 2012-03-21T21:40:10.797 に答える