实验9 根据材料编程《汇编语言》- 王爽

1. 需求

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

2. 分析

(1)材料中提到,一个在屏幕上显示的字符,具有前景(字符色)和背景(底色)两种颜色,字符还可以以高亮和闪烁的方式显示。前景色、背景色、闪烁、高亮等信息被记录在属性字节中,字节属性中,每位表示的含义如下

76543210
BLRGBIRGB
闪烁背景(底色)高亮前景(字符色)

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

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

红底绿字,属性字节为:01000010b

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

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

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

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

所以,从以上材料的描述,我们可以得到

绿字的属性字节为:00000010b

绿底红色的属性字节为:00100100b

白底蓝色的属性字节为:01110001b

其次,材料中提到,在显示器中0行0列显示红底高亮闪烁绿色的字符串'ABCDEF'

(红底高亮闪烁绿色,属性字节为:11001010b,即CAh)

显示缓冲区的内容为:

000102030405060708090A0B0C0D0E0F
B800:000041CA42CA43CA44CA45CA46CA....

所以,一个字在显示缓冲区中,是用2个字节描述的,偶数字节是这个字的assii码,奇数字节是这个字的属性。

(2)材料中提到,B8000h ~ BFFFFh 共32kb空间,是80 x 25 彩色字符模式的显示缓冲区。显示缓冲区分为8页,每页 4kb(约等于 4000字节),显示器可以显示任意一页的内容。一般情况下,显示第0页的内容,也就是说,B8000h ~ B8F9Fh 这4000个字节的内容会显示在显示器上。

所以,从以上材料的描述,我们可以让显示缓冲区的段地址为:B8000h

其次,在一页显示缓冲区中,

偏移地址 000h ~ 09Fh 对应显示器上第1行(共160个字节,80个字(每个字用2个字节描述,底字节:assii码,高字节:字的属性))

偏移地址 0A0h ~ 13Fh 对应显示器上第2行

。。。

。。。

偏移地址 F00h ~ F9Fh 对应显示器上第25行(最后一行)

所以,在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串的字符串 'welcome to masm!',即:

  • 在第12行的中间,偏移地址为:160*11 + 160/2 - 32/2 = 1824 处开始写入绿色字符串: 'welcome to masm!'
  • 在第13行的中间,偏移地址为:160*12 + 160/2 - 32/2 = 1984 处开始写入绿底红色字符串: 'welcome to masm!'
  • 在第14行的中间,偏移地址为:160*13 + 160/2 - 32/2 = 2144 处开始写入白底蓝色字符串: 'welcome to masm!'

3. 数据结构设计

我们可以用 C语言 数据结构的思想来组织需求中需要的数据

大概如C语言描述的如下结构

struct STR_8025 {
	unsigned char str[16];
	unsigned char attrs[3];
};

用汇编语言描述如下

data segment
    db 'welcome to masm!'   ;16个字节
    db 00000010b            ;1字节(绿色字)
    db 00100100b            ;1字节(绿底红色字)
    db 01110001b            ;1字节(白底蓝色字)
data ends

4. 代码

assume cs:code, ds:data, ss:stack
data segment
    db 'welcome to masm!'   ;16个字节, 看成C语言中的 uchar 类型字符
    db 00000010b            ;1字节(绿色字)
    db 00100100b            ;1字节(绿底红色字)
    db 01110001b            ;1字节(白底蓝色字)
data ends
stack segment
    db 16 dup (0)           ;16个db类型数据,并且初始化为0
stack ends
code segment
start:
    ;初始化数据段
    mov ax, data
    mov ds, ax
    ;初始化栈段
    mov ax, stack
    mov ss, ax
    mov sp, 16              ;设置栈顶

    mov ax, 0B800h          ;B8000h ~ BFFFFh 共32kb空间,是80 x 25彩色字符模式的显示缓冲区
    mov es, ax              ;设置显示缓冲区的段地址在es寄存器上

    mov si, 1824    ;在第12行的中间,偏移地址为:160*11 + 160/2 - 32/2 = 1824 处开始写入
    mov cx, 3       ;需要写的行数
    mov di, 0       ;字属性数据,10h[0], 10h[1], 10h[2]
rows:
    push cx         ;rows标号循环中的cx入栈
    mov bx, 0
    mov cx, 16      ;'welcome to masm!' 有16个字节
columns:
    mov al, [bx]        ;低字节存储字符对应的assii码编码值
    mov ah, 10h[di]     ;高字节存储字属性
    mov es:[si], ax     
    inc bx              ;移到下一个字 
    add si, 2           ;移到下一个字开始写的地址
    loop columns

    pop cx              ;恢复rows标号循环中的cx
    sub si, 32          ;每行写数据的首地址
    add si, 160         ;移到下一行
    inc di              ;移到下一行属性
    loop rows

    mov ax, 4c00h
    int 21h
code ends
end start

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值