美文网首页
合肥学院微机实验4(子程序调用实验代码及解析)

合肥学院微机实验4(子程序调用实验代码及解析)

作者: Songzh | 来源:发表于2016-12-02 11:54 被阅读0次
    .MODEL  TINY
    .STACK      100
    .DATA    
    

    BUFFER DB 10 DUP(?);BUFFER存放8个不确定数
    augend DB 2 DUP(?) ;被加数
    addend DB 2 DUP(?) ;加数
    msg1 DB 0DH,0AH,'请输入被加数: $'
    msg2 DB 0DH,0AH,'请输入加数: $'
    msg3 DB 0DH,0AH,'结果: $';msg3存放结果
    ;0DH和0AH分别是回车和换行的ASCII码,
    ;'$'是DOS功能调用INT 21H中9号功能要求的要显示字符串的结束标志
    .CODE
    START: MOV AX,@DATA
    MOV DS,AX
    MOV ES,AX
    CLD ;方向标志位清零 ;CLD与STD是用来操作方向标志位DF(Direction Flag)。
    ;CLD使DF复位,即DF=0,STD使DF置位,即DF=1.用于串操作指令中
    NOP ;空操作 ;NOP指令只使程序计数器PC加1,所以占用一个机器周期
    ;其目的为保证写、读之间有个稳定时间
    MOV AH,00H
    MOV AL,03H
    INT 10H ;清屏
    START1: MOV AH,09H ;9号调用DX指向被加数的首地址,输出提示信息
    LEA DX,msg1 ;将源操作数给出的有效地址传送到指定的的寄存器中
    INT 21H
    LEA DI,augend ;DI->augend的首地址
    MOV CX,4 ;按键次数
    CALL GetBCDKey ;得到双字节十进制数(被加数)
    JNB START2 ;没有输入任何数字,结束 CF=0
    MOV AH,09H ;9号调用DX指向加数的首地址
    LEA DX,msg2 ;将源操作数给出的有效地址传送到指定的的寄存器中
    INT 21H
    LEA DI,addend ;di指向加数
    MOV CX,4 ;按键次数
    CALL GetBCDKey ;得到双字节十进制数(加数)
    JNB START2 ;没有输入任何数字,结束
    MOV AL,augend ;被加数的低8位送al
    ADD AL,addend ;al与加数的低位相加的结果送al
    DAA ;BCD算术运算调整,转换为压缩型BCD
    XCHG AL,AH ;高位与低位互换
    MOV AL,augend + 1
    ADC AL,addend + 1 ;高位
    DAA
    XCHG AL,AH
    MOV BL,0
    ADC BL,0 ;进位 bl存放的是进位 bl和ax相加是最后的结果
    STD ;方向标志置1
    LEA DI,BUFFER+4 ;存放显示结果
    CALL B1toB2 ;低位
    MOV AL,AH
    CALL B1toB2 ;高位
    MOV AL,BL
    OR AL,30H ;转换成数字
    STOSB ;存数
    LEA SI,BUFFER
    MOV CX,5
    CALL BlackDisplay ;将高位0消隐
    MOV AH,09H
    LEA DX,msg3 ;9号调用DX指向结果的首地址
    INT 21H
    MOV AH,09H
    LEA DX,BUFFER ;9号调用DX指向BUFFER的首地址
    INT 21H
    JMP START1 ;跳转到START1
    START2: MOV AH,4CH ;结束程序
    INT 21H
    ; JMP $

    ;将一个字节压缩BCD码转换成二个字节数字
    B1toB2 PROC NEAR ;段内
    PUSH AX ;ax存放的是相加后的结果
    AND AL,0FH ;高四位置0
    OR AL,30H ;加30H
    STOSB ;存数 个位 百位
    POP AX
    AND AL,0F0H ;低四位置0
    ROR AL,4 ;循环右移4位
    OR AL,30H ;加30H
    STOSB ;存数 十位 千位
    RET
    B1toB2 ENDP

    BlackDisplay PROC NEAR
    CLD ;方向标志清零
    MOV DI,SI ;si送给di si指向buff的第一个缓冲区 增量变化
    BlackDisplay1: LODSB ;将高位0消隐,取串
    CMP AL,'0'
    JNZ Exit ;若al不等于0跳转EXIT
    LOOP BlackDisplay1 ;否则cx不为0一直循环 cx次
    INC CX ;cx加1
    Exit: DEC SI ;si前移
    REP MOVSB ;重复传送字节
    MOV AL,'$' ;把$符送al
    STOSB ;存数
    RET
    BlackDisplay ENDP

    GetBCDKey PROC NEAR
    LEA SI,BUFFER
    MOV AL,4 ;把4写入到buff
    MOV [SI],AL ;【】是内存单元
    MOV DX,SI
    MOV AH,0AH ;dx指向缓冲区
    MOV AL,02H ;0:任意字符 1:16进制数 2:10进制数,10进制数输入
    INT 21H

        MOV AL,[BUFFER+1]   ;把内存数据段buff地址+1的值给al
        XOR AH,AH           ;AH清零 异或指令
        MOV CX,AX           ;ax的内容送CX cx的值是数据的个数
        JCXZ    GetBCDKey3      ;cx为0,转向GetBCDKey3 判断cx直接回车cx=0
        LEA SI,BUFFER+1     ;不为0
        ADD SI,AX           ;ax=4 si=5
        STD                     ;std 使si或di递增
    

    GetBCDKey1: LODSB ;ds:si->al
    AND AL,0FH ;高4位清零
    CMP CX,1 ;
    JE GetBCDKey2
    DEC CX ;进数位-1
    MOV AH,AL
    LODSB
    AND AL,0FH
    SHL AL,4 ;逻辑左移4位
    OR AL,AH ;
    GetBCDKey2: CLD
    STOSB ;存串指令
    STD
    LOOP GetBCDKey1 ;cx=2 原先为4 上面减了一次一 loop再减一所以等于2
    MOV CL,[BUFFER]
    SUB CL,[BUFFER+1]
    SHR CL,1 ;逻辑右移1位
    MOV AL,0
    CLD
    REP STOSB ;重复存数
    STC ;进位标志位置1
    RET
    GetBCDKey3: CLC ;进位标志位清零cf=0
    RET ;返回
    GetBCDKey ENDP

        END START
    

    相关文章

      网友评论

          本文标题:合肥学院微机实验4(子程序调用实验代码及解析)

          本文链接:https://www.haomeiwen.com/subject/alafmttx.html