|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- assume cs:code,ds:data
- data segment
- db 10 dup (0)
-
- data ends
- code segment
- start:
- mov ax,12666 ;显示的数据
-
- ;定位数据存放的段地址
- mov bx,data
- mov ds,bx
- mov si,0
-
- ;解析每个字符,将以ascii码存放
- call dtoc
- mov dh,8 ;初始化打印的位置
- mov dl,3
- mov cl,0cah
- call show_str ;开始打印字符串
- mov ax,4c00h
- int 21h
- dtoc: ;以下寄存器将要被用到,所以保存以前的值
- push dx
- push cx
- push ax
- push si
- push bx
- ;bx用来记录个数(例如: 1234 也就是 4 个)
- mov bx,0
-
- ;10进制取余 除以10d
- s1: mov cx,10d
- mov dx,0 ;清空保存余数的寄存器
-
- ;刚开始 ax 存放的是 12666
- div cx
-
- ;除完之后 ax 又保存商 ,商是作为下一次的被除数,余数保存在dx中
- mov cx,ax
-
- add dx,30h ;将余数加上30h得到相应的ASCII码
- push dx ;将每个数字保存起来
- inc bx ;记录存放的次数 +1
- ;如果商为 0 的话,就不需要在进行除法运算了 ,刚才把ax商,保存在cx中,就是因为 jcxz 只判断cx 的值是否为0
- jcxz s2
-
- jmp short s1 ;返回到 s1 标号处,继续循环
-
- s2:
- mov cx,bx ;总共有bx位进栈了,所以循环次数为bx
- mov si,0
-
- s3: pop ax ;s3实现将栈中的数据依次出栈放到指定内存中
- mov [si],al ;因为余数8位存放的是8位,所以存放在al中
- inc si ;定位下一个存放的位置
- loop s3
- ;还原以前的值
- okay: pop bx
- pop si
- pop ax
- pop cx
- pop dx
- ret ;数值显示的子程序定义结束
-
- show_str: ;显示字符串的子程序已经在第一题中说明,在此不再赘述。
- push bx
- push cx
- push si
- ;行偏移
- mov al,0A0h
- dec dh
- mul dh
-
- ;列偏移
- mov bx,ax
- mov al,2
- mul dl
-
- ;列偏移加上行偏移
- sub ax,2
- add bx,ax
-
- ;显存段地址
- mov ax,0B800h
- mov es,ax
-
- mov di,0
- mov al,cl ;颜色
- mov ch,0
- ;注意 假如数字是 1234 ,前面我们入栈出栈 在1234 存入到内存的时候, 1的偏移地址是0 ,2的偏移地址是1 一次类推(这就由前面的入栈出栈导致的)
- s: mov cl,ds:[si]
- jcxz ok ;我们将 1234 (假如是1234) 解析每个数字,以ascii码 存放到内存的时候,我们并没有 给他一个结尾的标志0 ,那为什么我们可以通过jcxz 来判断数字是否结束?
- ;刚才我实验了一下,我们不需要在最后加0 他好像自动回添加 ,或者说我实验的时候,刚好1234 后面一个字节 的数字是0
- mov es:[bx+di],cl ;显示每个数字
- mov es:[bx+di+1],al ;指定每个数字的属性
-
- inc si ;定位下一字符数据的位置
- add di,2 ;定位下一字符数据要显示的位置
- jmp short s
- ok: pop si
- pop cx
- pop bx
-
- ret
- code ends
- end start
复制代码
|
|