子程序一:
一、题目框架
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:
code ends
end start
二、思路
段寄存器es定位数据存入地址,由于存入地址一个字母需要两个字节(ASCII码和颜色),而数据中一个字母对应一个字节,故用寄存器di=2*si来定位具体存入地址,其中di(偶数)与ds:si对应,di+1(奇数)与颜色(02,绿)对应。代码如下:
show_str: mov ax,0B800h
mov es,ax
mov al,cl 后面用了jcxz判定,故将cl存入al中
next:mov cl,[si]
mov ch,0
mov di,si
add di,di
jcxz ok cl作用一:判断字符串是否结束
mov es:[di+1280+6],cl cl作用二:存储数据信息
mov es:[di+1280+6+1],al al处存储颜色信息
inc si
jmp next 跳转next继续执行
ok: ret 如jcxz判定cx=0,则返回主程序
三、改进
原来的show_str只能在八行三列输出,现在改为与dh、dl值相关。
show_str:
mov ax,0B800h
mov es,ax 确定段地址
mov al,0a0h 一行为80列,160字节,即a0h
mul dh 乘于行数
push ax 行位置存入栈
mov al,2 一列即一个字,两个字节
mul dl 乘于列数
pop di 取出行位置
add di,ax 加列位置,完成di对输出位置的定位
mov al,cl 之后用到cl判断,先把cl中数据存到al
next:mov cl,[si]
mov ch,0
jcxz ok
mov es:[di],cl 存入字
mov es:[di+1],al 存入颜色
inc si 指向下一个字(byte大小)
add di,2 指向下一个字(word大小)
jmp next
ok:ret
子程序二:
assume cs:code
code segment
start: mov ax,04240h
mov dx,000fh
mov cx,0ah
call divdw
mov ax,4c00h
int 21h
divdw: push ax 存入低16位
mov ax,dx 转移高16位
mov dx,0 把高16位赋0
div cx 第一次运算
mov bx,ax 高位商存入bx,此时余数在dx
pop ax 取出低16位
div cx 此时第一次运算的余数在dx中为高16位
mov cx,dx 余数存入cx
mov dx,bx 高位商存入dx(低位商已在ax中)
ret 返回
code ends
end start
子程序三:
assume cs:code
data segment
db 10 dup(0)
data ends
code segment
start: mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str
mov ax,4c00h
int 21h
dtoc: mov bx,10 \\除数
s: mov dx,0 \\高16位赋0;(数据只存在ax中)
div bx \\商在ax,余数在dx(余数小于10)
mov cx,ax \\商存入cx,用于jcxz判定是否结束
add dl,030H \\余数加上30H等于对应字符ASCII码
push dx \\存入余数,通过栈先入后出原则正序
inc si \\记录长度,pop时用
jcxz ok \\数字是否结束
jmp short s \\未结束继续
ok: mov cx,si \\循环次数
mov si,0 \\定位
s1: pop ax \\取出(003XH)
mov [si],al \\存入
inc si \\下一个位置
loop s1 \\循环
mov [si],cl \\给12666结尾(赋0),show_str用
mov si,0 \\si回归初始值
ret \\程序返回
show_str:mov ax,0B800h
mov es,ax
mov al,0a0h
mul dh
push ax
mov al,2
mul dl
pop di
add di,ax
mov al,cl
next: mov cl,[si]
mov ch,0
jcxz ok1
mov es:[di],cl
mov es:[di+1],al
inc si
add di,2
jmp next
ok1: ret
code ends
end start