汇编:有关在屏幕区显示字符的四种方法

李忠老师的《x86汇编语言:从实模式到保护模式》中第五章到第七章的部分,每一章在讲述知识点的同时,分别使用了三种不同的显示字符的方法,加上调用BIOS的10h中 断的方法,这里做出一次简单梳理:

一:第五章,最基础的直接用mov 的方法

代码如下:

  1          ;代码清单5-1
  2          ;文件名:c05_mbr.asm
  3          ;文件说明:硬盘主引导扇区代码
  4          ;创建日期:2011-3-31 21:15
  5
  6          mov ax,0xb800                 ;指向文本模式的显示缓冲区
  7          mov es,ax
  8
  9          ;以下显示字符串"Label offset:"
 10          mov byte [es:0x00],‘L‘
 11          mov byte [es:0x01],0x07
 12          mov byte [es:0x02],‘a‘
 13          mov byte [es:0x03],0x07
 14          mov byte [es:0x04],‘b‘
 15          mov byte [es:0x05],0x07
 16          mov byte [es:0x06],‘e‘
 17          mov byte [es:0x07],0x07
 18          mov byte [es:0x08],‘l‘
 19          mov byte [es:0x09],0x07
 20          mov byte [es:0x0a],‘ ‘
 21          mov byte [es:0x0b],0x07
 22          mov byte [es:0x0c],"o"
 23          mov byte [es:0x0d],0x07
 24          mov byte [es:0x0e],‘f‘
 25          mov byte [es:0x0f],0x07
 26          mov byte [es:0x10],‘f‘
 27          mov byte [es:0x11],0x07
 28          mov byte [es:0x12],‘s‘
 29          mov byte [es:0x13],0x07
 30          mov byte [es:0x14],‘e‘
 31          mov byte [es:0x15],0x07
 32          mov byte [es:0x16],‘t‘
 33          mov byte [es:0x17],0x07
 34          mov byte [es:0x18],‘:‘
 35          mov byte [es:0x19],0x07
 36
 37          mov ax,number                 ;取得标号number的偏移地址
 38          mov bx,10
 39
 40          ;设置数据段的基地址
 41          mov cx,cs
 42          mov ds,cx
 43
 44          ;求个位上的数字
 45          mov dx,0
 46          div bx
 47          mov [0x7c00+number+0x00],dl   ;保存个位上的数字
 48
 49          ;求十位上的数字
 50          xor dx,dx
 51          div bx
 52          mov [0x7c00+number+0x01],dl   ;保存十位上的数字
 53
 54          ;求百位上的数字
 55          xor dx,dx
 56          div bx
 57          mov [0x7c00+number+0x02],dl   ;保存百位上的数字
 58
 59          ;求千位上的数字
 60          xor dx,dx
 61          div bx
 62          mov [0x7c00+number+0x03],dl   ;保存千位上的数字
 63
 64          ;求万位上的数字
 65          xor dx,dx
 66          div bx
 67          mov [0x7c00+number+0x04],dl   ;保存万位上的数字
 68
 69          ;以下用十进制显示标号的偏移地址
 70          mov al,[0x7c00+number+0x04]
 71          add al,0x30
 72          mov [es:0x1a],al
 73          mov byte [es:0x1b],0x04
 74
 75          mov al,[0x7c00+number+0x03]
 76          add al,0x30
 77          mov [es:0x1c],al
 78          mov byte [es:0x1d],0x04
 79
 80          mov al,[0x7c00+number+0x02]
 81          add al,0x30
 82          mov [es:0x1e],al
 83          mov byte [es:0x1f],0x04
 84
 85          mov al,[0x7c00+number+0x01]
 86          add al,0x30
 87          mov [es:0x20],al
 88          mov byte [es:0x21],0x04
 89
 90          mov al,[0x7c00+number+0x00]
 91          add al,0x30
 92          mov [es:0x22],al
 93          mov byte [es:0x23],0x04
 94
 95          mov byte [es:0x24],‘D‘
 96          mov byte [es:0x25],0x07
 97
 98    infi: jmp near infi                 ;无限循环
 99
100   number db 0,0,0,0,0
101
102   times 203 db 0
103             db 0x55,0xaa

代码一:

