版权声明:斌哥版权,如有雷同,纯属虚构 https://blog.csdn.net/iostream992/article/details/83413626
编写三个子程序,通过他们来认识几个常见的问题和掌握解决这些问题的方法
1、显示字符串
; 显示字符串子程序show_str
; 参数1 ds:si指向要显示的字符串首地址,字符串以0结尾
; 参数2 行号dh(0~24)
; 参数3 列号dl(0~79)
; 参数4 颜色属性 cl
show_str:
push ax
push bx
push cx
push dx
push si
push es
show_str_start:
mov ax,0b800h
mov es,ax
; 计算行偏移 ,结果在ax中
mov al,160
mul dh
; 计算列偏移 ,结果在dx中
mov dh,0
add dx,dx
;计算总偏移,结果放在bx中
mov bx,ax
add bx,dx
;到目前,es:[bx]指向目标显存
mov dl,cl
string_copy:
mov cl,[si]
mov ch,0
jcxz string_copy_ok ;当(ds:[si])==0时跳出循环
mov es:[bx],cl
mov es:[bx+1],dl
inc si
add bx,2
jmp short string_copy
string_copy_ok:
pop es
pop si
pop dx
pop cx
pop bx
pop ax
ret
2、解决除法溢出的问题
; 解决除法溢出的子程序divdw
; 参数1 被除数 dx+ax 32位组合
; 参数2 除数 cx
; 返回值 商:dx+ax 余数: cx
divdw:
push bx
push ax
; 被除数高位除CX 27/2 --> AX 商 DX 余数
mov ax,dx
mov dx,0
div cx
mov bx,ax ;商的高16位暂时存放在BX中
; 商在AX中,余数在DX中
; 余数就是最终的余数放到CX中去,商就是最终的商的低16位,不用动!
pop ax
div cx
mov cx,dx
mov dx,bx
pop bx
ret
3、数值显示
; dtoc
; 参数1 ds:si 指向最终字符串首地址
; 参数2 待转换的word型数据 ax
dtoc:
push ax
push bx
push cx
push dx
push si
push di
dtoc_start:
mov di,0 ; 用di 存放压入的数据个数
pick:
mov dx,0
mov bx,10
div bx ; 商在ax中 余数在dx中,直接进栈
add dx,30h
push dx
inc di
mov cx,ax
jcxz pick_ok
jmp short pick
pick_ok:
mov cx,di ; 确定弹出的数据个数
; 堆栈中的数据出栈,送到目标内存位置
dtoc_move:
pop ax
mov ds:[si],al
inc si
loop dtoc_move
; 在字符串末尾添加一个结束符0
mov byte ptr [si],0
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret