编写汇编语言程序,实现从文件(其中有n位学生的某科成绩)读入成绩后显示各个成绩段程序


前言

编写汇编语言程序,实现从文件(其中有n位学生的某科成绩)读入成绩后显示各个成绩段程序。

本文参考这两位大佬的文章(十分感谢这两个大佬的启发)

汇编程序语言设计-成绩统计_汇编统计成绩_冰糖Shirley_的博客-CSDN博客

汇编程序设计:磁盘文件的读写_汇编语言从文件中读取数字_飞行模式HR的博客-CSDN博客

问题点

全部代码在下方,主页的不知道可不可以免费下载

1.读取文件部分

代码如下(示例):本程序是将数据先读入一个数组在转换成bcd码存到另一个要操作的数组

              mov dx , offset file        ;dx获取file的偏移地址
              mov al , 0                
              mov ah , 3dh                
              int 21h                  ;打开文件,只读;ax返回文件代号
              ;jc error11                  ;若打开出错,转error
              mov handle , ax           ;保存文件句柄
              mov bx , ax                ;文件句柄
              mov cx , 255                ;读取255字节
              mov dx , offset buf        ;获取buf的偏移地址
              mov ah , 3fh                
              int 21h                  ;从文件中读255字节→buf
              ;jc error11                  ;若读出错,转error
              mov bx , ax              ;实际读到的字符数送入bx
              mov buf[bx] , '$'          ;在文件结束处放置一“$”符              
              MOV dx , offset buf[0]
              MOV AH , 09H
              int 21h                   ;显示文件内容
              mov bx , handle                    ;文件句柄
              mov ah , 3eh                        
              ​​​​​​int 21h                            ;关闭文件
              mov SI,offset buf                  ;将读入的数组首地址给源变址寄存器
INPUT:          mov AL,[SI]      ;将buf数组中第一个数据给AL
                inc SI             ;SI自增,指向buf第二个数据的位置
                CMP AL,44H          ;是否为结束字符A
                JZ ENDINPUT     ;如果是跳转
                CMP AL,20H     ;是否为空格
                JZ SAVE         ;如果是跳转
 
                CMP AL,30H      
                JB   ERROR
                CMP AL,39H
                JA    ERROR;确认ascii码对应的是0到9
 
                SUB AL,30H ;变为真数
                MOV CL,4 
                SHL BX,CL ;左移四位.变为BCD码
                ADD BL,AL
                JMP INPUT
SAVE:           MOV SCORE[DI],BX;将bx中的以bcd码存的数据(最多四位bcd码)
                                ;存入SCORE数组中的第一个位置
                ADD DI,2    ;将目的变址寄存器加二(也就是16位)指向下一个位置
                ADD sii1,1;用变量记录存入数据个数
                XOR BX,BX;异或,即清零作用
                JMP INPUT
ENDINPUT:       MOV SCORE[DI],BX ;保存最后一个数据
                XOR DI,DI
                ADD sii1,1
                mov dx,sii1
                ADD DI,dx;将变量给DI
                MOV DL,0AH
                MOV AH,02H
                INT 21H   ;留出一行空格(输出换行)
 
                MOV DX,OFFSET ENDTIPS ;显示输出提示
                MOV AH,09H
                INT 21H    ;DI得到个数,DI保持不变化
         

2.BCD码与十六进制转换

bcd码就是用四位二进制(一位十六进制)表示一位十进制数;

例如:十进制数4567    对应的十六进制为11D7

对应的bcd码为4567(以十六进制(4567)的存储方式保存也就是0100 0101 0110 0111)但是此时代表的数据是十进制四千五百六十七

(1)十六进制转bcd码

        MOV AX,BX;初始的十六进制数在BX中
        MOV BX,0000H
                MOV CX,1000
                DIV CX;先将数据除以1000,得到千位的值
                                ;比如数据为4321
                                ;那么此时得到的商4放在AX中,得到的余数321放在DX中
        
        MOV CL,4
        AND AX,000FH;取AX中低四位,也就是四位二进制表示一个十进制数即bcd码
        ADD BX,AX;把上面结果也就是4放在BX
        ROL BX,CL;把得到的结果循环左移4位,也就是放在了第二位十六进制数的位置也就是0040h
        
       
                MOV AX,DX ;余数再放到AX里面
                MOV CL,100;余数再除100,也就是321除100
                DIV CL;商放在AL里,余数放在AH里
        PUSH AX;入栈,保存AX数值
                AND AX,000FH;取低四位也就是3
        ADD BX,AX;加和后就是0043
        MOV CL,4
        ROL BX,CL;再左移,0430
        POP AX;把刚才的数据取出
 
                MOV AL,AH;余数再除10
                AND AX,00FFH;取刚才的余数
                MOV CL,10
                DIV CL;商2放在AL,余数1放在AH
               AND AX,000FH
        ADD BX,AX;取低四位也就是2放在BX,也就是0432
        MOV CL,4
        ROL BX,CL;再左移
 
                ADD BL,AH;放入,那么此时BX结果为4321

(2)bcd码转换成十六进制

 MOV AX, BX ;初始bcd码在BX中
        PUSH AX
        AND AX,0F000H;取千位数
        MOV CL, 4    ;移位取出千位数
        SHR AX, CL
        MOV DH, AH
        POP AX  
        
        PUSH AX
        AND AX, 0F00H  ;取百位数
        MOV DL, AH 
        POP AX  
        
        PUSH AX
        MOV AX, DX
        AAD 
;指令是在作除法前用于调整寄存器AH和AL之值,它是把二个寄存器中单BCD码组成一个十进制数值,其调整规则如下:
;AL←AH*10+AL,AH←0
;受影响的标志位:PF、SF和ZF(AF、CF和OF等都是无定义)
;MOV AX, 0502H MOV BL, 10D AAD          ;AH=0, AL=52H DIV BL        ;AH=2(余数), AL=5(商)                                 
        MOV DI, 100  ;乘100
        MUL DI                                 
        MOV SI, AX
        POP AX 
        
        PUSH AX       
        MOV CL, 4    ;移位取出十位数
        SHR AX, CL
        AND AX, 000FH  
        MOV DH, AL
        POP AX  
        
        PUSH AX
        AND AX, 000FH   ;取AL低四位,个位数
        MOV DL, AL 
        POP AX 
        
        MOV AX, DX
        AAD 
        ADD AX, SI
        
        MOV BX, AX ;转换结果给BX 

其余部分实现都是基本的操作,一些打印操作参考int 21h有关命令即可

全部代码(需要一个txt文档放在dos目录下的c盘,自己可以更改file声明行的路径)

环境可以使用ASM CoolKits软件,非常方便,也可以配dosbox。

DATA     SEGMENT   
INPUTTIPS        DB           'Please input score,divid with "  ":$'
ERRORTIPS        DB          'input ERROR!,please try again!$'
ENDTIPS         DB                    'results:$'
STRINGMAX        DB                 '|max  score     |$'
STRINGMIN         DB                 '|min  score     |$'
STRINGNUM      DB          '|total num      |$'
STRING_60           DB                 '|Less than 60   |$'
STRING60_70        DB                 '|From 60 to 69  |$'
STRING70_80        DB                 '|From 70 to 79  |$'
STRING80_90        DB                 '|From 80 to 89  |$'
STRING90_100        DB                 '|From 90 to 100 |$'
STRINGAVG        DB                 '|average score  |$'

STRINGLINE        DB                   '+===============+=============$'
ALL100             DB            '100%$'
BAI00            DB            '100.0$' 
SCORE          DW                 60 DUP(0) ;分配存放空间;重复分配60次值为0的16位数据的空间
S_60             DW                 0 ;定义变量
S60_70             DW                 0
S70_80             DW                 0
S80_90             DW                 0
S90_100             DW                 0
AVG               DW                 0
file             db    'c:\1.txt' , 0       ;文件名,dosbox 设置的c盘下的路径
buf             dw   256 dup(0)        ;文件内容暂存区
;error_message    db   0ah , 'error !' , '$'    ;出错时的提示
handle           dw  ?                ;保存文件号
sii1             dw                  0
DATA         ENDS
 
STACK     SEGMENT       
           DB                 200   DUP(0) 
STACK     ENDS 
  
CODE     SEGMENT   
              ASSUME     CS:CODE,DS:DATA,SS:STACK;段寻址伪指令,指明段名与寄存器的关系
  
START:                        
            MOV AX,DATA
            MOV DS,AX
            MOV AX,STACK
            MOV SS,AX;让各段指向正确的位置
            CALL BEGIN
            mov SI,offset buf
            CALL INPUT;    显示results    
            CALL NEXT    
            CALL LINE
            CALL PRINTNUM   
            CALL NEXT    
            CALL LINE
            CALL PRINTMAX    
            CALL NEXT            
            CALL LINE
            CALL PRINTMIN
            CALL NEXT    
            CALL LINE
            CALL SORT
            CALL PRINTSORT
            CALL PRINTAVG
            CALL LINE
            MOV AH,4CH
            INT 21H

;========================BEGIN=============================
BEGIN PROC NEAR;段内近调用,调用程序的子程序在同一代码段中
              mov dx , offset file		;dx获取file的偏移地址
              mov al , 0				
              mov ah , 3dh				
              int 21h                  ;打开文件,只读;ax返回文件代号
              ;jc error11                  ;若打开出错,转error
              mov handle , ax           ;保存文件句柄
              mov bx , ax				;文件句柄
              mov cx , 255				;读取255字节
              mov dx , offset buf		;获取buf的偏移地址
              mov ah , 3fh				
              int 21h                  ;从文件中读255字节→buf
              ;jc error11                  ;若读出错,转error
              mov bx , ax              ;实际读到的字符数送入bx
              mov buf[bx] , '$'          ;在文件结束处放置一“$”符              
              MOV dx , offset buf[0]
              MOV AH , 09H
              int 21h                   ;显示文件内容
              mov bx , handle					;文件句柄
              mov ah , 3eh						
              int 21h                            ;关闭文件
              XOR AX,AX                                
              XOR BX,BX
              XOR CX,CX
              ;XOR DX,DX
              XOR SI,SI
              XOR DI,DI  ;寄存器清零
              MOV S_60,AX             
              MOV S60_70,AX             
              MOV S70_80,AX             
              MOV S80_90,AX           
              MOV S90_100,AX             
              MOV AVG  ,AX         ;数据段清零,循环时使用    


                RET
BEGIN ENDP

;=======================INPUT==========================
INPUT PROC NEAR                  
                mov AL,[SI]
                inc SI
                CMP AL,44H 
                JZ ENDINPUT     ;是否为结束字符A
                CMP AL,20H     ;是否为空格
                JZ SAVE
 
                CMP AL,30H
                JB   ERROR
                CMP AL,39H
                JA    ERROR;确认ascii码对应的是0到9
 
                SUB AL,30H ;变为真数
                MOV CL,4 
                SHL BX,CL ;左移四位.变为BCD码
                ADD BL,AL
                JMP INPUT
SAVE:           MOV SCORE[DI],BX
                ADD DI,2
                ADD sii1,1;用变量记录存入数据个数
                XOR BX,BX;异或,即清零作用
                JMP INPUT
ENDINPUT:       MOV SCORE[DI],BX ;保存最后一个数据
                XOR DI,DI
                ADD sii1,1
                mov dx,sii1
                ADD DI,dx;将变量给DI
                MOV DL,0AH
                MOV AH,02H
                INT 21H   ;留出一行空格(输出换行)
 
                MOV DX,OFFSET ENDTIPS ;显示输出提示
                MOV AH,09H
                INT 21H    ;DI得到个数,DI保持不变化
                                
                JMP INPUTEND
ERROR:          mov dx,offset ERRORTIPS
                mov ah,09h
                int 21h
                CALL NEXT
                jmp START
              
    
INPUTEND:                RET
INPUT ENDP
;========================PRINTNUM========================
PRINTNUM PROC NEAR
                MOV SI,0           ;打印个数NUM 
                XOR BX,BX
                         
                MOV DX,OFFSET STRINGNUM ;显示输出NUM:
                MOV AH,09H
                INT 21H;打印'|total num      |$'
 
                MOV BX,DI
                AND BX,00FFH
 
                CALL PRINTINT
            RET 
PRINTNUM ENDP
;========================PRINTMAX========================
PRINTMAX PROC NEAR    
            MOV SI,0        ;打印最大值
            XOR BX,BX
            MOV CX,DI
            ;比较两个无符号数
                ;CMP结果	      ZF	CF
                ;目的操作数 < 源操作数	0	1
                ;目的操作数 > 源操作数	0	0
                ;目的操作数 = 源操作数	1	0
                ;比较两个有符号数
                ;CMP结果	                标志位
                ;目的操作数 < 源操作数	SF ≠ OF
                ;目的操作数 > 源操作数	SF=OF
                ;目的操作数 = 源操作数	ZF=1
    LMAX:    CMP BX,SCORE[SI]
                    JAE NEXT1     ;无符号左大于右跳转         
            MOV BX,SCORE[SI]    ;BX里面放最大值
    NEXT1:
            ADD SI,2
            LOOP LMAX;根据DI的值确定循环多少次
            
                    MOV DX,OFFSET STRINGMAX ;显示输出最大值
                    MOV AH,09H;09
                        ;显示字符串
                        ;DS:DX=串地址
                        ;'$'结束字符串
                    INT 21H
            
            CALL PRINTBCD
            RET
PRINTMAX ENDP 
;========================PRINTMIN========================
PRINTMIN PROC NEAR
            MOV SI,0        ;打印最小值
            MOV CX,DI
 
            LMIN:    CMP SCORE[SI],BX
                    JAE NEXT2         ;与上个函数同理     
            MOV BX,SCORE[SI]    ;BX里面放最小值
            NEXT2:
            ADD SI,2
            LOOP LMIN
            
                    MOV DX,OFFSET STRINGMIN ;显示输出最小值
                    MOV AH,09H
                    INT 21H
            
            CALL PRINTBCD
            RET
PRINTMIN ENDP
;========================SORT========================
SORT PROC NEAR
                    MOV SI,0
            XOR BX,BX
            MOV CX,DI            
                                
COM:                AND AX,0000H  ;开始比较
                    MOV AX,SCORE[SI]
                                
COM6:           MOV BX,60H 
            CMP AX,BX ;与60比较
            JAE COM7  ;大于就跳到COM7
            JMP C_60
            
COM7:       MOV BX,70H
            CMP AX,BX;与70比较
            JAE COM8 
            JMP C60_70
            
COM8:       MOV BX,80H
            CMP AX,BX ;与80比较
            JAE COM9 
            JMP C70_80
            
COM9:       MOV BX,90H
            CMP AX,BX ;与90比较
            JAE  C90_100
            JMP C80_90
 
C_60:       INC S_60 ;小于60时[S_60+1]
            JMP RE
C60_70:     INC S60_70 ;大于等于60小于70时[S60_70+1]
            JMP RE
C70_80:     INC S70_80;大于等于70小于80时[S70_80+1]
            JMP RE
C80_90:     INC S80_90 ;大于等于80小于90时[S80_90+1]
            JMP RE
C90_100:    INC S90_100 ;大于等于90小于100时[S90_100+1]
            JMP RE 
 
RE:                 ADD SI,2
        LOOP COM
            RET
SORT ENDP
;========================PRINTSORT========================
PRINTSORT PROC NEAR                                                               
          MOV DX,OFFSET STRING_60 ;显示输出S_60
          ;STRING_60           DB                 '|Less than 60   |$'
               ;STRING60_70        DB                 '|From 60 to 69  |$'
                ;STRING70_80        DB                 '|From 70 to 79  |$'
                ;STRING80_90        DB                 '|From 80 to 89  |$'
                ;STRING90_100        DB                 '|From 90 to 100 |$'
                MOV AH,09H
                ;显示字符串
                ;DS:DX=串地址
                ;'$'结束字符串
                INT 21H
                                
                MOV  BX,S_60
        AND BX,00FFH
        CALL PRINTINT
              CALL  PERCENT
                
        CALL NEXT
                  CALL LINE
                                
                MOV DX,OFFSET STRING60_70 ;显示输出S60_70
                MOV AH,09H
                INT 21H 
                
                MOV  BX,S60_70
        AND BX,00FFH
                   CALL PRINTINT
              CALL  PERCENT
        
                  CALL NEXT
                    CALL LINE
                                
                MOV DX,OFFSET STRING70_80 ;显示输出S70_80
                MOV AH,09H
                INT 21H
                
                MOV BX,S70_80 
        AND BX,00FFH
                   CALL PRINTINT
              CALL  PERCENT    
 
        CALL NEXT
                    CALL LINE
                                
                MOV DX,OFFSET STRING80_90 ;显示输出S80_90
                MOV AH,09H
                INT 21H
                
                MOV BX,S80_90
        AND BX,00FFH 
                CALL PRINTINT
             CALL  PERCENT
 
        CALL NEXT
                    CALL LINE
                                
                MOV DX,OFFSET STRING90_100 ;显示输出S90_100
                MOV AH,09H
                INT 21H 
                
                MOV BX,S90_100 
                CALL PRINTINT
          CALL  PERCENT
 
        CALL NEXT        
                    CALL LINE
                RET
PRINTSORT ENDP
;========================PRINTAVG========================
PRINTAVG PROC NEAR      
                  MOV SI,0;
                        XOR BX,BX;
                        MOV CX,DI
                        MOV AX,0
 
    AVERAGE:     MOV BX,SCORE[SI] ;把每一个以BCD码存储的数转化为十六进制  
                        CALL BCD_TO_HEN  ;调用转换函数
                        MOV SCORE[SI],BX
                        ADD AX,SCORE[SI]  ;求和
                        ADD SI,2
                        LOOP AVERAGE;
 
            
            MOV CX,100
            MUL CX
            DIV DI
            
            CMP AX,10000
            JAE BAI
            ADD AX,5;四舍五入
            MOV BX,AX
 
             CALL HEN_TO_BCD ;结果在转换为BCD码
            MOV DX,OFFSET STRINGAVG ;显示输出AVG
                            MOV AH,09H
                            INT 21H 
 
            MOV DL,BH
                 MOV CL,4
                            SHR DL,CL
                            ADD DL,30H
                            MOV AH,02H;输出千位数
                            INT 21H
        
                MOV DL,BH   ;输出百位数
                           AND DL,0FH
                           ADD DL,30H
                           MOV AH,02H
                           INT 21H
               MOV DL,2EH      ;输出小数点
                            MOV AH,02H
                            INT 21H   
                                     
                    MOV DL,BL       ;输出十位数
                            MOV CL,4
                            SHR DL,CL
                            ADD DL,30H
                            MOV AH,02H
                            INT 21H
            JMP N
BAI:            MOV DX,OFFSET STRINGAVG ;显示输出AVG
                            MOV AH,09H
                            INT 21H 
            CALL      BAI0                    
N:                        CALL NEXT    
                        RET   
PRINTAVG ENDP       
 
;========================BCD转换为十六进制========================
BCD_TO_HEN PROC NEAR
 
        PUSH CX
        PUSH AX  
        PUSH DX 
        PUSH SI
        PUSH DI 
        XOR DX, DX
        
        MOV AX, BX 
        PUSH AX
        AND AX,0F000H;取千位数
        MOV CL, 4    ;移位取出千位数
        SHR AX, CL
        MOV DH, AH
        POP AX  
        
        PUSH AX
        AND AX, 0F00H  ;取百位数
        MOV DL, AH 
        POP AX  
        
        PUSH AX
        MOV AX, DX
        AAD 
;指令是在作除法前用于调整寄存器AH和AL之值,它是把二个寄存器中单BCD码组成一个十进制数值,其调整规则如下:
;AL←AH*10+AL,AH←0
;受影响的标志位:PF、SF和ZF(AF、CF和OF等都是无定义)
;MOV AX, 0502H MOV BL, 10D AAD          ;AH=0, AL=52H DIV BL        ;AH=2(余数), AL=5(商)                                 
        MOV DI, 100  ;乘100
        MUL DI                                 
        MOV SI, AX
        POP AX 
        
        PUSH AX       
        MOV CL, 4    ;移位取出十位数
        SHR AX, CL
        AND AX, 000FH  
        MOV DH, AL
        POP AX  
        
        PUSH AX
        AND AX, 000FH   ;取AL低四位,个位数
        MOV DL, AL 
        POP AX 
        
        MOV AX, DX
        AAD 
        ADD AX, SI
        
        MOV BX, AX ;转换结果给BX         
        
        POP DI
        POP SI
        POP DX      
        POP AX 
        POP CX
        RET
BCD_TO_HEN ENDP
;========================4位十六进制转换为BCD========================           
HEN_TO_BCD PROC NEAR
        PUSH AX
                PUSH CX
        PUSH DX;保证原函数的寄存器的值不变,因此先放入栈,该子过程结束后在pop
        XOR DX,DX
        MOV AX,BX
        MOV BX,0000H
                MOV CX,1000
                DIV CX;先将数据除以1000,得到千位的值
                                ;比如数据为4321
                                ;那么此时得到的商4放在AX中,得到的余数321放在DX中
        
        MOV CL,4
        AND AX,000FH;取AX中低四位,也就是四位二进制表示一个十进制数即bcd码
        ADD BX,AX;把上面结果也就是4放在BX
        ROL BX,CL;把得到的结果循环左移4位,也就是放在了第二位十六进制数的位置也就是0040h
        
       
                MOV AX,DX ;余数再放到AX里面
                MOV CL,100;余数再除100,也就是321除100
                DIV CL;商放在AL里,余数放在AH里
        PUSH AX;入栈,保存AX数值
                AND AX,000FH;取低四位也就是3
        ADD BX,AX;加和后就是0043
        MOV CL,4
        ROL BX,CL;再左移,0430
        POP AX;把刚才的数据取出
 
                MOV AL,AH;余数再除10
                AND AX,00FFH;取刚才的余数
                MOV CL,10
                DIV CL;商2放在AL,余数1放在AH
               AND AX,000FH
        ADD BX,AX;取低四位也就是2放在BX,也就是0432
        MOV CL,4
        ROL BX,CL;再左移
 
                ADD BL,AH;放入,那么此时BX结果为4321
 
              POP DX
                POP CX
                POP AX;将原过程的寄存器值取出对应首部的push
         RET
HEN_TO_BCD ENDP
;========================换行========================
NEXT: 
    mov dl,0ah;换行对应ASCII码
    mov ah,02h
    int 21h
    mov    dl,0dh;回车对应的ASCII码
    mov    ah,02h;输出DL内容
    int    21h
    ret
;========================打印换行线========================
LINE:
    mov dx,offset STRINGLINE;;STRINGLINE        DB                   
    mov ah,09h;
                ;显示字符串
                ;DS:DX=串地址
                ;'$'结束字符串
    int 21h
    call NEXT 
    ret
;========================输出100%========================
ALL:
    mov dx,offset ALL100;ALL100             DB            '100%$'
    mov ah,09h
    int 21h
    
    ret
;========================输出100.0========================
BAI0:
    mov dx,offset BAI00;BAI00            DB            '100.0$'
    mov ah,09h
    int 21h
    
    ret
 
 
;========================打印百分数========================
PERCENT PROC NEAR
            PUSH BX
            PUSH CX
            PUSH AX
            PUSH DX;保存调用前寄存器值
            XOR DX,DX
            XOR AX,AX;寄存器清零
            
            MOV AX,BX;BX里存的是对应分数的人数
            MOV CX,10000
            CWD;把一个字符扩展为双字符,将AX内容扩展到DX AX。
            ;规则:若AX最高位=1,则执行后DX=FFFFH;若AX最高位=0,则执行后DX=0000H。
            MUL CX;防止出小数
            ;被乘数	乘数	乘积
;AL	;reg/mem8	AX
;AX	;reg/mem16	DX:AX
;EAX	;reg/mem32	EDX:EAX
            DIV DI
            CMP AX,10000;
            JAE ALL0;无符号左大于右跳转说明占比百分之百
            ADD AX,5;四舍五入
            MOV BX,AX
             CALL HEN_TO_BCD ;结果在转换为BCD码
 
             MOV DL,BH
             MOV CL,4
                        SHR DL,CL
                        ADD DL,30H
                        MOV AH,02H;输出千位数
                        INT 21H
        
            MOV DL,BH   ;输出百位数
                       AND DL,0FH
                       ADD DL,30H;转换为ASCII码
                       MOV AH,02H
                       INT 21H
 
           MOV DL,2EH      ;输出小数点
                        MOV AH,02H
                        INT 21H   
                                     
            MOV DL,BL       ;输出十位数
                        MOV CL,4
                        SHR DL,CL
                        ADD DL,30H
                        MOV AH,02H
                        INT 21H
                                                                                         
 
            MOV DL,25H
            MOV AH,02H
            INT 21H;    百分号
 
            MOV DL,20H
            MOV AH,02H
            INT 21H;    空格
            JMP M
ALL0:          CALL ALL
M:        POP DX
                POP AX
                POP CX
                POP BX
 
                RET
PERCENT ENDP
;====================打印16进制数为BCD整数====================
PRINTINT PROC NEAR
            PUSH BX
            PUSH CX
            PUSH AX
            PUSH DX;保存原过程寄存器值
 
            MOV AX,BX
            MOV CX,99
BX_100:     ADD  BX,AX
            LOOP BX_100;循环一百次,防止出现小数的情况
            ADD BX,5;四舍五入    
            CALL HEN_TO_BCD ;结果在转换为BCD码
            MOV DL,BH
            MOV CL,4
            SHR DL,CL;右移4位就是比如bcd码在BX中是4321,那么现在就是取43放DL,在右移最后是04
            ADD DL,30H
            MOV AH,02H;输出千位数
            INT 21H
        
            MOV DL,BH   ;输出百位数
            AND DL,0FH;取百位
            ADD DL,30H
            MOV AH,02H
            INT 21H
 
            MOV DL,20H ;输出空格
            MOV AH,02H
            INT 21H
            
 
            POP DX
            POP AX                                                                                         
            POP CX
            POP BX
            RET       
PRINTINT ENDP
;====================打印BCD整数====================
PRINTBCD PROC NEAR ;打印函数                              
                                CMP BH,00000001B ;判断百位是否为1;上一步BX中存放最大值
                                JNC B;cf等于零跳转,也就是没有进位

                                ;比较两个无符号数CMP
                                ;CMP结果	      ZF(零标志)CF(进位标志)
                                ;目的操作数 < 源操作数	0	1
                                ;目的操作数 > 源操作数	0	0
                                ;目的操作数 = 源操作数	1	0
                               ; 比较两个有符号数
                               ; CMP结果	        标志位
                               ;; 目的操作数 < 源操作数	SF ≠ OF
                               ; 目的操作数 > 源操作数	SF=OF
                               ; 目的操作数 = 源操作数	ZF=1
                                          
A:                              MOV DL,BL      ;输出十位数
                                MOV CL,4
                                SHR DL,CL
                                ADD DL,30H;取ASCII码
                                MOV AH,02H
                                INT 21H
                                
                                MOV DL,BL ;输出个位数
                                AND DL,0FH
                                ADD DL,30H
                                MOV AH,02H
                                INT 21H
                                
                                MOV DL,20H ;输出空格
                                MOV AH,02H
                                INT 21H                                                                                            
                                JMP D 
                                
B:                              MOV DL,BH  ;输出百位数
                                AND DL,0FH
                                ADD DL,30H
                                MOV AH,02H;取百位数显示输出
                                INT 21H
                                JMP A     
D:                              RET       
PRINTBCD ENDP

CODE     ENDS   
END       START 

总结

代码以及源程序可去主页下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值