这里采用的最基础的做法,就是对字符进行一个一个的处理。先将显示缓存区的地址0xb800赋给es寄存器,然后通过 mov byte[es:0x00],‘L‘ 的形式,来处理后续的字符。这种方法较为简单,这里不再赘述。

二:第六章,采用了批量处理的方法

代码如下:

 1          ;代码清单6-1
 2          ;文件名:c06_mbr.asm
 3          ;文件说明:硬盘主引导扇区代码
 4          ;创建日期:2011-4-12 22:12
 5
 6          jmp near start
 7
 8   mytext db ‘L‘,0x07,‘a‘,0x07,‘b‘,0x07,‘e‘,0x07,‘l‘,0x07,‘ ‘,0x07,‘o‘,0x07, 9             ‘f‘,0x07,‘f‘,0x07,‘s‘,0x07,‘e‘,0x07,‘t‘,0x07,‘:‘,0x07
10   number db 0,0,0,0,0
11
12   start:
13          mov ax,0x7c0                  ;设置数据段基地址
14          mov ds,ax
15
16          mov ax,0xb800                 ;设置附加段基地址
17          mov es,ax
18
19          cld
20          mov si,mytext
21          mov di,0
22          mov cx,(number-mytext)/2      ;实际上等于 13
23          rep movsw
24
25          ;得到标号所代表的偏移地址
26          mov ax,number
27
28          ;计算各个数位
29          mov bx,ax
30          mov cx,5                      ;循环次数
31          mov si,10                     ;除数
32   digit:
33          xor dx,dx
34          div si
35          mov [bx],dl                   ;保存数位
36          inc bx
37          loop digit
38
39          ;显示各个数位
40          mov bx,number
41          mov si,4
42    show:
43          mov al,[bx+si]
44          add al,0x30
45          mov ah,0x04
46          mov [es:di],ax
47          add di,2
48          dec si
49          jns show
50
51          mov word [es:di],0x0744
52
53          jmp near $
54
55   times 510-($-$$) db 0
56                    db 0x55,0xaa

代码二

这里采用的办法是批量传送,后续用loop循环挨个处理。这样的写法明显比上一种写法要高明一些,减少了工作量。这段代码中值得注意的地方是   mov si,mytext  (其中mytext是声明的字符的地址),这里值得留意的原因之一是在做显示时间的编码中,有过下列这样的写法,所以会格外的留心。

 1 org 7c00h
 2 start1:
 3
 4
 5     mov    ax, cs             ; 置其他段寄存器值与CS相同
 6     mov    ds, ax             ; 数据段
 7     mov es, ax
 8
 9     mov  bl, 10h
10     mov  bp, Message1
11
12     mov  ah, 02h
13     int  1ah
14
15     xor  ax, ax
16     mov  al, ch
17     div  bl
18     add  al, 0x30
19     mov  [es:bp+2], al
20     add  ah, 0x30
21     mov  [es:bp+3], ah
22
23     xor  ax, ax
24     mov  al, cl
25     div  bl
26     add  al, 0x30
27     mov  [es:bp+5], al
28     add  ah, 0x30
29     mov  [es:bp+6], ah
30
31     xor  ax, ax
32     mov  al, dh
33     div  bl
34     add  al, 0x30
35     mov  [es:bp+8], al
36     add  ah, 0x30
37     mov  [es:bp+9], ah
38
39     mov dh, 3
40     mov dl, 0
41     mov ax, 1301h     ; 功能号
42     mov bp, Message1
43     mov cx, MessageLength1
44     mov bx, 0007h
45     int 10h
46
47 ;    ret
48
49 Message1:
50 db ‘  00:00:00‘
51 MessageLength1  equ ($-Message1)
52
53      times 510-($-$$) db 0    ; 用0填充引导扇区剩下的空间
54     db     55h, 0aah                ; 引导扇区结束标志

代码三

(上面的那段代码的功能是调用BIOS中断显示系统时间)这段代码中对于“00:00:00”的处理方法,代码二中批量处理si处的mytext字段有异曲同工之妙,这里mark一下。

关于代码二中显示数字的方法,是用到了loop循环。先将数字按照“除以10”的方法得到每一位的值,然后将其加上0x30(有关ASCII的知识可解释这一点是为什么),然后将最终值赋予  依次递增的显存。直到将之前处理的每一位数字都显示出来,over.

三:第七章,使用栈来操作

四:调用BIOS的10h中断来显示字符

时间: 2024-12-27 23:43:31

汇编:有关在屏幕区显示字符的四种方法的相关文章

汇编--查找第一个非0字符的五种方法

第一种 #include <windows.h> #include <stdio.h> void main(void) { int m = 0, cout = 0; char cStr2Find[1024] = {0}; printf("请输入一段字符串"); scanf("%s", cStr2Find); __asm{ pushad; //保存所有寄存器 lea esi,cStr2Find; //esi指向查找字符串 xor ecx,ecx

MFC 在对话框显示图片的多种方法(四种方法)

我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为Ttest. 对话框类为CTestDlg (一) 非动态载入图片. 方法1.先从最简单的开始,用picture 控件来实现. 步骤: 先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点击打开属性, 将type下拉框选择B

Android TextView里直接显示图片的三种方法

方法一:重写TextView的onDraw方法,也挺直观就是不太好控制显示完图片后再显示字体所占空间的位置关系.一般如果字体是在图片上重叠的推荐这样写.时间关系,这个不付源码了. 方法二:利用TextView支持部分Html的特性,直接用api赋图片.代码如下: //第一种方法在TextView中显示图片 String html = "<img src='" + R.drawable.circle + "'/>"; ImageGetter imgGett

解决osgEarth中文显示乱码的几种方法

解决osgEarth中文显示乱码的几种方法 在此感谢那些在路上那个帮助过别人的朋友,谢谢. 方法一: 通过自己写函数转换类型. 下面这三个函数先复制过去吧. void unicodeToUTF8(const std::wstring &src, std::string& result) { int n = WideCharToMultiByte( CP_UTF8, 0, src.c_str(), -1, 0, 0, 0, 0 ); result.resize(n); ::WideCharT

DataGridView显示数据的两种方法

1.简单介绍 DataGridView空间是我们常用的显示数据的控件,它有极高的可配置性和可扩展性. 2.显示数据 DataGridView显示数据一般我们常用的有两种方法,一种是直接设置DataSoure属性就可以绑定数据.此方法不需要写任何代码操作比较简单,但是它显示出来的是整张表的数据.如果整一表数据比较多,而且我们并不需要所有的数据的情况下,我们就应该考虑第二种方法了.通过写代码连接数据库并从数据库中读取数据,最后将返回的数据传给DataGridView.这种方法貌似比较复杂,但是它只显

jquery 点击显示隐藏的三种方法

jquery点击显示隐藏的三种方法,从复杂到简单.使用jquery需要引用jquery库,如右所示<script src="jquery-1.11.3.min.js"type="text/javascript"></script>. 旁边按钮随着收缩展开发生状态变化,展开+变—,收缩—变+. 收缩效果: 展开效果: 一.HTML结构(盗用网上的) <body> <!-- 收缩展开效果 --><li class=&

WPF显示html的几种方法

原文:WPF显示html的几种方法 客户希望系统在一些特定的条件下,界面上能显示用户自定义的格式和内容,格式和内容通过html指定. 基本上在wpf中显示html有以下四种方法. 1.       Wpf Frame control this.frame1.Navigate(uri); this.frame1.Source = uri; 无法直接指定html内容. 2.       Wpf WebBrowser control this.webBrowser1.Navigate(source);

CSS实现自适应不同大小屏幕的背景大图的两种方法(转自简书)

CSS实现自适应不同大小屏幕的背景大图的两种方法 一张清晰漂亮的背景图片能给网页加分不少,设计师也经常会给页面的背景使用大图,我们既不想图片因为不同分辨率图片变形,也不希望当在大屏的情况下,背景有一块露白,简而言之,就是实现能自适应屏幕大小又不会变形的背景大图,而且背景图片不会随着滚动条滚动而滚动. 用CSS实现真的很简单很简单,下面我们来看一下第一种方法具体的代码: HTML代码: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <m

十五、在屏幕上显示字符

显示字符需要先实现绘点功能,然后用取模工具对需要显示的字符取模,我用的取模工具为PCtoLCD2002,设置如下图: 封装的函数最好比较容易使用,最好能选择字体,具体细节再此不详述,直接附上程序. draw.c 1 #include <stdio.h> 2 #include <linux/fb.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #i