整数平方根的汇编求法

原创 2003年04月01日 09:02:00

 SQUAREROOT--A APPROACH BY BINARY SEARCH(2)

1。Improved edition.

It improved in several ways.  It expand input limit to up to 65535. It uses a general "divide" function to generalize the call, deleting all those jump for 8bit and 16bit div. A modest improvement after 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 MASM assembler make this kind of mistake?

    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 seems there is 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 CHANGELINE
	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 SIXTEENDIV
	CMP AH, 0
	JNE SIXTEENDIV
EIGHTDIV:
	DIV BL; 8BIT DIV
	MOV [BP+6], AL; THE QUOTIENT;
	MOV [BP+4], AH; THE REMAINDER
	JMP ENDDIV
SIXTEENDIV:
	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 BEGINDIVIDE

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  PROC
	PUSH 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. 

汇编语言: 用减奇数次数的方法,求一个数的近似平方根,这个平方根是一个整数。

用减奇数次数的方法,求一个数的近似平方根,这个平方根是一个整数。如求17的平 方根,可以用17相继减去奇数1、3、5、7、…,当结果为负数时停止,即: 17-1-3-5-7-9<0 可以看出,17 在...
  • Shuphen
  • Shuphen
  • 2017年06月07日 20:45
  • 538

整数平方根整数近似解的求法

整数n求其整数近似平方根r    ,  使得 r22 输入范围是0---10^32超过这个范围的可以用同样的算法,使用高精度计算求整数解.   输入格式 1 2 3 4 输出 1 1 1 2     ...
  • wengzhong
  • wengzhong
  • 2004年07月06日 23:04
  • 1186

卡马克快速平方根(平方根倒数)算法(转)

日前在书上看到一段使用多项式逼近计算平方根的代码,至今都没搞明白作者是怎样推算出那个公式的。但在尝试解决问题的过程中,学到了不少东西,于是便有了这篇心得,写出来和大家共享。其中有错漏的地方,还请大家多...
  • xuexiaokkk
  • xuexiaokkk
  • 2015年11月03日 13:07
  • 491

关于平方根的最大下取整数的java代码解决方案

package com.java; import java.util.Scanner; import org.junit.Test; public class Demo1 {  @Test ...
  • futurech
  • futurech
  • 2017年09月07日 15:58
  • 234

整数平方根的计算(一)

摘要:本文主要讨论使用求级数和的方法来计算小整数的平方根,在内存空间允许的情况下,本算法可将整数的平方根精确到任意精度。本算法具有逻辑简单,且无需使用大数库等优点。另外,本算法也相对高效,在当前主流的...
  • liangbch
  • liangbch
  • 2012年02月16日 04:34
  • 6983

LeetCode Sqrt(x) 整数平方根 java

http://oj.leetcode.com/problems/sqrtx/ 求一个整数的平方根,如果该整数的平方根不是整数的话,返回平方根取整。 最简单办法,暴力搜索从1到N/2搜索但会TL...
  • samjustin1
  • samjustin1
  • 2016年09月06日 22:08
  • 989

算法学习笔记(二):平方根倒数速算法

序 这是一个神奇的算法! 一、介绍 起源于一篇《改变计算技术的伟大算法》文章,知道这个算法,然后google一下,维基讲的还不错,现在自己权当理清下思路。先贴源代码,为《雷神之锤III竞技场》源代...
  • era_misa
  • era_misa
  • 2014年03月24日 14:35
  • 4143

算法题:求一个整数的开方

#include #include using namespace std; double Grial(int x) { double result = 1; double num = x;...
  • liuhuiyan_2014
  • liuhuiyan_2014
  • 2015年08月12日 22:56
  • 909

求一个数的平方根

方法一: 使用标准库函数, 中的sqrt函数直接计算。 其函数原型为: float sqrt (float),double sqrt (double),double long sqrt(double...
  • luckyjoy521
  • luckyjoy521
  • 2013年10月21日 10:29
  • 1872

【c语言】从键盘输入一个小于1000的正数,输出它的平方根(若平方根不是整数,则输出它的整数部分)

// 从键盘输入一个小于1000的正数,输出它的平方根(若平方根不是整数,则输出它的整数部分) // 要求在输入数据后检查是否为小于1000的正数,若不是则要求重新输入 #include #inc...
  • zhaoyaqian552
  • zhaoyaqian552
  • 2015年04月15日 13:10
  • 10979
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:整数平方根的汇编求法
举报原因:
原因补充:

(最多只允许输入30个字)