可能有点乱,大家凑合看,错误不足请指正!
1、显示字符串
assume cs:code, ds:data, ss:stack
;数据段
data segment
db 'Welcome to masm!',0
data ends
;栈段
stack segment
dw 16 dup(0)
stack ends
;代码段
code segment
start:
mov ax,stack
mov ss,ax
mov sp,20H
;在第8行3列显示绿色字符串
mov dh,8
mov dl,3
mov cl,2
mov ax,data
mov ds,ax
mov si,0
call show_str
;在第9行3列显示红色字符串
mov dh,9
mov dl,3
mov cl,4
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00H
int 21H
show_str:
push dx
push cx
push si
push di
mov ax,0B800H
mov es,ax
;计算行地址
sub dh,1
mov al,dh
mov bl,0A0H
mul bl
mov di,ax
;加上列地址
mov al,2
mul dl
add di,ax
mov al,cl ;字符颜色
copy:
mov cl,ds:[si]
mov ch,0
jcxz last ;到字符串末尾就返回
mov byte ptr es:[di],cl
mov byte ptr es:[di+1],al
inc si
add di,2
loop copy
last:
pop di
pop si
pop cx
pop dx
ret
code ends
end start
运行结果:
2、解决除法溢出问题
assume cs:code
;代码段
code segment
start:
mov ax,4240H
mov dx,000FH
mov cx,0AH
call divdw
mov ax,4c00H
int 21H
divdw:
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
div cx
mov cx,dx
mov dx,bx
ret
code ends
end start
这题纯是在网上抄的,公式看不明白,根据网上代码理解如下
X:被除数,范围:[0,FFFFFFFF]
N:除数,范围:[0,FFFF]
H:X高16位,范围:[0,FFFF]
L:X低16位,范围:[0,FFFF]
+:运算符,表示双字节的高16位和低16位的整体
int():描述性运算符,取商
rem():描述性运算符,取余数
X/N的商 = int(H/N) + int((rem(H/N)+L)/N)
X/N的余 = rem((rem(H/N)+L)/N)
按照这个式子应该可以写出来,至于问为什么,我也不知道
运行结果:
3、数值显示
(1)先是固定值在ax中
assume cs:code, ds:data, ss:stack
data segment
dw 16 dup(0)
data ends
stack segment
dw 16 dup(0)
stack ends
;代码段
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc
mov dh,9
mov dl,3
mov cl,4
call show_str
over:
mov ax,4c00H
int 21H
dtoc:
push bx
push di
push dx
push si
push cx
push ss
push sp
mov bx,stack
mov bx,10
mov di,0
pushs:
mov dx,0
div bx
add dx,30H
push dx
mov cx,ax
inc di
jcxz strend
jmp short pushs
strend:
mov cx,di
moves:
pop ax
mov byte ptr ds:[si],al
inc si
loop moves
mov ax,0
mov byte ptr ds:[si],al
pop sp
pop ss
pop cx
pop si
pop dx
pop di
pop bx
ret
show_str:
push dx
push cx
push si
push di
mov ax,0B800H
mov es,ax
;计算行地址
sub dh,1
mov al,dh
mov bl,0A0H
mul bl
mov di,ax
;加上列地址
mov al,2
mul dl
add di,ax
mov al,cl ;字符颜色
copy:
mov cl,ds:[si]
mov ch,0
jcxz last ;到字符串末尾就返回
mov byte ptr es:[di],cl
mov byte ptr es:[di+1],al
inc si
add di,2
loop copy
last:
pop di
pop si
pop cx
pop dx
ret
code ends
end start
运行结果:
(2)然后是值在数据段中
利用前面已经写好的两个子程序,每次将数据段中的新值赋给ax,调用dtoc完成字符串转换,然后将show_str的字符串数据段改一下就行了,但是要注意各个寄存器值的变化,除了特殊需要,将子程序用到的寄存器都进行压栈出栈处理!!!
assume cs:code, ds:data, ss:stack
;要显示的数字
data segment
dw 123,12666,1,8,3,38
data ends
;存放转换后的字符串
string segment
dw 16 dup(0)
string ends
;栈段
stack segment
dw 16 dup(0)
stack ends
;代码段
code segment
start:
mov ax,data
mov es,ax
mov di,0 ;di - 表示要显示的数字的字节偏移
mov dh,9 ;dh - 从第几行开始打印
s:
mov ax,es:[di]
mov cx,ax
jcxz over ;cx为0就跳到over,直接返回
mov bx,string
mov ds,bx
mov si,0 ;si - 要转换数字的地址(dtoc中),也是打印字符串的首地址(show_str中)
call dtoc ;执行数字转字符串子程序
mov dl,3 ;打印的列数
mov cl,4 ;颜色
call show_str ;执行打印字符串子程序
add dh,1 ;下一个字符串在下一行打印
add di,2 ;由于是字型所以+2
jmp s
over:
mov ax,4c00H
int 21H
dtoc:
push bx
push di
push dx
push si
push cx
push ss
push sp
mov bx,stack
mov bx,10
mov di,0
pushs:
mov dx,0
div bx
add dx,30H
push dx
mov cx,ax
inc di
jcxz strend
jmp short pushs
strend:
mov cx,di
moves:
pop ax
mov byte ptr ds:[si],al
inc si
loop moves
mov ax,0
mov byte ptr ds:[si],al
pop sp
pop ss
pop cx
pop si
pop dx
pop di
pop bx
ret
show_str:
push dx
push cx
push si
push di
push es
mov ax,0B800H
mov es,ax
;计算行地址
sub dh,1
mov al,dh
mov bl,0A0H
mul bl
mov di,ax
;加上列地址
sub dl,1
mov al,2
mul dl
add di,ax
mov al,cl ;字符颜色
copy:
mov cl,ds:[si]
mov ch,0
jcxz last ;到字符串末尾就返回
mov byte ptr es:[di],cl
mov byte ptr es:[di+1],al
inc si
add di,2
loop copy
last:
pop es
pop di
pop si
pop cx
pop dx
ret
code ends
end start
运行结果: