[Hb-VIII] 转移指令 显示带色字符串

《汇编语言·第三版》--王爽


1 分析一个奇怪的程序

1.        assume    cs:codesg

2.         

3.        codesg     segment

4.                 mov ax, 4c00h

5.                 int    21h

6.                

7.        start:        mov ax, 0

8.         

9.        s:      nop

10.             nop

11.            

12.             mov di, offset s

13.             mov si, offset s2

14.             mov ax, cs:[si]

15.             mov cs:[di], ax

16.            

17.    s0:    jmp  short s

18.     

19.    s1:    mov ax, 0

20.             int    21h

21.             mov ax, 0

22.            

23.    s2:    jmp  short s1

24.             nop

25.    codesg     ends

26.    end  start

(1) 分析上面的程序,在运行前思考:这个程序可以正确返回吗?

答:不能。因为程序运行过程为s --> s0 --> s1 --> s2 --> s1 --> s2 --> s1……


(2) 运行后思考:为什么是这种结果?

答:运行程序后发现程序可以正确返回。再读程序并思之。原来程序运行的过程为:7 --> 17,再是3 --> 5,此时程序退出。数字为下表程序的行号。为什么是这样呢?因为12 ~ 15行代码将“23行的指令(机器码)拷贝到了9行处”,23行处的机器码的偏移量为s2 – s1,刚好等于s – codesg。故而,当程序跳转到s处运行s处指令时,程序将会从codesg处运行,故而程序可以正确返回。


2 根据材料编程

(1) 要求

编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’welcome to masm!’。


编程所需的知识通过阅读、分析下面的材料获得。

80 x 25彩色字符模式显示缓冲区(以下简称为显示缓冲区)的结构:

内存地址空间中,B8000H ~ BFFFFH共32KB的空间80 x 25彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器上。


在80 x 25彩色字符模式下,显示器可显示25行,每行80个字符,每个字符可以有256种属性(背景色、前景色、闪烁、高亮等组合信息)。


这样,一个字符在显示缓冲区中就要占两个字节分别存放字符的ASCII码和属性。80 x 25模式下,一屏的内容在显示缓冲区中共占4000个字节。


显示缓冲区分为8页,每页4KB[12位偏移](约等于4000B),显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。也就是说通常情况下,B8000H ~ B8F9FH中的4000个字节的内容将出现在显示器上。


在一页显示缓冲区中:

偏移000 ~ 09F对应显示器上的第1行(80个字符占160个字节);

偏移0A0 ~13F对应显示器上的第2行;

偏移140 ~ 1DF对应显示器上的第三行;

依次类推,可知,偏移F00 ~ F9F对应显示器上的第25行。[这个跟内存的真实结构没关系,是内存到屏幕坐标的一个对应关系]

在一行中,一个字符占两个字节的存储空间(一个字),低位字节存储字符的ASCII码,高位字节存储字符的属性。一行共有80个字符,占160个字节。


即在一行中:

00 ~ 01单元对应显示器上的第一列;

02 ~ 03单元对应显示器上的第2列;

04 ~ 05单元对应显示器上的第3列;

依次类推,可知,9E ~ 9F单元对应显示器上的第80列。


例:在显示器的0行0列显示黑底绿色的字符串’ABCDEF’(’A’的ASCII码值为41H,02H表示黑底绿色)

显示缓冲区里的内容为:

【】【】【】【 00  01     02     03     04     05     06     07     08     09     0A    0B    …      0E     0F

B800:0000        41     02     42     02     43     02     44     02     45     02     46     02     …      ..       ..

         ..

         ..

B800:00A0       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       …      ..       ..

可以看出,在显示缓冲区中,偶地址存放字符,奇地址存放字符的颜色属性


一个在屏幕上显示的字符,具有前景(字符色)和背景(底色)两种颜色,字符还可以以高亮度和闪烁的方式显示。前景色、背景色、山所、高亮等信息都被记录在属性字节中

