|
主题 : : 实验9分析与源码 [待解决] |
回复[ 21次 ]
点击[ 1101次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2010-01-30 21:35 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-01-27 01:57 |
实验9
编程: 在屏幕中间分别显示绿色,绿底红色,白底蓝色的字符串'welcome to masm!'
分析:
1
绿色: 0 000 0 010b(二进制) 十六进制 02h
绿底红色:0 010 0 100(二进制)十六进制 24h
白底蓝色:0 111 0 001(二进制)十六进制 71h
2 程序要求在屏幕中间分别显示;
所以效果图应该这样:
***************************************************
* *
* *
* *
* *
* *
*
*
*
*
*
* welcome to masm!
* welcome to masm!
* welcome to masm!
*
*
*
*
*
*
*
* *
* *
* *
**************************************************
因为每行有80个字符,每个字符占2个字节(分别存放ASCIL码和属性,所以每行有160个字节;
所以,'welcome to masm!'共有16个字符所以需要32个字节来存放。
题目中写出:
" 显示缓冲器分为8(0-7)页地址从[B8000H - BFFFFH ,共32KB],在第0页( B8000H - B8F9FH 共占4000字节)显示缓冲区中:
偏移000H-09FH对应显示器上的第1行(80个字符占160个字节A0H个字节);
偏移0A0H-13FH对应显示器上的第2行;
偏移140H-1DFH对应显示器上的第3行;
依此类推,可知,偏移F00 - F9F 对应显示器上的第25行。"
现在,我们要把 'welcome to masm!' 写在第0页中,当然也可写在其它页(0 - 7 )页都可以
现在我们要写在第0页中。第0页地址从 B8000H - B8F9FH 共占4000字节而我们的需要把三行写到40000个字节的中间!
所以这个起始地址为 (4000-3*160)/2=1760 ==> 1760+(160-32)/2=1824 = 720H + B8000H = B8720H
地址为:B8720H 段地址表示为: B872H:0000H
现在可以开始写代码:
assume cs:code,ds:data
data segment
db 'welcome to masm!'
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0B872H
mov es,ax
mov di,0
mov si,0
mov cx,16
s: mov al,[di] ;循环16次把welcome to masm!复制到3行
mov es:[si],al
mov es:[si+0A0H],al
mov es:[si+140H],al
add si,2
inc di
loop s
mov si,1
mov cx,16
s0: mov al,02h ;循环16次修改它们的色彩属性
mov es:[si],al
mov al,24h
mov es:[si+0A0H],al
mov al,71h
mov es:[si+140H],al
add si,2
loop s0
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2010-01-31 00:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51 |
|
|
|
|
|
[第2楼]
[ 回复时间:2010-07-30 20:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-21 14:13 |
恩 问问下 比如degug 9.exe后咋看它显示的结果呢? | | |
|
|
|
|
[第3楼]
[ 回复时间:2010-07-30 20:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-21 14:13 |
恩 问问下 比如degug 9.exe后咋看它显示的结果呢? | | |
|
|
|
|
[第4楼]
[ 回复时间:2010-08-29 12:09 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2010-06-14 11:07 |
debug 9.exe 后 g 就能看到结果了
或者直接 9.exe 不用debug | | |
|
|
|
|
[第5楼]
[ 回复时间:2010-09-04 13:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-09-03 12:59 |
回复:[第4楼]
------------------
非常感谢你的回答,用debug 1.exe 后 g 真的能看到效果
直接1.EXE也可以的,另外感谢楼主分享这个答案的分析过程。 | | |
|
|
|
|
[第6楼]
[ 回复时间:2010-10-07 23:48 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-06-19 23:55 |
|
|
|
|
|
[第7楼]
[ 回复时间:2011-01-02 16:24 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-30 14:59 |
|
|
|
|
|
[第8楼]
[ 回复时间:2011-01-06 16:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-06 15:52 |
|
|
|
|
|
[第9楼]
[ 回复时间:2011-01-09 17:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 16:13 |
assume cs:code,ds:data
data segment
db 'wife,I love you!'
db 2,36,113;颜色代码
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,0b86eh;es显示器缓冲区地址
mov es,ax
mov bx,0
mov cx,16
mov si,0
mov di,0
s:mov al,[si]
mov ah,[bx+16];得到颜色代码
mov es:[di+64],ax
mov al,[si]
mov ah,[bx+17]
mov es:[di+224],ax
mov al,[si]
mov ah,[bx+18]
mov es:[di+384],ax;按照列将3行字符写入写入内存
add si,1
add di,2
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第10楼]
[ 回复时间:2011-01-09 22:14 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 16:13 |
还有一个,这个用到了多个标号和条件转移,程序比较简洁!
assume cs:code,ds:data
data segment
db 'wife,I love you!'
db 0,2,36,113;颜色代码
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,0b872h;es显示器缓冲区地址
mov es,ax
mov di,0
mov si,0
mov cx,3
s: mov dx,cx
mov bx,0
s0:mov cl,[bx]
mov ch,[si+17];得到颜色代码
mov es:[di],cx
add bx,1
add di,2
mov ch,0
jcxz s1;首次复制数据完毕
loop s0
s1:add di,126
inc si
mov cx,dx
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第11楼]
[ 回复时间:2011-01-09 22:16 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 16:13 |
|
|
|
|
|
[第12楼]
[ 回复时间:2011-01-10 20:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-10 20:07 |
assume cs:code,ds:data
data segment
db 'welcome to masm!'
data ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
mov di,0
mov ax,0b868h
mov es,ax
mov cx,16
s: mov al,[si]
mov byte ptr es:[di],al
mov byte ptr es:[di+0a0h],al
mov byte ptr es:[di+140h],al
inc di
mov byte ptr es:[di],2h
mov byte ptr es:[di+0a0h],24h
mov byte ptr es:[di+140h],71h
inc di
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第13楼]
[ 回复时间:2011-01-20 20:17 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-14 12:26 |
我做的是在cmd模式下可以居中,如果是全屏就不对称了,还请高手多多指教:
ASSUME CS:CODE
DATA SEGMENT
DB 'welcome to masm!'
DATA ENDS
STACKSG SEGMENT
DW 0,0,0,0
STACKSG ENDS
CODE SEGMENT
START: MOV AX,DATA
MOV ES,AX
MOV AX,0B800H
MOV DS,AX
MOV AX,STACKSG
MOV SS,AX
MOV SP,16H
MOV BX,0
MOV SI,0
MOV DI,720H
MOV CX,16H
S: MOV AL,ES:[SI]
MOV [DI],AL
MOV [DI+0A0H],AL
MOV [DI+140H],AL
ADD DI,2H
INC SI
LOOP S
MOV CX,10H
MOV DI,721H
MOV AH,00000010B
MOV BH,00100100B
MOV DH,01110001B
S0: MOV [DI],AH
MOV [DI+0A0H],BH
MOV [DI+140H],DH
ADD DI,2H
LOOP S0
MOV AX,4C00H
INT 21H
CODE ENDS
END START | | |
|
|
|
|
[第14楼]
[ 回复时间:2011-02-20 11:21 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:0
注册日期:2011-02-16 23:01 |
|
|
|
|
|
[第15楼]
[ 回复时间:2011-03-23 02:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-03-19 14:07 |
assume cs:codesg
data segment
db 'welcome to masm!'
data ends
codesg segment
start:
mov ax,data
mov ds,ax
mov ax,0b800h
mov es,ax
mov di,0
mov si,7c0h
mov cx,16
s:mov al,ds:[di]
mov es:[si],al
mov bl,2
mov es:[si+1],bl
inc di
add si,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start | | |
|
|
|
|
[第16楼]
[ 回复时间:2011-05-07 11:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-06-07 11:23 |
assume cs:codesg ,ds:data
data segment
db 'welcome to masm!'
data ends
codesg segment
start:mov ax,data
mov ds,ax
mov ax,0b872h
mov es,ax
mov bx,0
mov si,0
mov cx,16
s:mov al,[bx]
mov ah,02h
mov es:[si],ax
mov ah,24h
mov es:[si+0a0h],ax
mov ah,71h
mov es:[si+140h],ax
add si,2
inc bx
loop s
mov ax,4c00h
int 21h
codesg ends
end start | | |
|
|
|
|
[第17楼]
[ 回复时间:2011-05-17 11:45 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-05-17 11:43 |
|
|
|
|
|
[第18楼]
[ 回复时间:2011-07-22 16:25 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-05-12 13:02 |
我是这样理解这个起始地址的,(4000-3*32)=3904,然后3904/2=1952,每行因为是160个字节,那么所空余的字节为160-32=128个字节,那么起始地址应该是1952-128=1824,不知我这样理解是不是有些绕弯了?这道题我也想了很长时间。 | | |
|
|
|
|
[第19楼]
[ 回复时间:2011-07-23 00:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-07-04 18:37 |
为什么我写的执行时程序一闪就过了
------------------
回复:因为你程序执行完就退出了,你可以先进入Cmd,然后输入你的程序地址,在cmd窗口上你就能看到效果了,你也可以在mov ax,4c00h前加上mov ax,700h
int 21h
这是一个读取键盘按键的Dos中断,它会让程序一直在那等待,直到有按键被按下,它后面也可以跟上比较和跳转或循环语句 | | |
|
|
|
|
[第20楼]
[ 回复时间:2011-09-29 09:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-09-23 17:33 |
|
|
|
|
|
[第21楼]
[ 回复时间:2011-10-01 16:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-09-25 22:54 |
assume cs:code,ds:data,ss:stack
data segment
db 'w e l c o m e t o m a s m ! '
data ends
stack segment
dw 00000010b,00100100b,01110001b
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,0
mov ax,0b800h
mov es,ax
mov di,6e0h
mov cx,3
s: mov dx,cx
mov bx,0
mov cx,32
s0: mov al,[bx]
mov es:[di+64+bx],al
inc bx
loop s0
mov bx,1
mov cx,16
pop ax
s1: mov es:[di+64+bx],al
add bx,2
loop s1
add di,0a0h
mov cx,dx
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|