注册 登录
编程论坛 汇编论坛

问一下,关于求所有公约数的代码

czwmrmrs 发布于 2016-08-21 11:25, 2826 次点击
DATA SEGMENT
    BUFF    DB 0DH,0AH,'$'
    IN_MSG1 DB 'PLEASE ENTER A NUMBER:',0DH,0AH,'$'
    IN_MSG2 DB 'PLEASE ENTER ANOTHER NUMBER:',0DH,0AH,'$'
    OUT_MSG DB 'THE COMMON NUMBER(S) IS(ARE):',0DH,0AH,'$'
    LOAD    DB 'PRESS ANY KEY TO CONTINUE$'
DATA ENDS

CODE SEGMENT
  ASSUME   CS:CODE,DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    MOV AX,OFFSET IN_MSG1 ; 提示输入第一个数据
    CALL DISPMSG ;调用09
    CALL READSID ; 输入第一个数据
    MOV BX,AX ; 保存到BX
    MOV AX,OFFSET IN_MSG2 ; 提示输入第二个数据
    CALL DISPMSG ;调用09
    CALL READSID ; 输入第二个数据
    MOV CX,AX ; 保存到CX
    CALL AGAIN
    MOV AX,OFFSET OUT_MSG
    CALL DISPMSG
    MOV AX,CX ; 保存到AX
    CALL DISPSID

AGAIN PROC
    CMP BX,CX ;判断第一个数字是不是大于第二个数
    JNL FRONT ;跳转
    XCHG BX,CX ;交换
    FRONT: XOR DX,DX ;清零
    MOV AX,BX ;第一个数给AX
    DIV CX ;AX除CX
    CMP DX,0 ;判断余数是否为0
    JZ EQUAL ;等于0跳转
    MOV BX,CX  ;传送
    MOV CX,DX  ;传送
    JMP FRONT  ;无条件跳转
    EQUAL: RET
AGAIN ENDP

DISPMSG PROC           ;输出显示函数
    MOV DX,AX
    MOV AH,9    ;字符串输出(显示)
    INT 21H
    RET
DISPMSG ENDP

READSID PROC
    MOV AH,1     ;单字符的接受
    INT 21H
    MOV DH,AL
    SUB DH,30H

    MOV AH,1     ;单字符的接受
    INT 21H
    CMP AL,0DH    ;判断是不是为回车
    JZ  DONE1
    SUB AL,30H
    SHL DH,1     ;左移一位  相当于乘以二
    MOV DL,DH
    SHL DH,1
    SHL DH,1
    ADD DH,DL    ;两数相加
    ADD DH,AL

    DONE1:
    MOV CL,DH
    MOV DX,OFFSET BUFF
    MOV AH,9     ;字符串输出(显示)
    INT 21H
    MOV AL,CL
    XOR AH,AH     ;AH清零
    RET
READSID ENDP

DISPSID:

MOV BL,AL
MOV BH,1

L1:MOV AL,BL
   XOR AH,AH
   DIV BH       ;整除指令   只保存商的整数  AL存储除法操作的商,AH存储除法操作的余数
   CMP AH,0     ;判断是不是整除   如果整除就执行下去   如果不是则跳转到NEXT
   JNZ NEXT
   MOV AL,BH
   AAM             ;把两位数分开    十位存在AH  各位存在AL
   MOV CX,AX
   ADD CH,30H
   MOV DL,CH
   MOV AH,2       ;单字符输出(显示)
   INT 21H
   ADD CL,30H     ;将字符转变为ASCII
   MOV DL,CL
   MOV AH,2      ;单字符输出(显示)
   INT 21H
   MOV DX,OFFSET BUFF
   MOV AH,9       ;字符串输出(显示)
   INT 21H

NEXT:INC BH
     CMP BL,BH
     JL DONE
     JMP L1

DONE:MOV AH,4CH      ;进程终止
     INT 21H


CODE ENDS
END START






这里部分有左移之类的代码,但是不明白为什么这样做
3 回复
#2
Valenciax2016-08-21 22:18
回复 楼主 czwmrmrs
第1次shl是x2
然后3次shl是x8
加上之前的x2相当于该值x10
比如输入32,完成动作后,就是3x10+2

另外,这代码没处理输入0时,会有溢出的情况
#3
czwmrmrs2016-08-28 16:39
回复 2楼 Valenciax
那下面贴出来的程序这一段呢?这段不太理解。
DISPSID:

MOV BL,AL
MOV BH,1

L1:MOV AL,BL
   XOR AH,AH
   DIV BH       ;整除指令   只保存商的整数  AL存储除法操作的商,AH存储除法操作的余数
   CMP AH,0     ;判断是不是整除   如果整除就执行下去   如果不是则跳转到NEXT
   JNZ NEXT
   MOV AL,BH
   AAM             ;把两位数分开    十位存在AH  各位存在AL
   MOV CX,AX
   ADD CH,30H
   MOV DL,CH
   MOV AH,2       ;单字符输出(显示)
   INT 21H
   ADD CL,30H     ;将字符转变为ASCII
   MOV DL,CL
   MOV AH,2      ;单字符输出(显示)
   INT 21H
   MOV DX,OFFSET BUFF
   MOV AH,9       ;字符串输出(显示)
   INT 21H

NEXT:INC BH
     CMP BL,BH
     JL DONE
     JMP L1

DONE:MOV AH,4CH      ;进程终止
     INT 21H

#4
Valenciax2016-08-28 22:25
回复 3楼 czwmrmrs

这是个印出al值的子程序,看来不是楼主写的,不管怎样都太累赘了

下面是修改后的,功能不变

DISPSID:  ; 显示al十进制值子程序
 aam   ;bcd十进制加法调整,若al=49h,aam后ax=0409h
 or ax,3030h ;转ascii 若ax=0409h, or 后, ax=3439h,即已是49的ASCII吗
 push ax ;保存
 mov dl,ah ;十位放入dl,即34h
 mov ah,2
 int 21h ;印出
 pop dx  ;取al值,即49h
 int 21h ;印出

DONE:MOV AH,4CH      ;进程终止
     INT 21H
1