多语言展示
当前在线:620今日阅读:86今日分享:14

汇编程序:无符号移位相减除法子程序(二)

上一篇我们简单说明了一下这个汇编程序的基本原理,接下来我们继续分析这个程序,下面的链接是(一)篇,由于标题被吞了,所以说明一下4汇编程序:无符号64位除32位的除法子程序(
方法/步骤
1

程序如下(R4R5R6R7/R2R3=R6R7):;This program for:R4R5R6R7/R2R3=R6R7 ;Remainder=(R4R5);----------------------------------------------------------------;define stack segmentSTACK           SEGMENT STACK 'STACK'                DB 1024 DUP (0)STACK           ENDS;define data segmentDATA            SEGMENTBWORD   EQU     THIS    BYTE                           R0      DW      (?)                R1      DW      (?)                R2      DW      (?)                R3      DW      (?)                R4      DW      (?)                R5      DW      (?)                R6      DW      (?)                R7      DW      (?)DATA            ENDS;define code segmentNBDIV           SEGMENT;MAIN            PROC FAR                ASSUME  CS:NBDIV,DS:DATA,SS:STACK;START:          PUSH    DS        ;return DOS standard program                MOV     AX,0                PUSH    AX                MOV     AX,DATA   ;set DS                MOV     DS,AX                MOV     AX,R5                SUB     AX,R3                MOV     AX,R4                SBB     AX,R2                JNC     DIV4    ;Over process                MOV     CX,32                 ;DIV1:           CLC                RCL     R7,1                RCL     R6,1                RCL     R5,1                RCL     R4,1                PUSHF                POP     R0      ;Store RF to R0                MOV     AX,R5                SUB     AX,R3                MOV     R1,AX                MOV     AX,R4                SBB     AX,R2                PUSHF                TEST    BYTE PTR R0,01H                JNZ     DIV21                POPF                JNC     DIV2                JMP     DIV3DIV21:          POPFDIV2:           MOV     R4,AX                MOV     AX,R1                MOV     R5,AX                INC     R7DIV3:           LOOP    DIV1                STCDIV4:           RETMAIN            ENDPNBDIV           ENDS                END     START上一篇我们说过了,这是把图中过程用汇编语言实现的程序而且还顾及到了下面的问题1、判断够减或不够减的方法2、够减时的处理方法3、不够减时的处理方法4、商上1的位置和方法5、商上零的方法

2

STACK           SEGMENT STACK 'STACK'                DB 1024 DUP (0)STACK           ENDS;define data segmentDATA            SEGMENTBWORD   EQU     THIS    BYTE                             R0      DW      (?)                R1      DW      (?)                R2      DW      (?)                R3      DW      (?)                R4      DW      (?)                R5      DW      (?)                R6      DW      (?)                R7      DW      (?)DATA            ENDS;define code segmentNBDIV           SEGMENT;MAIN            PROC FAR                ASSUME  CS:NBDIV,DS:DATA,SS:STACK;START:          PUSH    DS        ;return DOS standard program                MOV     AX,0                PUSH    AX                MOV     AX,DATA   ;set DS                MOV     DS,AX这一部分是程序的一些定义,初始化的代码,比较简单,但需要一些微机的知识,我们这里不讲解这一部分,而是主要讲解功能实现的部分

3

其中讲解一下几个命令 PUSHF  POPF,一个是入栈,一个是出栈,但与PUSH,POP不同的是,PUSHF入栈的内容是确定的,就是标志寄存器的所有的标记位,也就不单单是cf或者af之类,而是所有,POPF也是一样,内容出栈,但出栈的内容去哪里是确定的,就是覆盖标志寄存器的内容JNC, JNC是单单判断标记寄存器中的CF位是不是0,如果是0,就跳转,不是就不跳转。JNZ 也是差不多,不过它是判断上一条指令的结果是不是零,如果不是0,就跳转,是0就不跳转,这里就与JNC刚好相反,当然也可以这么说,JNZ判断标记寄存器中的ZF位是不是0,如果上一条指令的结果不是零,则ZF就为0,如果ZF为0,则跳转。两种说法是一样的。JMP,是无条件跳转,也就是,前面无论发生什么都与它无关,它只负责跳转RCL ,是向左移一位,把低位补上标记寄存器CF的值,并把高位存储覆盖标记寄存器CF的值CLC,是把标记寄存器中的CF位 置零STC,是把标记寄存器中的CF位 置一其他命令都比较好理解就不说了

4

MOV     DS,AX                MOV     AX,R5                SUB     AX,R3                MOV     AX,R4                SBB     AX,R2                JNC     DIV4    ;Over process                MOV     CX,32                 ;这里讲一下这一行内容,这是初始化紧接着的内容,这段内容的意义主要是解决判断算式是否是可执行的,我们知道程序的式子是:R4R5R6R7/R2R3=R6R7上面几行代码的意思就是判断R4R5是不是比R2R3大,如果是就跳到DIV4,但为什么要这么做?别急,请看下面

5

(一)篇的式子商是1100,我们修改一下式子,如下图所示,结果变成了10011,1100是四位二进制,但10011时五位二进制,原因是被除数11000001的前四位1100比除数1010大我们回到程序,为什么R4R5不能比R2R3大,因为如果R4R5比R2R3大,得到的结果就比R6R7的位数大,一个字节是8位,一个字是两个字节,R0~R7是字,即16位二进制,R6R7是双字,共32位二进制,我们设定商是R6R7,即商只能是32位二进制,如果R4R5比R2R3大,则商多于32位,则无法显示正确结果。当然,如果你设置结果是R0R1R6R7,即和被除数一样是64位,是允许R4R5比R2R3大的。不过这就需要改动一些代码这里就不讨论了

6

CLC                RCL     R7,1                RCL     R6,1                RCL     R5,1                RCL     R4,1就是把被除数整体左移一位,并把末尾一位补上零,把最高位存储在CF标记寄存器如果被除数是ffff ffff ffff ffff ffff ffff ffff ffff 执行上面代码后变成ffff ffff ffff ffff ffff ffff ffff fffe CF的值就为1

7

PUSHF  POP     R0      ;Store RF to R0这行的意思就是把寄存器的内容存储在R0上,作用等下再说

8

MOV     AX,R5                SUB     AX,R3                MOV     R1,AX                MOV     AX,R4                SBB     AX,R2以上的代码很好理解,但意义是什么呢?这个程序中的式子是R4R5R6R7/R2R3=R6R7,在(一)篇中,我们设置商是Q,余数是R,但在程序 R6R7是商(Q),R4R5是余数(R),除数是R2R3(B),所以我们可以套用(一)篇的内容来解释,用R4R5作为余数事实上,就是先左移32位进R,但上面我们已经说过了,一开始R4R5是不能比R2R3大的,所以这里代码就继续左移一位,这样再比较余数R是不是比被除数B大,是,商就左移进一个1并使余数等于R-B的差,即执行如下代码,下面的代码就是把差存进R中,并把R7最后一位变为1DIV2:        MOV     R4,AX                MOV     AX,R1                MOV     R5,AX                INC     R7但如果余数R4R5并不是比R2R3大,商就左移进一个0。这里需要解释一为什么用 INC     R7,INC     R7是给R7加1的意思,为什么要加1呢,首先我们在前面的时候执行了下面代码                 CLC                 RCL     R7,1                RCL     R6,1                RCL     R5,1                RCL     R4,1首先我们要知道R6R7既是被除数一部分,又是商,我们在左移被除数时,已经默认左移了一个0进商R6R7最后一位去了,所以我们只要加1把这个零改成1就行了,如果余数R4R5不是比R2R3大,也不需要左移一个0了,因为已经移了。这里需要理解(一)篇的内容才行。

9

PUSHF                TEST    BYTE PTR R0,01H                JNZ     DIV21                POPF上面代码是什么意思,首先BYTE PTR R0是指定R0低位的字节,TEST是把R0低位的字节与01H进行与运算。那么意义是什么呢,首先看前面的两行代码 PUSHF  POP     R0      ;Store RF to R0可以知道R0现在存储是之前左移后的标记寄存器的内容。这里我们还是回到(一)篇的内容,我们假设一个方程A/B=Q,余数是R其中(二进制)A=10000001B=1010从(一)篇可以知道,有10000-1010这一步,这里商应该被左移进一个1,但是在程序中虽然10000是比1010大的,但程序只比较和除数一样位数的值,即在程序中比较的0000与1010的大小,进行的是0000-1010的借位减法,所以CF是1,这样 JNC     DIV2,这一步就不会跳转到DIV2,商就不会被左移进一个1,造成结果的错误,所以,我们这里保证如果执行               CLC                 RCL     R7,1                RCL     R6,1                RCL     R5,1                RCL     R4,1后,CF的值变成1,即被除数原最高位是1这种情况下,商应该被左移进一个1,因为这种情况下,不应该是0000-1010,而是10000-1010,必定是商应该被左移进一个1的。DIV21:          POPF这里是为了进行两次POPF,使CF变成0这样 JNC     DIV2,这一步就可以跳转到DIV2

10

这样程序就基本讲解完成了,比较难理解的是步骤9,其实简单来说就是R4R5可能比R2R3小,但如果进位的CF是1,CF R4R5就一定比R2R3大,就是这么一个道理。

推荐信息