注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

第8章练习: put_string 与 put_char 编写练习.  

2013-01-24 16:11:09|  分类: 《x86汇编语言: |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
; 第8章练习: 显示字符串与字符子程序
; put_string: 显示字符串子程序,字符串以数值0结束
; put_char: 显示字符子程序,可以跟踪光标状态,可以识别回车与换行.

  put_char 程序流程图: 
第8章练习: put_string 与 put_char 编写练习. - sangguowei2002 - 编程学习
 

; 以下代码编译以后写到MBR运行.
;主程序,定义字符串,用于测试子程序put_string与put_char
; 主程序开始====================================================
section show vstart=0x7c00
jmp start

;字符串定义=========================
message   db 'Hello,world.',0xd,0xa
db 0xd,0xa
db 0xd,0xd,0xd
db 0xa,0xa,0xa
db 'put_char test:',0xa
db '--sgw888',0xa,0xa
times 16 db 0xa
db 'test',0xd,0xa
times 16 db 'char.'
db 0
;字符串结束==========================

start:
xor ax,ax
mov ds,ax
mov ax,0xb800
mov es,ax
mov bx,0
mov cx,25*80
s1:
mov byte [es:bx],' '
inc bx
mov byte [es:bx],0xa
inc bx
loop s1 ;更改屏幕颜色,为了使演示效果更明显.

mov bx,message
call put_string
jmp $
;主程序结束====================================================

;=========================================================================================
;子过程开始===============================
; put_string 子过程 入口参数: DS:BX 指向字符串.
put_string:
push bx
push cx
put_string_s:
mov cl,[bx]
or cl,cl
jz put_string_ret
call put_char
inc bx
jmp put_string_s
put_string_ret:
pop cx
pop bx
ret
;========================================================================================

;========================================================================================
;put_char子过程 入口参数: CL为要显示的字符
put_char:
push ax
push bx
cmp cl,0x0d ;判断是不是回车符
jnz put_0a
call get_cursor ;获得当前光标位置,存放到AX.(调用获取光标位置子过程)
mov bl,80
div bl
mul bl ;计算当前行的行首坐标
call update_cursor ;更新光标到行首(调用更新光标位置子过程)
jmp put_char_ret

put_0a:
cmp cl,0x0a ;判断是不是换行符
jnz put_ch
call get_cursor ;获得当前光标位置
add ax,80 ;每行80列
cmp ax,80*25 ;比较是否超过一屏的范围
jb put_0a_1
call roll_screen                ;调用滚屏子过程
jmp put_char_ret
put_0a_1:
call update_cursor
jmp put_char_ret

put_ch:
call get_cursor ;获得当前光标位置
shl ax,1 ;光标位置*2=显示偏移
push es
mov bx,0xb800
mov es,bx
mov bx,ax
mov [es:bx],cl ;显示字符
pop es
shr ax,1
inc ax
cmp ax,25*80
jb put_ch_1
call roll_screen
mov ax,24*80 ;第24行行首
put_ch_1:
call update_cursor
jmp put_char_ret

roll_screen:
push ds
push es
push si
push di
push cx
mov cx,0xb800
mov ds,cx
mov es,cx
mov cx,24*80 ;循环次数
mov si,1*80*2
mov di,0
cld
rep movsw
mov cx,80
mov si,24*80*2 ;24行,行从0开始计数.
screen_cls:
mov byte [si],' '
add si,2
loop screen_cls ;清除最后一行
pop cx
pop di
pop si
pop es
pop ds
ret

put_char_ret:
pop bx
pop ax
ret

;===============================================
;获得当前光标位置,并保存到AX中. 用到了寄存器AX ,DX已保护
get_cursor:
push dx
mov dx,0x3d4
mov al,0xe
out dx,al
inc dx
in al,dx
mov ah,al
dec dx
mov al,0xf
out dx,al
inc dx
in al,dx ;获得当前光标,存放在ax
pop dx
ret
;================================================
;更新光标位置,位置由AX指定
update_cursor:
push ax
push bx
push dx
mov bx,ax
mov dx,0x3d4
mov al,0xe ;0xe是光标高8位
out dx,al
inc dx
mov al,bh
out dx,al
dec dx
mov al,0xf ;0xf是光标低8位
out dx,al
inc dx
mov al,bl
out dx,al
pop dx
pop bx
pop ax
ret
;======================================================================================
times 510-($-$$) db 0
db 0x55,0xaa
  评论这张
 
阅读(32)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017