免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1099 | 回复: 0
打印 上一主题 下一主题

从最底层实现汉字输出,一个中文启动界面的实现方法(转) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-23 19:17 |只看该作者 |倒序浏览
从最底层实现汉字输出,一个中文启动界面的实现方法[ 07-27 21:19 2005, by xujiwei, from
未知
] [ 字体大小:
[url=javascript:SetFontSize('articlecontentview',12);][/url]

[url=javascript:SetFontSize('articlecontentview',14);][/url]

[url=javascript:SetFontSize('articlecontentview',16);][/url]
]
版权说明:本文为网上收集,转载时请注明原作者及保留原始链接
呵呵,要再次感谢赵博的书给我的启发,现在想什么就可以自己去实践,这种感觉真好。这两天我实践了一个中文显示问题,终于成功,贴出来与大家共享。
   通过实践,大概了解图形模式下的工作方式,和汉字支持的基本实现方法。我的工作是让系统启动后在屏幕上显示“汉字操作系统”五个汉字
   说明:这里只介绍使用点阵字库。
   准备工作:
   1、首先必须创建相应的点阵信息
          我们来创建一个16×16的两个汉字的点阵,其实很简单,你在纸上画一个行列
      各有16个格子的方块出来,然后按其大小,在里面写一个字,比如”成“,建
      议你写得粗一点,这时你会发现有些格子中被字的笔画穿过,有的仍是空格
      子,现在你把没有笔画穿过的记为0,有笔画的记为1,从第一行开始,将这个
      16×16的“点阵”的信息记下来,由于每行有16个位,所以需要2个字节来记录一
      行,共16行,所以共需2×16=32个字节来保存一个字的“点阵”.
         比如:汉-->00000h,04008h,037fch,01008h,08208h,06208h,02210h,00910h
                    01120h,020A0h,0E040h,020A0h,02110h,02208h,0240Eh,00804h
         当然我这个“点阵”是从别的字库里载取出来的,但上面的方法绝对是可行的
       点阵本质上就是这样生成的。
   2、编写一个显示一个像素的子程序
          面临的任务:在图形模式下,在屏幕上打印一个像素点
          分析:
              所需的变量:初始的左上角的坐标值x0,y0
              默认参数:  默认分辨率为640×480×16色模式
                          (因为这是VGA标准BIOS支持的模式)
                          默认颜色为黑底黄字
          实现:(参考了《VGA实用编程技术》罗健军 清华大学出版社 1995)
               ;功能:
               ;     在指定的屏幕位置用指定的颜色画一个点
               ;入口参数:
               ;        bx = x0     象素在屏幕上的X坐标
               ;        ax = y0     象素在屏幕上的Y坐标
               ;        cl = color  象素的颜色值
                writePix proc
                    linelen = 80      ;640*480*16色模式下一条扫描线占用的字节数
                                      ;=Width/8
                         ;计算象素点的位置
                         push es
                         push bp
                         push dx
                         push ax
                         push di
                         push cx
                         push bx
                        
                        
                         mov bp,sp
                         mov cl,3
                         shr bx,cl    ;X0/8
                         mov cx,linelen
                         mul cx
                         add ax,bx           ;至此ax中为像素点的偏移,dx为页号
                         mov di,ax
                        
                         ;设置映象屏蔽寄存器
                         mov dx,sequen_ctl
                         mov al,2
                         out dx,al
                         inc dx
                         mov al,0fh   ;四个位面全部充许写
                         out dx,al
                         ;选择写方式2
                         mov dx,graphi_ctl
                         mov al,5
                         out dx,al
                         inc dx
                         mov al,2
                         out dx,al
                         ;计算屏蔽码,并设置位屏蔽寄存器
                         dec dx
                         mov al,8
                         out dx,al
                         mov cx,[bp]  ;取出X坐标
                         and cl,7
                         mov al,80h
                         shr al,cl
                         inc dx
                         out dx,al
                         ;写数据
                         mov ax,vgaseg  ;ES段指向显存地址0a000h
                         mov es,ax
                         mov ax,[bp+2]     ;取颜色值
                         mov ah,es:[di]    ;读一次使屏蔽寄存器有效
                         mov es:[di],al ;写入显示存储器
                         pop  bx
                         pop  cx
                         pop  di
                         pop  ax
                         pop  dx
                         pop  bp
                         pop  es
                         ret
                writePix endp
   3、编写一个输出一个汉字图形字符的子程序,有了2的基础这一步显得比较容易,实现
      如下:
             ;在图形模式下显示一个汉字
             ;输入参数:
             ;  BX=x0 初始左上角X坐标
             ;  AX=y0 初始左上角Y坐标
             ;  CX=color  其实只是cl表示颜色
             ;  ds:si=buff 字符点阵信息首地址
             ;返回值:无
             DispZhC proc
                push si
                push bp
                push ax
                push bx
                push cx
                push dx
                mov bp,sp
                xor dx,dx     ;dx 当前行
                jmp a1
             Disp:
                inc si
                inc si        ;指向下一个字
                inc dx        ;行记数加一
             a1:
                cmp dx,16     ;当前行为0-15,因为是16*16点阵
                je  Done
                xor cx,cx     ;cx 当前列初始化
                mov bx,word ptr [si]     ;读入一行的点阵信息,一行两个字节表示
             DispL:
                cmp cx,16
                je  Disp       ;换行      
                or  cx,cx        ;清零CF
                shl bx,1
                jc  DispP             ;如果当前位是1,显示一个点
                inc cx
                jmp DispL
             DispP:
                push ax
                push bx
                push cx
                mov ax,[bp+6]
                add ax,dx
                mov bx,[bp+4]
                add bx,cx
                mov cx,[bp+2]  ;颜色值在cl中
                call writePix
                pop cx
                inc cx
                pop bx
                pop ax
                jmp DispL
             Done:
                pop dx
                pop cx
                pop bx
                pop ax
                pop bp
                pop si
                ret
             DispZhC endp               
                 
   4、编写一个输出一个字符串的子程序
          面临的任务:你已经拥有显示一个字符的子程序,现在要对它连续调用,完整
      地显示缓冲区中的全部汉字点阵。
      分析:
              所需的变量:整个字符串初始的左上角坐标x0,y0
                          字符串长度
                          在显示每个字符时传递给子程序的左上角坐标x1,y1
              默认参数:  默认为16点阵
                          默认字间距为5个像素
              程序主要结构:
                          一个单重循环,按字符串长度进行循环。
       我的实现:
               ;在图形模式下显示指定长度的字符串
               ;输入参数:
               ;          ds:si       字符串点阵缓冲区的首地址
               ;          ax=y0       字符串第一个字符左上角的Y坐标
               ;          bx=x0       字符串第一个字符左上角的X坐标
               ;          ch=n
               ;          cl=color
               ;返回值:无
               DefDis = 5   ;每两个符号间的默认间距为5个像素
               CharWidth = 16 ;默认为16点阵,这也是每个字符的像素宽度
               DispZhS proc
                  push bp
                  push ax
                  push bx
                  push ds
                  push si
                  push cx
                  push dx
                  mov bp,sp
                  xor dx,dx
                  jmp s1
                nextChar:        ;指向下一个要输出的字符
                   add si,32
                   add bx,DefDis+CharWidth
                s1:
                   cmp dh,ch    ;是否已经输出了指定个数的字符
                   je  Dones
                   call DispZhc
                   inc dh
                   jmp nextChar
                Dones:
                  pop dx   
                  pop cx   
                  pop si   
                  pop ds   
                  pop bx   
                  pop ax   
                  pop bp   
                  ret
               DispZhS endp
   5、标准VGA进入图形模式的方法
         ;进入640×480×16色模式
         ;setmode:
         ;对640*480*16和320*论200*256是标准VGA模式,在各种VGA上都分别为12h和13h
         mov ax, 12h
         int 10h
标签:
系统开发

汇编

汉字显示



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/11176/showart_406074.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP