首页
社区
课程
招聘
王爽汇编实验九
发表于: 2010-7-29 17:17 5363

王爽汇编实验九

2010-7-29 17:17
5363
题目要求:在屏幕中间分别显示绿色,绿底红色,白底蓝色字符串‘welcome to masm!‘
默认显示在 显示缓冲区第0页屏幕中间。

我经过计算得出为第12,13,14这三行,偏移地址分别为0780H,0820H,08C0H
每一行将字符从第32个字符写到第47个字符,共32个字节,以下为代码
assume cs:code, ds:data

data segment
	db 'welcome to masm!'
data ends
code segment
start:
	mov ax,0b800h
	mov es,ax	
	
	mov ax,data
	mov ds,ax
	mov si,0
	mov di,32 ; 每行开始写入的位置,为偶数
	mov cx,16 ;循环16次,每次写一个字母,一个颜色属性
s:	mov al,ds:[si]
	mov es:[di+0780h],al   ;写字母
	mov es:[di+0780h+1],02h ;写颜色 绿色
	
	mov al,ds:[si]
	mov es:[di+0820h],al
	mov es:[di+0820h+1],24h ;绿底红字
	
	mov al,ds:[si]
	mov es:[di+08c0h],al
	mov es:[di+08c0h+1],71h ;白底蓝字
	
	inc si
	add di,2
	loop s
	
	
	mov ax,4c00h
	int 21h
code ends
end start


以下为网上下载的答案的代码
assume cs:code,ds:data,ss:stack

 

data segment

        db 'welcome to masm!'  ;定义要显示的字符串(共16字节)

        db 02h,24h,71h    ;定义三种颜色属性

data ends

 

stack segment

        dw 8 dup(0)

stack ends

 

code segment

start:

        mov ax,data

        mov ds,ax

        mov ax,stack

        mov ss,ax

        mov sp,10h

        mov bx,0

        mov di,0

        mov ax,0b872h    ;算出屏幕第12行中间的显存的段起始位置放入ax中

 

        mov cx,3     ;外循环为3次,因为要显示三个字符串

s3:     push cx        ;三个进栈操作为外循环s3保存相关寄存器的值

        push ax        ;以防止它们的值在内循环中被破坏

        push di

        mov es,ax      ;此时es为屏幕第12行中间的显存的段起始位置

        mov si,0

        mov di,0

 

        mov cx,10h     ;内循环为10h次,因为一个字符串中含10h个字节

s1:     mov al,ds:[bx+si]

        mov es:[bx+di],al

        inc si

        add di,2

        loop s1      ;此循环实现偶地址中存放字符

        

        mov si,1   ;si的值设为1,从而为在显存奇地址中存放字符的颜色属性做准备

        pop di        ;将di的值恢复成进入内循环之前的时候的值

        mov al,ds:10h[bx+di]    ;取颜色属性[源OP寻址方式:相对基址变址]

 

        mov cx,10h     ;第二个内循环也为10h次

s2:     mov es:[bx+si],al

        add si,2

        loop s2       ;此循环实现奇地址中存放字符的颜色属性

        

        ;以下4句为下一趟外循环做准备

        inc di

        pop ax

        add ax,0ah   ;将显存的段起始地址设为当前行的下一行

                  ;[在段地址中加0ah,相当于在偏移地址中加了0a0h(=160d)]

        pop cx

 

        loop s3

        

        mov ax,4c00h

        int 21h

 

code ends

end start



改写为子程序
assume cs:code, ds:data
data segment
	db 'Welcome to masm!',0
data ends

code segment
start:
	mov dh,8 ;line
	mov dl,3 ;column
	mov cl,0cah ;color
	mov ax,data
	mov ds,ax
	mov si,0
	call show_str
	mov ax,4c00h
	int 21h
show_str:
	push ax
	push bx
	push cx
	push dx
	push si
	push di
	push ds
	push es
	
	mov ax,0b800h
	mov es,ax	
	
	mov al,0a0h ;line
	mul dh
	mov bp,ax	
 
	mov al,2    ;column
	mul dl	
	mov di,ax
	
	mov ah,cl ;color
	s:	mov cl,ds:[si]
		sub ch,ch
		jcxz ok		
		mov es:[bp+di],cl
		mov es:[bp+di+1],ah		
		inc si
		add di,2
		jmp short s
		
		
	ok:	pop es
		pop ds
		pop di
		pop si
		pop dx
		pop cx
		pop bx
		pop ax
		ret	
code ends
end start	

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
已经学习!谢谢楼主!
2010-7-29 17:48
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
怎么简单就怎么写了,效率高就是规范
2010-7-30 08:43
0
雪    币: 341
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了
2010-7-30 08:48
0
雪    币: 459
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
等效的么。都一样。
2010-7-30 09:11
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
处女帖来顶一顶,
 强大的汇编!!!
2011-1-29 11:54
0
雪    币: 1240
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
直接写屏么?呵呵
其实用C写也很高效啊,而且程序更短。

个人感觉汇编只能用来调试、破解,开发还得用C
2011-2-18 22:53
0
游客
登录 | 注册 方可回帖
返回
//