定点数开方只能得到结果的整数部分,如代入FFFFH和FF10H的开方结果都是一样的,为FFH。如果想要得到比较精确的结果,可以先对被开方数乘以一个系数,待得到结果后,再除以相应的系数。如果被开方数太大,则不能使用此法,若想得到比较精确的结果,可以采用后面介绍的“浮点数开方”。
 以下为定点数开方的程序清单(其中包含校验程序部分)。该程序中包含定点数加法程序和定点数除法程序。
 LIST p=16f877
 INCLUDE p16f877.inc
 ;****************************************
 ;此子程序是求16位二进制数平方根的子程序,需要调用16/16位除法子程序和
 ;加法子程序,虽然前面有了,但标号有些不同,为了易于阅读和理解,也把它列在后面。
 ;入口条件:16位二进制数存放在NUMHI和NUMLO单元中。
 ;出口条件:8位二进制数存放在SQRTLO单元中。
 ;迭代次数由LUPCNT的地址值决定。
 ;用指令CALL SQRT实现定点数开方程序调用
 ;****************************************
 ACCALO EQU 0X20
 ACCAHI EQU ACCALO+1
 EXPA EQU ACCALO+2
 ACCBLO EQU ACCALO+3
 ACCBHI EQU ACCALO+4
 EXPB EQU ACCALO+5
 ACCCLO EQU ACCALO+6
 ACCCHI EQU ACCALO+7
 ACCDLO EQU ACCALO+8
 ACCDHI EQU ACCALO+9
 TEMP EQU ACCDHI+1
 SIGN EQU ACCDHI+2
 SQRTLO EQU ACCALO
 SQRTHI EQU ACCAHI
 NUMLO EQU ACCDHI+4
 NUMHI EQU ACCDHI+5
 COUNT EQU ACCDHI+6 ;此方法定义的数据块为连续层断,只要
 ;将第一行改变,就可以将数据整块搬动到
 ;新的地方,为调试带来方便,是比较推
 ;崇的一种寄存器定义方法
 LUPCNT EQU .10
 ;****************************************
 ORG 0X00
 GOTO MAIN
 ORG 0X10
 ;****************************************
 INIT MOVLW LUPCNT
 MOVWF COUNT
 MOVF NUMHI,0
 MOVWF SQRTHI
 MOVF NUMLO,0
 MOVWF SQRTLO
 BCF STATUS,C
 RRF SQRTHI,1
 RRF SQRTLO,1
 RETLW 0
 ;***************16×16位定点数右移子程序***************
 DIV2 BCF STATUS,C
 RRF ACCBHI,0
 MOVWF SQRTHI
 RRF ACCBLO,0
 MOVWF SQRTLO
 RETLW 0
 ;*********16×16位定点数开方子程序**********
 SQRT CALL INIT
 SLOOP MOVF NUMLO,0
 MOVWF ACCBLO
 MOVF NUMHI,0
 MOVWF ACCBHI
 CALL D_DIVS
 CALL D_ADD
 CALL DIV2
 DECFSZ COUNT,1
 GOTO SLOOP
 RETURN
 ;***********16×16位定点整数除法子程序*********
 D_DIVS CALL SETUP
 CLRF ACCCHI
 CLRF ACCCLO
 DLOOP BCF STATUS,C
 RLF ACCDLO
 RLF ACCDHI
 RLF ACCCLO
 RLF ACCCHI
 MOVF ACCAHI,0
 SUBWF ACCCHI,0
 BTFSS STATUS,Z
 GOTO NOCHK
 MOVF ACCALO,0
 SUBWF ACCCLO,0
 NOCHK BTFSS STATUS,C
 GOTO NOGO
 MOVF ACCALO,0
 SUBWF ACCCLO,1
 BTFSS STATUS,C
 DECF ACCCHI,1
 MOVF ACCAHI,0
 SUBWF ACCCHI,1
 BSF STATUS,C
 NOGO RLF ACCBLO
 RLF ACCBHI
 DECFSZ TEMP
 GOTO DLOOP
 RETLW 0
 ;****************************************
 SETUP MOVLW .16
 MOVWF TEMP
 MOVF ACCBHI,0
 MOVWF ACCDHI
 MOVF ACCBLO,0
 MOVWF ACCDLO
 CLRF ACCBHI
 CLRF ACCBLO
 RETLW 0
 ;**********16×16位定点数取补子程序**************
 NEG_A COMF ACCALO,1
 INCF ACCALO,1
 BTFSC STATUS,Z
 DECF ACCAHI,1
 COMF ACCAHI,1
 RETLW 0
 ;*************16×16位定点数加法子程序**************
 D_ADD MOVF ACCALO,0
 ADDWF ACCBLO,1
 BTFSC STATUS,C
 INCF ACCBHI,1
 MOVF ACCAHI,0
 ADDWF ACCBHI,1
 RETLW 0
 ;****************************************
 【校验举例】 被开方数2910H(十六进制)
 10512(十进制)
 求得平方根:66H(十六进制)
 102(十进制)
 MAIN NOP
 MOVLW 0X29
 MOVWF NUMHI
 MOVL7W 0X10
 MOVWF NUMLO ;被开方数赋值
 CALL SQRT ;调用开方子程序
 NOP ;开方完毕
 END