时光地下铁

走走停停,看看风景

0%

汇编:显示字符串

8086汇编中,有一道在屏幕上显示字符串的子程序。因为好久没做汇编题了,花了两个多小时,这里记录一下做的过程。
题目是这样的:

显示字符串是现实工作中经常要用到的功能, 应该编写一个通用的子程序来实现这个功能。我们应该提供灵活的调用接口,使调用者可以决定显示的位置(行、列)、内容和颜色。
子程序描述
名称: show_str
功能: 在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数: (dh)= 行号(取值范围024), (di)= 列号(取值范围079)
(cl)=颜色, ds:si指向字符串的首地址
返回: 无

示例程序要求:在屏幕的8行3列, 用绿色显示data段中的字符串。
下面是我写的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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:
push ax
push bx
push bp ;bp用来读取显存中的偏移地址
push es ;es用来读取显存中的起始地址

mov ax,0b800h
mov es,ax ;将起始地址存入es

mov al,dh ;显存偏移地址行号的偏移计算
mov ah,0
sub al,1
mov bl,0a0h
mul bl
mov bp,ax

mov ax,0 ;显存偏移地址列号的偏移计算
mov al,dl
mov bl,2
mul bl
add bp,ax ;偏移地址都加到bp中

s: push cx
mov cl,[si]
mov ch,0
jcxz ok ;根据0判断循环的结束。程序结束时需要pop cx
pop cx
mov al,[si] ;低位存字母
mov ah,cl ;高位存颜色
mov es:[bp],ax ;设置到屏幕内存中
inc si
add bp,2
jmp short s

ok: pop cx ;逐个pop用过寄存器
pop es
pop bp
pop bx
pop ax
ret

code ends
end start