编写子程序Div_16,实现双字节无符号数除法。自行定义变量,其中:
- ACCALO ;存放被除数低 8 位
- ACCAHI ;存放被除数高 8 位
- ACCBLO ;存放除数 8 位
- ACCCLO ;存放余数 8 位
- ACCCHI ;存放商 8 位
采用移位法,设被除数为ACCA、除数为ACCBLO、商为ACCCHI(初值为0)、余数为ACCCLO(初值为0)。ACCA由高位至低位依次左移进入ACCCLO单元,每次移位进入后比较ACCCLO单元和ACCBLO的值,如果ACCCLO≥ACCBLO,则将这一位的商单元的值置1,然后从ACCCLO中减去ACCBLO,否则不做操作。直到ACCA全部进入ACCCLO单元为止。此时ACCCHI中存放商、ACCCLO中存放余数。
程序框图:
list p=16f877A ;标明所用的处理器类型
#include ;调用头文件
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
;*****************变量定义*******************************************************
ACCALO EQU 0x20 ; 存放被除数低 8 位
ACCAHI EQU 0x21 ; 存放被除数高 8 位
ACCBLO EQU 0x22 ; 存放除数 8 位
ACCCLO EQU 0x23 ; 存放余数 8 位
ACCCHI EQU 0x24 ; 存放商 8 位
COUNT EQU 0x25 ; 存放循环变量
;*******************************************************************************
ORG 0x0000 ; 复位入口地址
nop ; 兼容ICD调试工具,必须加nop
goto Main ; 跳转至Main函数
;*************************Main 函数的代码******************************
Main
MOVLW 0x2A ; 送被除数高8位
MOVWF ACCAHI
MOVLW 0x3B ; 送被除数低8位
MOVWF ACCALO
MOVLW 0x4C ; 送除数
MOVWF ACCBLO
MOVLW .16 ; 初始化循环变量
MOVWF COUNT
CLRF ACCCLO ; 清零结果单元
CLRF ACCCHI
CALL Div_16 ; 调用子程序求解,结果应为商0x8E,余0x13
nop
goto $ ; 停机
;**************************压缩BCD码转二进制子程序 ********************
ORG 0X0100
Div_16
RLF ACCALO
RLF ACCAHI
RLF ACCCLO ; 被除数由高位至低位依次左移进入余数单元
MOVF ACCBLO,W
BSF STATUS,C ; C位置1
SUBWF ACCCLO,W ; 比较余数单元与除数单元
BTFSC STATUS,C ; 若ACCCLO>=ACCBLO
CALL SUB_C_B ; 则该位商单元置1,余数单元减去除数,否则该位商单元置0
RLF ACCCHI
DECFSZ COUNT,F
GOTO Div_16
RETURN
SUB_C_B
MOVF ACCBLO,W ; 余数单元减去除数
SUBWF ACCCLO,F
RETURN
;*****************************************************************************
END ; 程序结束