Compilation of integer square roots

zhaozj2021-02-16  54

Squareroot - a approach by binary search (2)

1. Improved edition.

IT Improved In Several Ways. It expand INPUT LIMIT TO UP 65535. IT Uses A General "Divide" Function to Generalize The Call, Deleting All Those Jump for 8bit and 16bit Div. A Modest ImprovementAfter ALL.

2. Main function

All Other Function Remains The Same As Before Except Some Simplicity By Using "Divide" Function Call.

A. Divide

INPUT: by Stack Dividant, Divisor

Output: by Stack Remainder, Quotient

3. Problems & DouBTS

It took me almost half painful day to debug a simple dividing problem: when the divisor is a quite small number, say 2, and it seems the assembler try to use 8bit div instead of 16bit even though the ax is a 16bit number Because it. continually give "divide overflow" error. It bothered me so painfully! And in book it only gives a vaguely explanation that this will trigger a 00h interrupt which is a hardware interrupt, it suggested that some application programmer may want to adapt this kind of error But why? How can mas masm assembler make this kind of misteake?

Personally I am Still NOT 100% Sure About this is The Real Reason. However, i Called Chunming and He Hinted Me To Use Shift To Get Round of this Problem.

Another Doubt Is The Previous Program Size Is More Than 2k, And Now It Is Less 1k. It Seem the a Big Difference In Assembling The Two Program.

4. My Program

.Dosseg

.Model small

.Stack 200h

.DATA

MSG DB "this is true", "$"

MSG1 DB "this is quotient", "$"

MSG2 DB "this is remainder", "$"

.Code

Start:

Mov AX, @Data

MOV DS, AX

Call InputNumber

Call Squareroot

Call Changelineline

Call DisplayNumber

MOV AX, 4C00H

Int 21h

Pass Dividant, Divisor by Stack; Get Quotient from Stack

Quotient Proc

Push BP

MOV BP, SP

Push AX

MOV AX, [BP 6]

Push AX

MOV AX, [BP 4]

Push AX

Call Divide

POP AX; Useless Remainder, ONLY POP

POP AX; this is quotient

MOV [BP 6], AX

POP ax; the Original Ax Saved

POP BP

Ret 2

Quotient ENDP

Pass Dividant, Divisor by Stack

Get MoDulos from stack

Module PROC

Push BP

MOV BP, SP

Push AX

MOV AX, [BP 6]

Push AX

MOV AX, [BP 4]

Push AX

Call Divide

POP AX; this is remainder

MOV [BP 6], AX

Pop ax; useless quotient, but have to pop out to clear stack

POP ax; Original Ax Saved

POP BP

Ret 2

Module ENDP

Use Stack to Pass Dividant and Divisor

Use stack to return quotient and remainder

Divide Proc

Push BP

MOV BP, SP

Push AX

Push BX

Push dx

MOV AX, [BP 6]; The Dividant

MOV BX, [BP 4]; The Divisor

CMP BH, 0; Check if IT IS A 16bit Divide or Not

JNE Sixtendiv

CMP AH, 0

JNE Sixtendiv

EIGHTDIV:

Div BL; 8bit Div

MOV [BP 6], Al; The quotient;

MOV [BP 4], Ah; The Remainder

JMP Enddiv

Sixtendiv:

DIV BX; 16bit Div

MOV [BP 6], AX; the quotient

MOV [BP 4], DX; The Remainder

Enddiv:

POP DX

POP BX

POP AX

POP BP

RET

Divide ENDP

Changeline Proc

Push AX

Push dx

Mov Ah, 02

MOV DL, 0DH

Int 21h

MOV DL, 0AH

Int 21h

POP DX

POP AX

RET

Changeline ENDP

DISPLAYNumber Proc

Push bx

PUSH CX

Push dx

MOV BX, 10

MOV CX, 0

Begindivide:

CMP AX, 0

Je ShowResult

Push AX

Push bx

Call Divide

POP DX

POP AX

INC CX

Add dx, 30h

Push dx

JMP BegindiDe

ShowResult:

CMP CX, 0

Je EndDisplay

DisplayLoop:

MOV AH, 02H

POP DX

Int 21h

Loop DisplayLoop

EndDisplay:

POP DX

POP CX

POP BX

RET

DisplayNumber Endp

Squareroot ProCPUSH BX

PUSH CX

Push dx

Push Si

Push di

MOV CX, 00h

MOV BX, AX; BX Save the Number

CMP BX, 255; The Biggest root of 16bit

Jg Local1

MOV DI, BX

JMP Local2

Local1:

MOV Di, 255; this is upper bound of 16bit root

Local2:

MOV Si, 1; Lowbound

CheckResult:

MOV AX, SI

Add Ax, Di; AX Is The Sum of Low and High Bound

MOV DX, 02H

SHR AX, 1

MOV CX, AX

Mul ax; AX is the Square of CX

Compare:

CMP AX, BX

Je FindResult

CMP AX, BX

JB Smaller

Biggerr:

DEC CX

CMP CX, Si; Compare Lowbound

JL FindResult; Exceed Low Bound

MOV Di, CX; New High Bound

JMP next

Smaller:

INC CX

CMP CX, DI; Compare Highbound

JG FindResult; Exceed Low Bound

MOV Si, CX; New Low Bound

JMP next

NEXT:

JMP CheckResult

FindResult:

MOV AX, CX; Result Is Return In AX

POP DI

POP Si

POP DX

POP CX

POP BX

RET

Squareroot ENDP

INPUTNUMBER PROC

Push bx

PUSH CX

MOV AX, 00H

MOV BX, 00h

MOV CX, 00h

Check:

MOV AH, 01H

Int 21h

CMP Al, 0DH

Je endInput

MOV CL, Al; Save Input In CX

Mov AX, 10; Prepare Mul

Mul bx; Old Data In BX

SUB CX, 30H; cx to be nubmers

Add Ax, CX

MOV BX, AX; Save Data IN BX

JMP CHECK

EndInput:

MOV AX, BX; RETURN VALUE IN AX

POP CX

POP BX

RET

InputNumber Endp

End Start

End

Click here to download the execute file to have a try. Just run and key in a number smaller than 65535 ended by return and you get the approximate answer or exact answer, depending if the number has an integer root or not.

转载请注明原文地址:https://www.9cbs.com/read-23847.html

New Post(0)