在16位匯編程序中,可以使用DOS中斷21h
的功能號09h
來打印字符串;下面是一個簡單的示例程序,演示了如何在16位匯編程序中打印字符串:
assume cs:code,ds:data
?
data segmentszBuffer 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 21hcode 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 segmentszBuffer db 0dh,0ah,'HelloWorld$'
data ends
?
code segment
start:mov ax,datamov ds,ax//打印字符串mov ah,09hlea dx,szbufferint 21hint 21h ;再次調用中斷打印字符串mov ax,4c00hint 21hcode ends
end start
-
lea dx, szBuffer
:將szBuffer
的偏移地址加載到DX
寄存器。 -
int 21h
:調用DOS中斷21h,打印以$
結束的字符串。 -
int 21h
:再次調用中斷,重復打印字符串。
最后運行該程序生成的exe
文件: