《汇编语言第三版》王爽学习历程——实验10(3)

本文介绍了一个用于将十六位整数转换为ASCII码字符串并在屏幕指定位置显示的汇编语言子程序。该程序使用除10取余的方法逆序存储数字,并通过栈操作实现。文中还详细介绍了如何计算屏幕上的显示位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编写子程序——数值显示

新人自己分析的,希望大神给予意见~!

问题描述:
将数值显示到屏幕上

子程序描述
名称:dtoc
功能:将word型数据转变为表示十进制数的字符串,字符串以0结尾
参数:(ax)=word数据, ds:si指向字符串的首地址
返回:无

分析
个人认为这个子程序还是蛮简单的。
1、并不是内存中存的多少,在屏幕上就能显示多少,因为显卡遵循ASCII码,除非存的数正好和该数的编码是一样的,那么就比较好了,不过事实并不是这样。
由书中提示可以知道,十进制数码字符对应的ASCII码 = 十进制数码+30H。
2、既然是一个一个显示,那就必须要把一个多位数拆成一个一个的数,书中也给出了方法,除10取余,只不过除完后必须逆序存入数据段,如:12666,拆完后是66621,。讲到逆序,就很容易想到用栈了。

汇编代码:

assume cs:codesg

datasg segment
        db 16 dup(0)
datasg ends

stacksg segment
        db 64 dup(0)
datasg ends

codesg segment
 start:
        mov ax, stacksg
        mov ss, ax
        mov sp, 40h     ;初始化栈

        mov ax, datasg
        mov ds, datasg      
        mov si, 0       ;初始化数据段

        mov ax, 12666
        call dtoc

        mov dh, 1
        mov dl, 3
        mov cl, 2
        call show_str

        mov 4c00h
        int 21h

 dtoc:  
        push ax
        push bx         ;用来存放除数0AH
        push cx         ;用来判断是否除完
        push dx         ;用32位除法,用来保存余数
        push si         ;数据段偏移地址
        push di         ;计算数的位数

        mov cx, 0
        mov dx, 0
        mov di, 0
        mov bx, 0ah     ;寄存器的初始化

 s0:                ;开始短除法取余数并入栈
        div bx
        mov cx, ax
        push dx         ;余数入栈
        mov dx, 0       ;重置被除数高位
        inc di
        jcxz ok         ;若商为0,则取余数已经完成
        jmp short s0



 ok:                    ;完成取余后,需要入数据段
        mov cx, di          ;出栈次数
 s1:
        pop ax
        add ax, 30h         ;对应ascii字符码
        mov ds:[si], al     ;逆序入数据段
        inc si
        loop s1

        pop di
        pop si
        pop dx
        pop cx
        pop bx
        pop ax
        ret


 show_str:
        push es         ;把子程序中用到的寄存器入栈保存原有数据
        push ax
        push bx
        push dx
        push cx         ;保存字符属性
        push di
        push si

        mov ax, 0b800h   
        mov es, ax      ;初始化显示缓冲区

        mov al, 0a0h    ;进行行的计算,来确定行的偏移地址
        sub dh, 1
        mul dh
        mov bx, ax     ;行计算完毕

        mov al, 2      ;进行列的计算,来确定列的偏移地址
        sub dl, 1
        mul dl
        mov di, ax     ;列计算完毕

        mov al, cl 
        mov cx, 0       ;重置一下寄存器,以后需要用它判断是否结束       
s_str:
        mov cl, ds:[si]
        jcxz ok_str            ;判断如果字符读取完了就可以跳出循环了
        mov es:[bx][di], cl    ;字符送入完毕
        mov ex:[bx][di+1], al  ;字符属性送入
        inc si
        add di, 2
        jmp shrot s_str            ;字符的循环复制

ok_str:
        pop si                 ;相关寄存器出栈保持调用者原有寄存器数据不变
        pop di
        pop cx
        pop dx
        pop bx
        pop ax
        pop es
        ret
codesg ends

end start

数值:12666, 在1行3列以绿色字显示:
这里写图片描述

数值:17573, 在10行7列以7号字体显示:
这里写图片描述

没有清屏是因为需要一个参照物来比较是否在N行M列显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值