在16位汇编程序中,可以使用DOS中断21h的功能号09h来打印字符串;下面是一个简单的示例程序,演示了如何在16位汇编程序中打印字符串:
assume cs:code,ds:data
data segment
szBuffer db 0dh,0ah,'HelloWorld$' //定义字符串
data ends
code segment
start:
mov ax,data ; 将数据段地址加载到AX寄存器中
mov ds,ax ; 将AX中的数据段地址加载到DS寄存器中
(`DS` 寄存器是一个段寄存器,用于存储数据段的地址。)
mov dx,offset szBuffer ; 将szBuffer的偏移地址加载到DX寄存器中
mov ah,09h ; DOS功能号09h,用于显示字符串
int 21h ; 调用DOS中断21h
mov ax,4c00h
int 21h
code ends
end start
assume cs:code, ds:data:指令告诉汇编器代码段位于 cs 寄存器所指示的代码段中,数据段位于 ds 寄存器所指示的数据段中。
data segment 和 data ends 之间的部分是数据段。在这里,szBuffer 被定义为一个字符串,以 $ 结尾。
0dh 和 0ah 是 ASCII 字符集中的转义序列,分别代表回车(Carriage Return)和换行(Line Feed)。
-
0dh对应于回车字符,表示将光标移动到当前行的开头,但不换行。通常与0ah结合使用,表示回车换行,即在显示文本时,光标移到下一行的开头。 -
0ah对应于换行字符,表示将光标移动到下一行的开头。
code segment 和 code ends 之间的部分是代码段。在 start 标签处开始执行。
mov ax, data:将数据段地址加载到 AX 寄存器中。
mov ds, ax:将 AX 中的数据段地址加载到 DS 寄存器中,这样程序就可以访问数据段中的数据。
mov dx, offset szBuffer:将 szBuffer 的偏移地址加载到 DX 寄存器中;offset 操作符用于获取标签(如变量或标签)的偏移地址。
mov ah, 09h:将 09h 存储在 AH 寄存器中,该值表示调用 DOS 中断 21h 的功能号 09h,用于显示字符串。
int 21h:调用 DOS 中断 21h,显示字符串。
使用ML.exe对汇编程序进行处理后,执行处理后生成的exe程序,得到结果:

上述代码中我们使用OFFSET操作符将szBuffer字符串变量的地址偏移值计算出来,接着使用mov指令将偏移值移入dx寄存器中,接着使用DOS中断21h的功能号09h来打印字符串,即将功能号09h传入ax寄存器的高地址寄存器ah中,最后使用int 21h调用中断执行打印字符串的操作。
但其实在计算字符串的地址时除了使用OFFSET操作符之外,我们还可以使用lea指令取获取字符串的有效地址。
LEA指令
LEA指令(Load Effective Address)是x86汇编语言中的一条指令,用于将一个有效地址加载到寄存器中。它的主要用途是计算地址,但不进行内存访问。
语法
LEA destination, source
-
destination是一个寄存器,用于存储计算出的地址。 -
source是一个内存操作数,表示需要计算的有效地址。
此时我们使用lea指令获取字符串的有效地址,并调用中断将其打印
assume cs:code,ds:data
data segment
szBuffer db 0dh,0ah,'HelloWorld$'
data ends
code segment
start:
mov ax,data
mov ds,ax
//打印字符串
mov ah,09h
lea dx,szbuffer
int 21h
int 21h ;再次调用中断打印字符串
mov ax,4c00h
int 21h
code ends
end start
-
lea dx, szBuffer:将szBuffer的偏移地址加载到DX寄存器。 -
int 21h:调用DOS中断21h,打印以$结束的字符串。 -
int 21h:再次调用中断,重复打印字符串。
最后运行该程序生成的exe文件:
