|
主题 : : 实验九,大家看看,经过测试能显示。 [已解决] |
回复[ 5次 ]
点击[ 511次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2010-07-23 14:31 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
assume ds:data,ss:stack,cs:code
;由于字符串数据长16字节,每个字符其对应的ascii码和字符属性在显示缓冲区中各占一个字节,故共占32个字节,远小于一页总共能显示的4000个字节,故在此只需选择第0页来显示所需显示的字符串。在第0页中,共25行,每行80个字符,由于每个字符对应的在显示缓冲区各占一个字节,故每行共160个字节。要显示的字符串在显示缓冲区分别以3种不同的颜色属性显示,那就需3行来显示,即分别位于第11,12,13行,且题目中要求显示的字符串位于屏幕中央,即位于上述三行中每行的64~95字节处。在本程序中,上述三行的段地址用es表示,由题可知
(es)=0B800h,第十一行开始处的偏移地址为第0行开始处的偏移地址加上中间11行的长度,即0000h+11*160=06E0h,用bx表示。另外字符串位于每行的64~95字节处,则第64字节离每行起始处的距离为40h,由于每个字符串从第64字节处占2个字节,因此用变量di每次循环加2,共循环16次,遍历这段存储空间。另外这三行中每行字符串对应位置相差160个字节,因此把(bx)+160就会切换到下一行。可知外循环为3次循环,在每行之间切换,内循环为16次循环,在每行中,将要显示的字符串中的每个字符的ascii码和对应的颜色属性分别传送到显示缓冲区中的第11,12,13行中的64~95字节处。
data segment
db 'welcome to masm!' ;显示在屏幕中央的由16个字符组成的,总共长16个字节的字符串数据
db 02h,24h,71h ;分别代表绿色,绿底红色,白底蓝色
data ends
stack segment
db 16 dup (0) ;用来构建长16个字节的栈
stack ends
code segment
start: mov ax,0B800h
mov es,ax ;以上两指令将显示缓冲区的段地址传送给es
mov ax,data
mov ds,ax ;以上两指令将数据段段地址传送给ds
mov ax,stack
mov ss,ax
mov sp,10h ;以上三条指令将栈段段地址传送给ss,栈顶指针指向10h,即起始时栈空
mov si,0 ;外循环的变量段地址si初始值为0
mov di,0 ;外循环di,每次循环增加1
mov bx,06E0h ;要显示的显示缓冲区的行偏移地址
mov cx,3 ;外循环循环次数
s0: push cx ;由于内循环也要用cx,现将外循环的cx入栈保护起来,以便出栈后恢复
push si ;由于内循环也用到si,将si保护起来,出栈后保持每行的内循环的si初始值为0
push di ;由于内循环也要用到di,其内循环di每次增加2,将外循环的di保护起来,使其不受内循环的di影响
mov ah,ds:[di+10h] ;将数据段的颜色传给ah
mov cx,16 ;内循环的循环次数为16
mov di,0 ;保证每行内循环的di初始值为0
s: mov al,ds:[si]
mov es:[bx+di+40h],al
mov es:[bx+di+41h],ah
inc si
add di,2
loop s ;内循环中的所有指令是将每个字符的ascii码(存储在al中)和颜色属性(存储在ah中)传送到每行的64~95字节中。
pop di ;恢复外循环的di值
pop si ;恢复外循环的si值
pop cx ;恢复外循环的cx值
add bx,0A0h ;转移到一行
inc di ;外循环di每次加1,从而选择数据段中三种不同的属性,分别传送给相应的三行中
loop s0
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2010-07-23 14:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
在dos下先编译连接后,然后运行可执行文件。显示效果的时候,通过cmd进入dos后,通过按下Alt+Enter键,全屏观看,不然不时会出现问题。程序中不少地方注释太长,只是为了方便理解,实际测试应将这些注释去掉,不然会提示好几处注释内容太长的警告信息。 | | |
|
|
|
|
[第2楼]
[ 回复时间:2010-07-23 15:14 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
assume ds:data,ss:stack,cs:code
;由于字符串数据长16字节,每个字符其对应的ascii码和字符属性在显示缓冲区中各占一个字节,故共占32个字节,远小于一页总共能显示的4000个字节,故在此只需选择第0页来显示所需显示的字符串。在第0页中,共25行,每行80个字符,由于每个字符对应的在显示缓冲区各占一个字节,故每行共160个字节。要显示的字符串在显示缓冲区分别以3种不同的颜色属性显示,那就需3行来显示,即分别位于第11,12,13行,且题目中要求显示的字符串位于屏幕中央,即位于上述三行中每行的64~95字节处。在本程序中,上述三行的段地址用es表示,由题可知
(es)=0B800h,第十一行开始处的偏移地址为第0行开始处的偏移地址加上中间11行的长度,即0000h+11*160=06E0h,用bx表示。另外字符串位于每行的64~95字节处,则第64字节离每行起始处的距离为40h,由于每个字符串从第64字节处占2个字节,因此用变量di每次循环加2,共循环16次,遍历这段存储空间。另外这三行中每行字符串对应位置相差160个字节,因此把(bx)+160就会切换到下一行。可知外循环为3次循环,在每行之间切换,内循环为16次循环,在每行中,将要显示的字符串中的每个字符的ascii码和对应的颜色属性分别传送到显示缓冲区中的第11,12,13行中的64~95字节处。
data segment
db 'welcome to masm!' ;显示在屏幕中央的由16个字符组成的,总共长16个字节的字符串数据
db 02h,24h,71h ;分别代表绿色,绿底红色,白底蓝色
data ends
stack segment
db 16 dup (0) ;用来构建长16个字节的栈
stack ends
code segment
start: mov ax,0B800h
mov es,ax ;以上两指令将显示缓冲区的段地址传送给es
mov ax,data
mov ds,ax ;以上两指令将数据段段地址传送给ds
mov ax,stack
mov ss,ax
mov sp,10h ;以上三条指令将栈段段地址传送给ss,栈顶指针指向10h,即起始时栈空
mov si,0 ;外循环的变量段地址si初始值为0
mov di,0 ;外循环di,每次循环增加1
mov bx,06E0h ;要显示的显示缓冲区的行偏移地址
mov cx,3 ;外循环循环次数
s0: push cx ;由于内循环也要用cx,现将外循环的cx入栈保护起来,以便出栈后恢复
push si ;由于内循环也用到si,将si保护起来,出栈后保持每行的内循环的si初始值为0
push di ;由于内循环也要用到di,其内循环di每次增加2,将外循环的di保护起来,使其不受内循环的di影响
mov ah,ds:[di+10h] ;将数据段的颜色传给ah
mov cx,16 ;内循环的循环次数为16
mov di,0 ;保证每行内循环的di初始值为0
s: mov al,ds:[si]
mov es:[bx+di+40h],al
mov es:[bx+di+41h],ah
inc si
add di,2
loop s ;内循环中的所有指令是将每个字符的ascii码(存储在al中)和颜色属性(存储在ah中)传送到每行的64~95字节中。
pop di ;恢复外循环的di值
pop si ;恢复外循环的si值
pop cx ;恢复外循环的cx值
add bx,0A0h ;转移到一行
inc di ;外循环di每次加1,从而选择数据段中三种不同的属性,分别传送给相应的三行中
loop s0
code ends
end start
------------------
回复:对了在loop so与code ends之间应该添加mov ax,4c00h和int 21h两条指令。 | | |
|
|
|
|
[第3楼]
[ 回复时间:2010-07-23 15:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
在dos下先编译连接后,然后运行可执行文件。显示效果的时候,通过cmd进入dos后,通过按下Alt+Enter键,全屏观看,不然不时会出现问题。程序中不少地方注释太长,只是为了方便理解,实际测试应将这些注释去掉,不然会提示好几处注释内容太长的警告信息。
------------------
回复:其中不许全屏也可观看这个效果,主要还是没有mov ax,4c00h 和int 21h 这两条指令。汗啊。 | | |
|
|
|
|
[第4楼]
[ 回复时间:2010-07-23 15:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
在dos下先编译连接后,然后运行可执行文件。显示效果的时候,通过cmd进入dos后,通过按下Alt+Enter键,全屏观看,不然不时会出现问题。程序中不少地方注释太长,只是为了方便理解,实际测试应将这些注释去掉,不然会提示好几处注释内容太长的警告信息。
------------------
回复:其中不须全屏也可观看这个效果,主要还是没有mov ax,4c00h 和int 21h 这两条指令。汗啊。
------------------
回复:加了这两条指令后,就没有上述问题了。 | | |
|
|
|
|
[第5楼]
[ 回复时间:2010-07-23 15:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
此贴由 贴主 于 [ 2010-07-23 15:19 ] 结贴。 结贴原因:问题已解决 | | |
|