前几个实验都没记录,实验10想记录一下!
问一下!markdown里汇编咋高亮啊,灰了吧唧好难看
1.显示字符串
名称:show_str
功能:指定位置,指定颜色,显示一个以数字0结束的字符串
参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si->字符串
返回:无
;ds:si->字符串首地址
;dh行号 dl列号 cl颜色
;寄存器均不会被修改
show_str:
push es
push di
push ax
push bx
push cx
push dx ;将用到的寄存器入栈
mov ax,0b800H
mov es,ax
xor ax,ax
mov al,160
mul dh ;8位乘
xor dh,dh
add dx,dx
add ax,dx
mov di,ax ;es:di->指定显示首地址
mov al,cl ;cl即将被用作判断
xor bx,bx
s0: mov cl,ds:[si+bx]
jcxz ok0 ;若(cx)=0退出循环
mov es:[di+0],cl ;写入要打印的字符
mov es:[di+1],al ;写入要打印字符的颜色
inc bx
add di,2
jmp s0
ok0:pop dx
pop cx
pop bx
pop ax
pop di
pop es ;恢复被修改的寄存器
ret
2.解决除法溢出的问题
名称:divdw
功能:32位除商不会溢出(余数自然不会溢出)
参数:(dx)(ax)=被除数,(cx)=除数
返回:(dx)(ax)=商,(cx)=余数
;(dx)=H,(ax)=L,(cx)=N
;(dx)(ax)/(cx)=(dx)(ax)
;(dx)(ax)%(cx)=(cx)
;除返回所用寄存器外,其他均不会被修改
divdw:
push bx ;将用到的寄存器入栈
mov bx,ax ;(bx)=被除数低16位
mov ax,dx
xor dx,dx ;(dx)(ax)=H
div cx ;32位除,(ax)=H/N,(dx)=H%N
push ax ;压入H/N
mov ax,bx ;(dx)(ax)=H%N*65536+L
div cx ;(ax)=(H%N*65536+L)/N
mov cx,dx ;(cx)=(dx)=余数
pop dx ;(dx)(ax)=
; H/N*65536+(H%N*65536+L)/N
pop bx ;恢复被修改的寄存器
ret
3.数值显示
(1)dtoc子程序
名称:dtoc
功能:将范围在0-65535的数据转化为十进制字符串,并添加数字0结尾
参数:(ax)=操作数据,ds:si->字符串
返回:无
;ds:si->字符串,(ax)=操作数据
;字符串结尾添加数字0
;寄存器均不会被修改
dtoc:
push ax
push bx
push dx
push cx
push di ;将用到的寄存器入栈
xor di,di ;di记录转化后字符串长度,方便ok1
s3: mov bx,10
xor dx,dx ;(dx)(ax)=操作数据
div bx
mov cx,ax
push dx ;将余数压入栈:若直接写入string段则为逆序
inc di
jcxz ok1
jmp s3
ok1:mov cx,di
xor bx,bx
s4: pop ax
add ax,30H ;将数字(0-9)转化为字符
mov ds:[si+bx],al ;!注意,这里是al而不是ax
inc bx
loop s4
mov ds:[si+bx],0 ;结尾添加数字0
pop di
pop cx
pop dx
pop bx
pop ax ;恢复被修改的寄存器
ret
(2)问题:编程,将data段数据以十进制显示
data segment
dw 123,12666,1,8,3,38
data ends
代码如下:
assume cs:codesg,ds:data
data segment
dw 123,12666,1,8,3,38
data ends
string segment
db 'I am a happy space occupying sentence!'
string ends
stack segment
dw 0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0 ;栈空间:0-1fH
stack ends
codesg segment
start:
mov ax,stack
mov ss,ax
mov sp,20H ;初始化栈
mov ax,string
mov ds,ax
xor si,si ;ds:si->字符串
mov ax,data
mov es,ax
mov di,di ;es:di->操作数据集
mov dh,5
mov dl,20
mov cl,2 ;准备show_str参数:5行20列绿色
push cx ;记录颜色信息,cx即将被用作循环计数
mov cx,6
xor bx,bx
s1: mov ax,es:[di+bx] ;准备dtoc参数
call dtoc
mov ax,cx ;ax暂存循环计数
pop cx ;归还颜色信息给cx
call show_str
push cx
mov cx,ax ;归还循环计数给cx
inc dh ;下个操作数据将打印在下一行,偷个懒哈哈哈
add bx,2
call dtoc
loop s1
mov ax,4c00H
int 21H
;ds:si->字符串,(ax)=操作数据
;字符串结尾添加数字0
;寄存器均不会被修改
dtoc:
push ax
push bx
push dx
push cx
push di ;将用到的寄存器入栈
xor di,di ;di记录转化后字符串长度,方便ok1
s3: mov bx,10
xor dx,dx ;(dx)(ax)=操作数据
div bx
mov cx,ax
push dx ;将余数压入栈:若直接写入string段则为逆序
inc di
jcxz ok1
jmp s3
ok1:mov cx,di
xor bx,bx
s4: pop ax
add ax,30H ;将数字(0-9)转化为字符
mov ds:[si+bx],al ;!注意,这里是al而不是ax
inc bx
loop s4
mov ds:[si+bx],0 ;结尾添加数字0
pop di
pop cx
pop dx
pop bx
pop ax ;恢复被修改的寄存器
ret
;ds:si->字符串首地址
;dh行号 dl列号 cl颜色
;寄存器均不会被修改
show_str:
push es
push di
push ax
push bx
push cx
push dx ;将用到的寄存器入栈
mov ax,0b800H
mov es,ax
xor ax,ax
mov al,160
mul dh ;8位乘
xor dh,dh
add dx,dx
add ax,dx
mov di,ax ;es:di->指定显示首地址
mov al,cl ;cl即将被用作判断
xor bx,bx
s0: mov cl,ds:[si+bx]
jcxz ok0 ;若(cx)=0退出循环
mov es:[di+0],cl ;写入要打印的字符
mov es:[di+1],al ;写入要打印字符的颜色
inc bx
add di,2
jmp s0
ok0:pop dx
pop cx
pop bx
pop ax
pop di
pop es ;恢复被修改的寄存器
ret
codesg ends
end start
运行结果如下: