put_char

光标的位置

CRT Controller Data Registers
中索引为 0Eh 的 Cursor Location High Register 寄存器和索引为 0Fh 的 Cursor Location Low Register 寄存器,这两个寄存器都是 8 位长度,分别用来存储光标坐标的低 8 位和高 8 位地址。访问 CRT controller 寄存器组的寄存器,需要先往端口地址为 0x3D4 的 Address Register 寄存器中写入寄存器的索引,再从端口地址为 0x3D5 的 Data Register 寄存器读、写数据。

获得的光标

注意:我们获得的光标的位置是0~1999,表示2000个位置,一个位置表示一个字符,我们要设置字符之前要乘2,然后就可以设置要显示的字符,和字符的属性,低字节显示的是字符,高字节是要显示字符的属性。

global put_char 
put_char:
    pushad    
    mov ax,SELECTOR_VIDEO
    mov gs,ax

    mov dx,0x3d4     
    mov al,0x0e
    out dx,al     	;0x3d4的address register寄存器中写入寄存器的索引
    mov dx,0x03d5
    in al,dx      	; 在从端口地址0x3d5的data register寄存器中读写数据
    mov ah,al     	; 我们获取了坐标的高8位

    mov dx,0x3d4
    mov al,0x0f
    out dx,al     
    mov dx,0x03d5
    in al,dx     

    mov bx,ax      		;bx成为了下一个待打印字符的光标作标值
    mov ecx, [esp+36]   ; 获取需要打印的字符
    cmp cl,0xd          ;CR是0x0d,LF是0x0a

    jz .is_carriage_return ;回车
    cmp cl,0xa
    jz .is_line_feed      ;换行

    cmp cl,0x8             ;退格
    jz .is_backspace
    jmp .put_other

.is_backspace:    
    dec bx
    shl bx,1                ;相当于乘以2
    mov byte [gs:bx],0x20   ;将待删除的字节补为0或空格
    inc bx
    mov byte [gs:bx],0x07
    shr bx,1                 ;除以2                 
    jmp .set_cursor

.put_other:
    shl bx,1       
    mov [gs:bx],cl
    inc bx
    mov byte [gs:bx],0x07;字符属性
    shr bx,1
    inc bx
    cmp bx,2000  ;如果不小于2000,就需要滚屏幕    
    jl .set_cursor          

.is_line_feed:            ;换行
.is_carriage_return:      ;回车
    xor dx,dx
    mov ax,bx
    mov si,80
    div si
    sub bx,dx

.is_carriage_return_end:
    add bx,80
    cmp bx,2000
.is_line_feed_end:
    jl .set_cursor

.roll_screen:  
    cld
    mov ecx,960
    mov esi,0xc00b80a0
    mov edi,0xc00b8000
    mov ebx,3840
    mov ecx,80
.cls:
    mov word [gs:ebx],0x0720
    add ebx,2
    loop .cls
    mov bx,1920  ; 最后一行的的首字符

.set_cursor:
    mov dx,0x03d4
    mov al,0x0e
    out dx,al
    mov dx,0x03d5
    mov al,bh
    out dx,al

    mov dx,0x3d4
    mov al,0x0f
    out dx,al
    mov dx,0x3d5
    mov al,bl
    out dx,al
.put_char_done:
    popad
    ret
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值