先说明一点,本次编程,发现了书中错误之处,书中在讲解MUL指令时,两个相乘的数,如果是8位,一个默认应该存储在AL中,书中错写成AH。导致笔者在编写程序时错误使用AH。。。特此纠正。。
思路简单,就是定位显存缓冲区位置,然后把对应字符送到该位置即可。
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
stack segment
dw 8 dup(0)
stack ends
code segment
start:
mov dh,8 ;显存页对应的行
mov dl,3 ;显存页对应的列
mov cl,2 ;字符属性,这里是绿色
mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
mov si,0 ;data数据偏移地址
call show_str ;调用显示字符子程序
all:
jmp short all ;一直循环,为了看效果
mov ax,4c00h
int 21h
show_str:
push ax ;把子程序中使用到的寄存器值入栈
push es
push dx
push bx
push si
push di
mov ax,0b800h ;显存缓冲区段地址
mov es,ax
mov al,160 ;计算行上的偏移量
mul dh
mov bx,ax
mov al,2 ;计算列上的偏移量
mul dl
add bx,ax ;得到最终偏移地址,存入bx
mov di,0 ;辅助计算显存对应的偏移地址
mov al,cl ;把cl中字符属性值存入al。
mov ah,0 ;后面还要用cl判断当前字符是否是0
show:
mov cl,ds:[si] ;把单个字符存入cl
jcxz ok
mov es:[bx+di],cl
mov es:[bx+di+1],al
inc si
add di,2
jmp short show
ok:
pop ax ;把子程序中使用到的寄存器值还原
pop es
pop dx
pop bx
pop si
pop di
ret
code ends
end start
assume cs:code
code segment
start:
mov ax,4240h
mov dx,000fh
mov cx,0Ah
call divdw
mov ax,4c00H
int 21h
divdw:
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
div cx
mov cx,dx
mov dx,bx
ret
code ends
end start
计算机里存储的二进制数字,转换成十进制,并显示在屏幕指定位置。
assume cs:code
data segment
db 10 dup(0)
data ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0 ;data数据偏移地址
call dtoc
mov dh,8 ;显存页对应的行
mov dl,3 ;显存页对应的列
mov cl,2 ;字符属性,这里是绿色
call show_str ;调用显示字符子程序
all:
jmp short all ;一直循环,为了看效果
mov ax,4c00h
int 21h
dtoc:
push si
push dx
push cx
push bx
push ax
mov si,0
mov bx,10 ;除10取余,转为10进制
change:
mov dx,0
div bx
mov cx,ax ;商存入cx,便于使用jcxz
jcxz last
add dx,30h ;转为ASCII对应的数字
push dx
inc si ;统计余数个数,便于后续循环
jmp short change
last: ;最后一次除法
add dx,30h
push dx
inc si
mov cx,si
mov si,0
s:
pop ds:[si]
inc si
loop s
exit_dtoc:
pop ax
pop bx
pop cx
pop dx
pop si
ret
show_str:
push ax ;把子程序中使用到的寄存器值入栈
push es
push dx
push bx
push si
push di
mov ax,0b800h ;显存缓冲区段地址
mov es,ax
mov al,160 ;计算行上的偏移量
mul dh
mov bx,ax
mov al,2 ;计算列上的偏移量
mul dl
add bx,ax ;得到最终偏移地址,存入bx
mov di,0 ;辅助计算显存对应的偏移地址
mov al,cl ;把cl中字符属性值存入al。
mov ah,0 ;后面还要用cl判断当前字符是否是0
show:
mov cl,ds:[si] ;把单个字符存入cl
jcxz exit_show_str
mov es:[bx+di],cl
mov es:[bx+di+1],al
inc si
add di,2
jmp short show
exit_show_str:
pop ax ;把子程序中使用到的寄存器值还原
pop es
pop dx
pop bx
pop si
pop di
ret
code ends
end start