|
主题 : : 实验十 (1) 我觉得我写的比较规范了! [待解决] |
回复[ 8次 ]
点击[ 470次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2009-05-15 11:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05 |
assume cs:code,ss:stack
data segment
db 'welcome to masm!',0
data ends
stack segment
dw 20 dup (0)
stack ends
code segment
start: mov dh,8 ;行
mov dl,3 ;列
mov cl,2 ;颜色
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21H
show_str: mov ax,stack ;指定栈段,状态栈空
mov ss,ax
mov sp,40
push ax ;寄存器原始数据用栈备份
push bx
push cx
push dx
push si
mov bx,0 ;数据初始化
mov ax,0b800H ;确定显存所在段
mov es,ax
mov al,160 ;确定显存起始偏移地址
dec dh
mul dh
mov dh,0
add dl,dl ;列偏移地址
add ax,dx ;行偏移地址加列偏移地址
mov bx,ax ;bx表示起始偏移地址
mov al,cl ;al表示颜色
mov ch,0 ;counter高位清0
s: mov cl,ds:[si] ;用cl检字符窜是否为0
jcxz s1 ;如果为0,程序转移到s1
;不为0执行下列程序
mov es:[bx],cl ;字符ASCII码写入显存地址
mov es:[bx+1],al ;字符属性写入显存地址
inc si ;si定位字符窜ASCII偏移地址
add bx,2 ;bX定位写入显存的偏移地址
loop s ;循环
s1: pop si ;相关寄存器数据还原
pop dx
pop cx
pop bx
pop ax
ret ;返回调用程序
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2009-05-16 19:25 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-28 23:57 |
这么长,来个短点的
assume cs:code
data segment
db'welcome to masm!',0
data ends
code segment
start:mov dh,8
mov dl,3
mov cl,2
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str:mov al,160
mul dh
mov dh,0
add ax,dx
mov bx,ax
mov ax,0b800h
mov es,ax
mov di,0
mov ah,cl
s: mov al,[si]
mov word ptr es:[bx+di+1],ax
mov ch,0
mov cl,al
jcxz ok
add si,1
add di,2
jmp short s
ok: ret
code ends
end start | | |
|
|
|
|
[第2楼]
[ 回复时间:2009-05-17 10:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05 |
你所谓的短 就是 少几行空格 以及 不做寄存器原始数据备份和恢复啊 狂汗 | | |
|
|
|
|
[第3楼]
[ 回复时间:2009-06-11 16:31 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-12-21 10:26 |
呵呵,短是没短多少,不过有值得学习的地方,还有我觉得楼主的LOOP指令用得没有JMP恰当 | | |
|
|
|
|
[第4楼]
[ 回复时间:2009-06-13 10:17 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-06-12 14:58 |
自己也写了一个,不过不规范,没怎么注释。
DATAS SEGMENT
db 'welcome to masm!',0
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov dh,8
mov dl,3
mov cl,2
call show_str
MOV AH,4CH
INT 21H
show_str:
mov ax,0b800h ;定义显示位置
mov es,ax
mov al,160
mul dh
add dl,dl
add al,dl
mov bx,ax
mov si,0
mov di,0
push dx
mov ch,0
push cx
pop dx
s:
mov cl,[si]
jcxz ok
mov ah,dl
mov al,cl
mov es:[bx+di],ax
inc si
add di,2
loop s
ok:
mov cx,dx
pop dx
ret
CODES ENDS
END START | | |
|
|
|
|
[第5楼]
[ 回复时间:2009-06-22 02:45 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:3
注册日期:2009-03-13 16:19 |
楼主 我仔细看了你的程序,我想请问你,你在计算行偏移的时候加上了一句 "dec dh"也就是将行数减一再去乘160,你有没有仔细去数过你的程序显示真的是在第8行吗?恐怕应该在第7行吧!
我当初做的是和你一样的,计算的时候也加上了一句"dec dh" 就始终不能再正确的位置显示! | | |
|
|
|
|
[第6楼]
[ 回复时间:2009-06-23 09:51 ]
[引用]
[回复]
[ top ] | |
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05 |
对于对象 我们来说 1~9 对应的是屏幕上 1~9行
对于 cpu来说 0才是他的第一行 所以要在 屏幕上第一行显示 必须输入的行数-1 | | |
|
|
|
|
[第7楼]
[ 回复时间:2009-07-26 13:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2009-06-29 14:39 |
楼主这里不能用loop吧,不然如果恰好碰到01h不是就出问题啦 | | |
|
|
|
|
[第8楼]
[ 回复时间:2009-07-31 09:16 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:3
注册日期:2009-06-08 15:13 |
个人认为在子程序中忽略保护寄存器而追求代码短是一种错误的做法
assume cs:code,ds:data,ss:stack
data segment
db 'Welcome to masm!',0
data ends
stack segment
dw 8 dup(0)
stack ends
code segment
start: mov dh,16
mov dl,50
mov cl,42
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,16
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str:push ax
push bx
push cx
push dx
push es
push di
push ds
push si
mov ax,0b800h
mov es,ax
mov al,160
mul dh
mov bx,ax ;bx中保存行
mov dh,0
add dx,dx
mov di,dx ;di中保存列
mov al,cl ;al中保存颜色
print: mov cl,[si]
mov ch,0
jcxz out
mov es:[bx+di],cl
mov es:[bx+di+1],al
inc si
add di,2
jmp short print
out:pop si
pop ds
pop di
pop es
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start | | |
|