大话西游2光武截图:一种实用的单片机多字节除法算法

来源:百度文库 编辑:中财网 时间:2024/04/29 11:54:48

一种实用的单片机多字节除法算法

(2010-10-09 12:38:36)

一种实用的单片机多字节除法算法
在单片机的实际应用中,除法运算是比较常见的一种运算。以MCS-51单片机为例,虽然它提供了除法指令,但只能进行单字节除以单字节的运算,如果要进行多字节的除法运算,就得自己设计算法。目前,许多资料上都介绍了四字节除以二字节的算法,但它们主要有以下几点不足:
1.    只能求出商,不能求出余数;
2.    在被除数高二位大于除数时,不能进行运算;
3.    商只有两个字节。
例如,被除数是0FFFFFFFFH,除数是0004H时,商数应该是3FFFFFFFH,余数是0003H。但是,用以前的算法是无法进行运算的。
在实际运用中,参与运算的数是任意的,有时需要求出余数,有时商数要求有四个字节,因此,以前的算法在实际应用中受到了很大的限制。
为了满足实际运用中的需要,我设计了一套新的四字节除以二字节的算法,克服了上述算法中的缺点,可以适合广泛的实际需要。下面以MCS-51汇编语言为例进行说明。
该算法增加了两字节的余数单元,并把被除数单元用来存放商数。运算时,首先判断除数是否为零,若为零时,则设溢出标志为1,然后退出。若除数不为零,则采用移位相减法进行运算。首先,把进位位和余数单元清零。再将进位位、余数单元和被除数单元按顺序首尾相连,逐位进行向左循环移位(如图示),共移位32次。每移位一次,余数单元都


     (H    L)(HH    HL    LH    LL)
进位位   余 数 单元     被  除  数  单 

和除数作一次减法运算,若够减,余数单元内容更新为两者之差,并且将被除数最末一位置为1;若不够减,则余数单元内容保持不变,且将被除数最末一位置为0。判断是否够减的方法是:在作减法之前,先保存进位位,再看作完减法后的进位位。仅在作减法之前进位位为0,并且作减法之后进位位为1时判为不够减,其余情况均视为够减。这样,等到全部运算结束时,商数为四个字节,存放在被除数单元中;余数为两个字节,存放在余数单元中。
例如,被除数是0FFFFFFFFH,除数是0004H时,运行新的算法,商数是3FFFFFFFH,存放在被除数单元中,余数是0003H,存放在余数单元中。
这个算法自然、流畅,运算结果商数为四个字节,余数为两个字节,尤其是在求除以某数的N次方时,只需连续调用N次该算法子程序就可以了,省去了繁琐的数据转存语句。该算法还可以依实际需要扩充为位数更高的多字节除数算法,也可以移植到其它的单片机平台上。本算法已在AT89C51单片机上调试通过。下面给出算法的程序代码清单。
divdll    data    20h        ;定义被除数单元
divdlh    data    21h
divdhl    data    22h
dlvdhh    data    23h
divl        data    24h        ;定义除数单元
divh        data    25h
templ    data    26h        ;定义余数单元
temph    data    27h

divd:    push        acc
        push        b
    mov    a,divdh    ;判除数是否为零
    orl    a,divl
    jnz    divd0
    setb    ov        ;除数为零,置溢出标志
    pop    b
    pop    acc
    ret
divd0:    mov    templ,#00h    ;除数不为零,进行运算
    mov    temph,#00h
    mov    b,#20h        ;置循环次数
divd1:clr              ;进位位、余数单元和
    mov    a,divdll        ;被除数单元全体逐个
    rlc              ;向左循环移位
    mov    divdll,a
    mov    a,divdlh
    rlc    a
    mov    divdlh,a
    mov    a,divdhl
    rlc    a
    mov    divdhl,a
    mov    a,divdhh
    rlc    a
mov    divdhh,a
mov    a,templ
rlc    a
mov    templ,a
xch    a,temph
rlc    a
xch    a,temph
mov    f0,c            ;保存进位位
clr    c
subb    a,divl        ;用余数减去除数
mov    r7,a
mov    a,temph
subb    a,divh
anl    c,/f0            ;判断是否够减
jc    divd2        ;不够减,移下一位
mov    templ,r7        ;够减,刷新余数单元
mov    temph,a
inc    divdll        ;商上1
divd2:    djnz    b,divd1
    clr    ov
    pop    b
    pop    acc
    ret
end