汇编程序:无符号移位相减除法子程序(二)
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、商上零的方法

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大的。不过这就需要改动一些代码这里就不讨论了

9、 PUSHF TEST BYTE P哌囿亡噱TR 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大,就是这么一个道理。