属性字节的格式

【】【】【7       6       5       4       3       2       1       0

含义         BL     R       G      B       I        R       G      B

R:红色,G:绿色,B:蓝色

[绿色字属性字节内容:02H,绿底红色字属性字节内容:00100100b, 24H,白底蓝色字属性字节内容:0111 0001b, 71H]

可以按位设置属性字节,从而配出各种不同的前景色和背景色。


比如:

红底绿字,属性字节为:01000010B;

红底闪烁绿字,属性字节为:11000010B

红底高亮绿字,属性字节为:01001010B

黑底白字,属性字节为:00000111B

白底蓝字,属性字节为:01110001B


例:在显示器的0行0列显示红底高亮闪烁绿色的字符串’ABCDEF’(红底高亮闪烁绿色,属性字节为:11001010B,CAH)

显示缓冲区里的内容为:

【】【】【】【 00     01     02     03     04     05     06     07     08     09     0A    0B    …      9E     9F

B800:0000        41     CA    42     CA    43     CA    44     CA    45     CA    46     CA    …      ..       ..

         ..

B800:00A0       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       ..       …      ..       ..

注意,闪烁效果必须在全屏DOS方式下才能看到。


(2) 分析

编程要求在屏幕中间显示’welcome to masm!’字符串,加上空格共16个字符。屏幕为80 x 25(默认显示第0页内容)。16个字符在一行中会占用32个字节,那么字符串从第12、13、14行第33列处开始写。各行对应的内存地址分别为(偶地址开始存字符): 

【】【】【  B800:6E0 + 72

                   B800:780+ 72

                   B800:820+ 72

(3) 程序

1.        ;ds段寄存器指向'welcome to masm!'数据段

2.        ;es段寄存器指向显存地址,使用[bp+ si]的方式防显存

3.        ;bp为第12行偏移地址,每次加160

4.        assume    cs:codesg, ds:datasg

5.         

6.        datasg      segment

7.                 db     'welcome to masm!'

8.        datasg      ends

9.         

10.     

11.    codesg     segment

12.    start:

13.             mov ax, datasg

14.             mov ds, ax

15.             mov bx, 0

16.            

17.             mov ax, 0b800h

18.             mov es, ax

19.             mov bp, 6e0h            ;屏幕12行对应的显存偏移地址

20.             mov si, 0           ;作为显存地址递增作用

21.     

22.            

23.             mov cx, 16

24.    s0:

25.             mov al, [bx]

26.             mov es:[bp + si + 72],al            ;字符

27.             inc    si               

28.             mov byte ptr es:[bp +si + 72], 02h ;字符前景色

29.             inc    si

30.             inc    bx

31.             loop s0

32.     

33.            

34.             mov si, 0

35.             mov bx, 0

36.             add  bp, 160

37.             mov cx, 16

38.    s1:

39.             mov al, [bx]

40.             mov es:[bp + si + 72],al            ;字符

41.             inc    si               

42.             mov byte ptr es:[bp +si + 72], 24h ;字符前景色

43.             inc    si

44.             inc    bx

45.             loop s1

46.     

47.             mov si, 0

48.             mov bx, 0

49.             add  bp, 160

50.             mov cx, 16       

51.    s2:

52.             mov al, [bx]

53.             mov es:[bp + si + 72],al            ;字符

54.             inc    si               

55.             mov byte ptr es:[bp +si + 72], 71h ;字符前景色

56.             inc    si

57.             inc    bx

58.             loop s2

59.            

60.             mov ax, 4c00h

61.             int    21h

62.    codesg     ends

63.  end  start

(4) 运行

用masm编译源程序:masm       src\...\l9

用连接器连接目标文件:link        src\...\l9

最后在dos下运行可执行程序:src\...\l9.exe得到以下运行结果

Figure1. 程序运行结果
显示如上图所示。欧克。

[2014.12.04 - 22:56]
R《Hb》Note Over.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值