2016-10-30 4 views
2

Я пишу 8-битную целочисленную функцию newton raphson в сборке MASM X8086-32bit, и я думаю, что застрял в бесконечном цикле. Редактор, который я должен использовать для класса, не отправляет ошибку для бесконечных циклов.Newtons Raphson Итерационные проблемы

В любом случае я не уверен, где моя проблема. Я только что начал MASM несколько недель назад, и я потерял любую помощь с бесконечным циклом. Мое начальное значение x определяется как 1.

Функция y = 1/2 (x + n/x) ===> x/2 + n/2x, где n - это число. и 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, вы только читать один символ и вы получите ascii code в AL.

Предположим, что введенный пользователем номер «A», который переводится на номер . Ни в коем случае никакое целое число не даст вам x^2 = 65, так что цикл будет циклическим навсегда.

Я предлагаю вам использовать это условие в качестве перерыва цикла. Результатом будет приближение (округленный до меньшего числа):

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

Имейте в виду, что вы работаете все с 8 битами, поэтому самое высокое решение будет: у = 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 

Любое нажатие между теми, сделает ваш код попасть в бесконечный цикл.

И наконечник для выход: добавить 48 к БЛ перед печатью, так что идет в ASCII числа :)

- Update 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 

Я предполагаю, что это должно быть что-то вроде:

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) 

Я использовал jb вместо jl, потому что я предполагаю, что только possitive номера. jl будет рассматривать 129 как отрицательное число, и, возможно, у нас будут проблемы.

- Update 3:

От Peter Cordes' ответа, подробно я не заметил (я читал div cl):

ДИВ сх; ax/cl ====> n/2x ===> p = ah и q = al. Это было бы правильно, если бы вы использовали div cl

+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 = al. Это было бы правильно, если бы вы использовали div cl, но DIV r/m16 принимает DX: AX как 32-битный дивиденд и производит результаты в AX = quotient, DX = остаток.

Посмотрите MUL и DIV in the manual.


Я настоятельно рекомендую выполнить однократное выполнение кода в отладчике. И/или останавливая его в отладчике после того, как он попадает в бесконечный цикл и один шаг оттуда во время просмотра регистров.

В нижней части тегов wiki есть несколько советов по использованию GDB для отладки asm. (например, использовать layout reg). Поскольку вы используете MASM, вы можете использовать Visual Studio, в которой встроен отладчик.

Не имеет значения, какой отладчик вы используете, но это важный инструмент для разработки asm.

+0

Ох. Впервые я прочитал об отладчике для asm. Я никогда не использовал его! xD О, мой! XD. Да, это важный инструмент. Хотел бы я подумать об этом давным-давно ... –

Смежные вопросы