马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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
|