鉴于全网到处都是该例题的各种解析,但是有些是有问题,有些没有完全实现要求(保存寄存器内容)等等,我决定实现一个可以随意移植到其他程序中的print函数.(确保正确,可以尽情参考(keep my nose in the air 滑稽保命))
这里提供该题的答案与解析
assume cs:code ;欲调用本程序,(dh)=行号(0~24),(dl)=列号(0~79),(ah)=颜色
;ds储存欲输出字符串的段地址,bx储存欲输出字符串的首字符的偏移地址
;栈至少有14 bytes剩余
data segment
db 'Hello World',0
data ends
stack segment ;用于从右往左临时保存cs,ip,bx,cx,bp,ax,es
dw 0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,14
;初始化dx,ax的值
mov dh,8
mov dl,3
mov ah,00000010b
call far ptr print
mov ax,4c00h
int 21h
stop: pop es
pop ax
pop bp
pop cx
pop bx
pop dx
retf
print: push bx ;输出一行字符,字符必须以0结尾.调用方式: call far ptr print
push cx
push bp
push ax
;调整bp的值,使bp指向需输出的行列
mov al,0a0h ;一行有160 bytes
mul dh
mov bp,ax
mov al,2
mul dl
add bp,ax ;每一个字符占2 bytes
sub bp,162 ;
;还原ax
pop ax
push ax
;初始化值,bx指向待显示字符串的首字符
mov bx,0
mov cx,0B800h
push es
mov es,cx
Obo: mov cl,ds:[bx]
mov ch,0
jcxz stop
mov ch,ah
mov es:[bp],cx
inc bx
add bp,2
jmp Obo
code ends
end start
是否正确可以自己数一哈,保证正确!!!
下面我将提炼一哈,使得该程序可以随意移植
printstop: pop es
pop ax
pop bp
pop cx
pop bx
pop dx
retf
print: push bx
push cx
push bp
push ax
mov al,0a0h
mul dh
mov bp,a
mov al,2
mul dl
add bp,ax
sub bp,162
pop ax
push ax
mov bx,0
mov cx,0B800h
push es
mov es,cx
printloop: mov cl,ds:[bx]
mov ch,0
jcxz printstop
mov ch,ah
mov es:[bp],cx
inc bx
add bp,2
jmp printloop
首先,向ds存入字符串所在位置的段地址.
接着向bx存入首位字符串的偏移地址(注意!该字符串结束时必须在后面加0!!!数字0!!!).
在dh内存入行号
在dl内存入列号
向ah内存入字符属性(该函数不支持每个文字都不同属性,只能一串字符串有相同的字符串)
确保栈内至少有14 Bytes(=7 字=112 bits)剩余
接着,call far ptr print