课程设计1(p211)、
课程设计1(p211)
# 执行结果
# code
; DATE: 20190614 ; DESCRIPTION: 在屏幕上按格式显示数据 assume cs:code data segment db 16 dup (0) ; 用于临时保存数据转字符串的结果 ; 年份 db '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983' db '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992' db '1993', '1994', '1995' ; 收入 dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97497, 140417, 197514 dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000 ; 雇员 dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226 dw 11542, 14430, 15257, 17800 data ends code segment start: mov ax, data mov ds, ax mov si, 0 ; ds:si 指向data段中的自定义字符串空间 call company mov ax, 4c00H int 21H ; 数据处理并显示 company: push ax push bx push cx push dx push si push di ; 保护现场 mov bx, 16 ; ds:bx 指向年份 mov di, 16 add di, 168 ; ds:di 指向雇员 mov dh, 2 ; 屏幕上显示行 mov cx, 21 ; 一共要显示21行数据 year: push cx ; 颜色cl将覆盖cx mov dl, 10 ; 屏幕上显示列 mov cl, 2 ; 颜色 ; 年份 mov ax, [bx] mov [si], ax mov ax, [bx+2] mov [si+2], ax ; 直接将4Bytes年份复制到ds:si mov ax, 0 mov [si+4], ax ; 字符串以0结尾 call show_str ; 收入 push dx ; div中dx为被除数高16位 mov ax, [bx+84] ; ax存放被除数低16位 mov dx, [bx+86] ; dx存放被除数高16位 call ddtoc pop dx add dl, 10 ; 屏幕上显示列右移10列 call show_str ; 雇员 mov ax, [di] ; ax存放16位的被除数 call dtoc add dl, 15 ; 屏幕上显示列右移15列 call show_str ; 人均收入 push dx ; div指令用dx存储余数 mov ax, [bx+84] ; ax存放被除数低16位 mov dx, [bx+86] ; dx存放被除数高16位 div word ptr [di] pop dx call dtoc ; 结果的商存放在ax中 add dl, 10 ; 屏幕上显示列右移10列 call show_str pop cx inc dh ; 屏幕上显示行下移一行 add bx, 4 ; 下一个年份和收入数据 add di, 2 ; 下一个雇员数据 loop year pop di pop si pop dx pop cx pop bx pop ax ; 恢复现场 ret ; 返回 ; 名称:dtoc ; 功能:将word型数据转变为表示十进制数的字符串,以0结尾 ; 参数:(ax)=word型数据,ds:si指向字符串的首地址 ; 返回:无 dtoc: push ax push bx push cx push dx push si mov bx, 10 division: mov dx, 0 ; 被除数的高16位 div bx add dx, 30H ; dx为余数,转为字符 push dx ; 余数入栈 inc si ; 通过si统计长度 mov cx, ax ; ax为商 jcxz save0 jmp short division save0: mov cx, si mov si, 0 s2: pop [si] ; 余数出栈,保存到ds:si inc si ; 取巧,出栈2Bytes,但si+1;末尾以0结尾 loop s2 pop si pop dx pop cx pop bx pop ax ret ; 名称:ddtoc ; 功能:将dword型数据转变为表示十进制数的字符串,以0结尾 ; 参数:(ax)=dword低16位,(dx)=dowrd高16位,ds:si指向字符串的首地址 ; 返回:无 ddtoc: push ax push cx push dx push si push di mov di, 0 change: mov cx, 10 ; cx为除数 call divdw add cx, 30H ; cx为余数, 加48转为字符 push cx ; 余数入栈 inc di ; 通过di统计余数个数 mov cx, ax or cx, dx ; 判断商是否为0 jcxz save jmp short change save: mov cx, di s1: pop [si] ; 余数出栈,保存到ds:si inc si ; 取巧,出栈2Bytes,但si+1;末尾以0结尾 loop s1 pop di pop si pop dx pop cx pop ax ret ; 名称:divdw ; 功能:不会产生溢出的除法,被除数为dword,除数为word,结果为dword ; 参数:(ax)=dword低16位 (dx)=dword高16位 (cx)=除数 ; 返回:(dx)=结果高16位 (ax)=结果低16位 (cx)=余数 divdw: push bx ; ax cx dx为返回值 push ax ; 被除数低16位 ; 被除数的高16位除法 mov ax, dx mov dx, 0 div cx ; 被除数的低16位除法 mov bx, ax ; 高16位除法的商暂移到bx pop ax div cx ; 结果返回 mov cx, dx ; 低16位除法的余数移到cx mov dx, bx ; 高16位除法的商移到dx pop bx ret ; 名称:show_str ; 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串 ; 参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79) ; (cl)=颜色, ds:si指向字符串首地址 ; 返回:无 show_str: push ax push cx push dx push si push di push es mov ax, 0b800H mov es, ax ; 显示缓冲区 b8000 ~ b8ffff mov al, 160 ; 一行80个字符,加上颜色属性,占160Bytes mul dh ; 乘以行号 mov di, ax mov al, 2 ; 内容1Byte、属性1Byte mul dl ; 乘以列号 add di, ax ; es:di指向屏幕指定位置对应的显示缓冲区 mov ah, cl ; 高位字节存储颜色属性 s0: mov ch, 0 mov cl, [si] ; 给定的字符串以0结尾 jcxz ok mov al, cl ; 低位字节存储字符ASCII码 mov es:[di], ax inc si ; 下一个字符 add di, 2 ; 屏幕显示位置右移2Bytes jmp short s0 ok: pop es pop di pop si pop dx pop cx pop ax ret code ends end start
文章来源: https://blog.csdn.net/trb331617/article/details/92060478