2016-10-30 6 views
2

私は8bit整数のnewton raphson関数をMASM X8086-32bitアセンブリに記述していますが、無限ループに陥っていると思います。クラスのために使用しなければならないエディタは、無限ループのエラーを送信しません。Newtons Raphson反復の問題

とにかく私の問題がどこにあるかわかりません。私は数週間前にMASMを始めたばかりで、無限ループの助けを失ってしまったのは分かります。私の最初のx値は1と定義されます。

関数は、y = 1/2(x + n/x)===> x/2 + n/2xです。 xは初期化された値、次に前の反復のyの値です。

mov ah, 09h 
    lea dx, prompt ;Prompt User 
    int 21h 

    mov ah, 01h 
    int 21h   ;User input 
    sub al, 30h 

    mov bh, al 
    mov bl, x  ;Loading for loop 
    mov al, x 

    iteration: 
       mul bl; al*bl = al 

       mov dl, al ; storing x^2 

       add al, 01h ; (x+1)^2 
       mul al 

       cmp bh, dl 
       jge doneCheck ; bh - dl ====> n- x^2 => 0 
       doneCheck: 
       cmp bh, al; bh-al = ? ====>n - (x+1)^2 == -int 
       jl done 

       mov al, 02h; loading 2 in ah 
       mul bl ; bl*al = 2(bl) = 2x = al 

       shr bl, 1 ; x/2 = bl 

       mov cl, al ; storing 2x in cl 
       mov ah, 0 ; clearing ah 
       mov ch, 0; clearing ch 
       mov al, bh ; moving n into ax for division prep 
       div cx ; ax/cl ====> n/2x ===> p =ah and q = al 

       add bl, ah ;so this is finally 1/2(x+(n/x)) === (x/2+n/2x) y the new value y is now stored in bl for next loop 
       mov al, bl ; for next loop 
       jmp iteration 

    done: 

    mov dl, bl; print square root 
    mov ah, 02h 
    int 21h 

答えて

4

これは:

shl bl, 1 ; x/2 = bl 

は?:

shr bl,1 

すべきではない - 更新:

をそしてあなたの質問について:

BH = Number to find sqrt. When x^2 == BH then x is the sqrt(n) 
AL and BL = y value of the last iteration 

とあなたは:

mul bl  ; AL*BH => AX 
cmp bh, al ; BH == AL? or with names: n == x^2 ? 

なぜ無限ループ?

あなたはAH=01h+int 21hとの入力を取ると、あなただけの1文字を読んで、あなたはALでascii codeを取得します。

ユーザー入力番号が「」に変換された「A」であるとします。決して整数はあなたにx^2 = 65を与えないので、ループは永遠にループします。

この条件をループブレイクとして使用することをお勧めします。結果は(下の数に丸め)近似値になります。

(n >= x^2) && (n < (x+1)^2) 

ベア心​​の中であなたが8ビットで全てを操作しているので、最高のソリューションは、次のようになります。この時、Y = 15ルック:

1^2 = 1 
2^2 = 4 
3^2 = 9 
4^2 = 16 
5^2 = 25 
6^2 = 36 
7^2 = 49 
8^2 = 64 
... 
15^2 = 225 

ものは、あなたが(私の提案なし)あなたのコードでSQRTを計算することができのみ番号です。

だから、入力としてのみ、以下のキーを押すことができます:

$ = number 36 
1 = number 49 
@ = number 64 
Q = number 81 
d = number 100 
y = number 121 

それらの間の任意のキー入力をあなたのコードは無限ループに入るようになります。

そして出力のためのヒント:それはASCII番号:)

に行くので、それを印刷する前にBLに48を追加 - アップデート2:あなたのコードから

私は、このエラーが見つかりました:

add al, 01h ; (x+1)^2 ; AL = x^2, therefore you are doing (x^2)+1 
mul al 

、ここで実行フローは、常にすべての行を実行します:

cmp bh, dl 
jge doneCheck ; bh >= dl? ====> n >= x^2 ? 
doneCheck: 
cmp bh, al; bh-al = ? ====>n - (x+1)^2 == -int 
jl done 
01私はpossitive番号を想定しているため、私は jb代わりの jlを使用

cmp bh, dl  ; n vs x^2 
    jb notSolution ; BH < DL? ====> if n < x^2 continue with next NR step 
    cmp bh, al  ; here, n >= x^2 
    jb done  ; BH < AL ? ====> if n < (x+1)^2 we found a solution 

notSolution:  ; n is not in [ x^2 , (x+1)^2) 

は、私はそれが何かのようにする必要がありますね。 jlは129を負数として扱い、おそらく問題になるでしょう。

- アップデート3:

Peter Cordes'答え、私は(私はdiv clを読む)気づかなかったディテールから:

のdiv CX。 ax/cl ====> n/2x ===> p = ahとq = al。それはあなたがdivを使用した場合、正しいでしょう。

+0

ありがとうございました。あなたの右が、無限のループを修正しなかったので、それを変更しました。 – TheLiquor

+0

私はあなたのコードを詳しく見て、なぜそれが永遠にループするのかを知りました。 –

+0

答えを –

2

MULとDIVのオペランドがそれぞれdouble the width of the other twoであることを正しく理解しているかどうかはわかりません。

それらのライン上のあなたの意見は間違っている:

  • mul bl; al*bl = al:いいえ、AX = AL*BL
  • div cx ; ax/cl ====> n/2x ===> p =ah and q = aldiv clを使用した場合は正しいでしょうが、DIV r/m16はDX:AXを32ビットの被除数とし、AX =商、DX =剰余の結果を生成します。

ルックアップMULおよびDIV in the manual


デバッガでコードをシングルステップ実行することを強くお勧めします。そして/または無限ループに入った後でデバッガで停止し、レジスタを見ながらそこからシングルステップを実行します。

タグwikiの末尾には、GDBを使用してasmをデバッグするためのヒントがいくつかあります。 (例:layout regを使用)。 MASMを使用しているので、デバッガが組み込まれているVisual Studioを使用している可能性があります。

使用するデバッガは重要ではありませんが、asmを開発するための必須ツールです。

+0

ああ私は初めてasmのデバッガを読んだ。私は一度も使ったことがない! xDああ、私! xD。ええ、それは不可欠なツールです。私はずっと前にそれについて考えて欲しいです... –

関連する問題