注册 登录
编程论坛 汇编论坛

[求助]学了王爽的《汇编语言》,有个小问题请教大家

nofarewell 发布于 2007-11-04 22:56, 1436 次点击
学了王爽的汇编语言许久,今天终于能往屏幕上输出点东西了,汗。做了实验十第一题,感觉题目有点怪,居然用cl存储字体颜色,但又要用cx来判断字符串结束,所以只好在子程序循环中把cx再次入栈(子程序开始前就入了一次了)总是感觉很怪。。。我觉还是我编得不好。把程序贴出来大家帮我看看:
题目:设计一个子程序
名称:show_str
功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:(dh)=行号,(取值范围0-24),(dl)=列号(取值范围0-79),(cl)=颜色,ds:si指向字符串首地址
my code:

assume cs:code
data segment
db 'welcome to masm!',0
data ends
code segment
start: mov dh,8 ;给各参数赋值
mov dl,3
mov cl,0cah
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 ;cx第一次入栈
push es
push di
push si
mov ax,0b800h ;以下代码为定位要显示的行,列
mov es,ax
mov ah,0
mov al,0a0h
mul dh
mov bx,ax
mov ah,0
mov al,2
mul dl
mov di,ax
to_show: mov ch,ds:[si] ;to_show段处理写要写处显存的字符串,结束条件为遇到字符串后面的0
push cx ;cx第二次入栈,不入栈下一次就没法用cx判断是否继续循环了
mov cl,0
jcxz ok
pop cx
mov es:[bx+di],ch
mov es:[bx+di+1],cl
inc si
add di,2
jmp short to_show
ok: pop cx ;好多的pop,push...
pop si
pop di
pop es
pop cx
pop bx
pop ax
ret
code ends
end start

调试通过。但总感觉太繁琐,另外还有个问题,子程序运行之前有必要把所有用到的寄存器都入栈吗?包括在外部赋值的

[此贴子已经被作者于2007-11-4 23:17:44编辑过]

7 回复
#2
无理取闹2007-11-05 19:41
什么叫王爽的汇编  听起来真不爽
#3
nofarewell2007-11-05 22:53
不爽不爽 课程都快结束了,居然才告诉读者汇编可以计算表达式的值!啊啊啊 这程序原来几行就可以完成
#4
howarezhao2007-11-14 00:30
这个看得我毫无头绪啊~LZ能告诉一下我思路吗?~,0b800h是什么?为什么要mul dh?我看到这个题目时完全没有思路~还有那几行的代码?
#5
永夜的极光2007-11-14 08:34

下面是我当时写的程序

assume ds:data,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:
    push bx    ;保存各个寄存器
    push cx
    push di
    push ax
    push si
    push es
    mov ax,0b800H    ;第0页的起始地址存入es,作为段地址
    mov es,ax
    mov bx,0    ;bx控制行
    mov di,0    ;di控制列
    mov ah,cl    ;将颜色保存在ah,后面将文字保存到al,直接复制ax就行
    mov cl,dh    ;bx移动到指定行
    s1:
        add bx,0a0H
    loop s1
    mov cl,dl    ;di移动到指定列
    s2:
        add di,2
    loop s2
    s3:                ;写入显存
        mov cl,[si+1]    ;把si的后一位存到cl,如果后一位为0,则可以跳出循环
        mov ch,0            
        mov al,[si]        ;si指向的值存入al,颜色已经在上面存入ah了
        mov es:[bx+di],ax    ;整个ax赋值给显存
        add di,2
        inc si
        inc cx    ;因为loop判断是否结束,是先把c减1,再判断,所以如果c=0,是不会结束的,要c=1,才会结束
    loop s3
    pop es    ;各寄存器出栈
    pop si
    pop ax
    pop di
    pop cx
    pop bx
    ret
code ends
end start



我是用al来存放待显示字符的,所以不需要把cx第二次入栈

我也是到后面才知道能用表达式的....所以用了两个循环来移动到开始显示的地方......

不过这本书感觉还是挺不错的

#6
kr_zHaYj2007-11-14 10:06

dseg segment
msg db 'enter into the par',0
mode db ?
attr db 1

dseg ends

cseg segment
assume cs:cseg,ds:dseg,es:dseg

main: mov ax,dseg
mov ds,ax

mov ah,0fh
int 10h
mov mode,al

mov ax,0001h
int 10h

mov ax,0b800h
mov es,ax
mov di,0

mov si,offset msg
dismsg:
lodsb
or al,al
jz exit
mov ah,attr
stosw
add di,80
inc attr
jmp dismsg

exit: mov ah,0
int 16h

mov ah,0
int 10h



mov ah,4ch
int 21h
cseg ends
end main

#7
kr_zHaYj2007-11-14 10:09

这个程序 所用的知识点 都差不多,运行下看看.

0b800h是 DOS 下存放 图形和字符的 缓冲区 ,你可以用 E 命令编辑下这段内存看看,

王爽汇编上有的

#8
howarezhao2007-11-14 23:32
好~~~~~多谢啦~~~~~~
1