Intel汇编语言程序设计学习-第五章 过程-上
過程
5.1 ?簡介
? ?需要閱讀本章的理由可能很多:
??1.讀者可能想要學習如何在匯編語言中進行輸入輸出。
??2.應該了解運行時棧(runtime stack),運行時棧是子過程(函數)調用以及從子過程返回的基本機制。
??3.通過本章,將學到如何把大程序劃分為模塊化的子過程。
??4.本章講述流程圖,流程圖是描述程序邏輯的圖形工具。
5.2 ?外部庫鏈接
? ? 鏈接庫Irvine32.lib用于32位保護模式下編寫的程序,其中進行輸入輸出的過程調用了MS-Windows API。庫Irvine16.lib用于16位實地址模式下編寫的程序,其中進行輸入輸出的過程調用了MS-DOS中斷。
5.2.1 ?背景知識
???鏈接庫(link library)是一個文件,其中包含了已經編譯成機器碼的過程。庫可以由一個或多個源代碼文件構成,這些文件被匯編成目標文件,然后這些目標文件被插入到一個特定格式的文件-庫中,鏈接實用工具能夠識別這種特定的文件格式。假設程序要調用名為WriteString的過程在控制臺上顯示一個字符串,那么程序源碼中就必須包含下面的PROTO偽指令聲明WriteSteing過程:
WriteString PROTO
然后,用一條CALL指令執行WeiteString過程:
call WriteString
匯編器匯編程序的時候,為CALL指令的目的地址留出空白,該空白所有將由鏈接器填充為實際的目的地址。鏈接器在鏈接庫中查找WriteString這個名字,并從庫中把響應的機器指令復制到程序的可執行文件中,然后把WriteString在可執行文件的實際地址插入到CALL指令中為目的地址留出空白處。如果視圖調用不在鏈接庫中的過程,鏈接器會產生一條錯誤消息并拒絕生成可執行文件。
鏈接器的命令行選項:鏈接器程序把程序的目標文件和其他目標文件以及庫文件合并起來。例如下列命令將hello.obj,irvine32.lib,kernel32.lib相連接:
link hello.obj irvine32.lib kernel32.lib
? ? 鏈接32位程序:下面解釋一下鏈接32位程序時使用的鏈接庫kernel32.lib。kernel32.lib文件是Microsoft Windows平臺軟件開發包(platform SDK)的一部分,它包含了kernel32.dll中的操作系統函數的鏈接信息。kernel32.dll是Microsoft Windows操作系統的一個基本組件,稱為動態鏈接庫,其中包含了執行基本字符輸入輸出功能的可執行函數。讀者可以把kernel32.lib想象成桐鄉kernel32.dll的橋梁,如圖:
?
5.3 ?本書附帶的鏈接庫
5.3.1 ?概述
? ? 下表列出了Irvine32和Irine16鏈接庫中常用的過程。盡管庫Irvine16.lib是用于16位(實地址)程序的,它還是使用了32位的寄存器。Irvine32.lib和Irvine16.lib同時包含本屆的大多數過程。對那些只有Irvine32.lib才有的過程在描述后以”*”進行了標注。
?
? ? 控制臺窗口:控制臺窗口(console window)是MS-Windows創建的文本窗體,所有Windows版本控制臺窗口的大小默認和MS-DOS一樣,都是25*80的。可以使用mode命令修改行數和列數。
mode con cols=40 lines=30
重定向輸入和輸出 ?
庫Irvine32和Irvine16都向控制臺寫輸出數據。但是可以進行重定向,假設一個程序sample.exe要向標準輸出(控制臺)寫數據,可以在命令行提示符下使用如下命令把它的輸出重定向到一個名為output.txt的文件中:
sample > output.txt
input.txt內同做為輸入:
sample < input.txt
可以使用一條命令同時重定向輸出和輸出
sample < input.txt > output.txt
還可以使用管道(|)把1的輸出做為2的輸入
prog1 | prog2
把1的輸出做為2的輸入,然后把2的輸出存到文檔里
prog1 | prog2 > output.txt
下面的例子中,1從文檔中讀取輸入,然后把自己的輸出做為2的輸入,然后2把輸出存在另一個文檔中
prog1 < input.txt | prog2 > output.txt
5.3.2 ?過程的描述
CloseFile(僅Irvine32):CloseFile過程關閉一個之前打開的文件。文件是以文件句柄(handle)標示的,文件句柄通過EAX傳遞。如果文件被成功關閉,EAX中返回非零值。如:
mov eax,fileHandle
call CloseFile
Clrscr:Clrscr過程用于清除控制臺窗口的內容,他們通常在程序開始和結束時使用,如果在其他時刻調用,做好在嗲用Clrscr之前暫停一下程序(調用WaitMsg),以便用戶在屏幕擦除之前能夠看清已有的信息,例子:
call WaitMsg
call Clrscr
Crlf:Crlf過程把光標定位到控制臺窗口下一行的開始,該功能是通過向標準輸出寫包含0Dh和0Ah兩個字符的字符串來實現的,例子:
call Crlf
CreateOutputFile(僅Irvine32):CreateOutPutFile過程創建一個磁盤文件并以輸出模式打開使用時通過EDX傳遞要創建的文件名的偏移地址。過程返回時,如果文件成功創建,則EAX包含有效的文件句柄(一個32位整數)。如果創建失敗,EAX中的值是INVALID_HANDLE_VALUE。例子:
.data
filename BYTE “newfile.txt”?,0
myhandle DWORD ?
.code
mov edx,OFFSET filename
call CreatePutputFile
cmp eax,INVALID_HANDLE_VALUE
je file_error ?;顯示錯誤信息
mov myhandle,eax
注意:前面的代碼比較EAX和預定義常量INVALID_HANDLE_VALUE是否相等。如果相等,則跳轉到名為file_error的標號處。CMP和JE指令在第6張介紹,這里給出的錯誤處理代碼是為了完成起見。
Delay:Delay過程暫停程序指定的毫秒數。在調用該程序之前需要把EAX初始化為預期暫停的時間,單位以毫秒計算。
mov eax,1000 ??;1s
call Delay
DumpMem:DumpMem過程以十六進制數格式在控制臺窗口中顯示一塊內存的內容。在調用之前,需要將ESI設置為內存的開始地址,ECX設置為元素的數目,EBX設置為元素尺寸(1=byte,2=word,4=doubleword)。下面的語句顯示一個名為array的包含11個雙字變量的數組:
.data
array DWORD 1,2,3,4,5,6,7,8,9,0Ah ,0Bh
.code
main PROC
????mov esi,OFFSET array ?????;起始地址
????mov ecx,LENGTHOF array ??;元素數目
????mov ebx,TYPE array ???????;格式為雙字
????call DumpMem
上例的輸出如下
?
DumpRegs:DumpRegs 過程以一六進制數格式顯示EAX,EBX,EDX,ESI,EDI,EBP,ESP,EIP,EFL(EFLAGS)寄存器的內容,并同時顯示進位、符號、零和移除標志的值。使用舉例:
call DumpRegs
例子輸出:
?
? ? 顯示的EIP值是緊跟在call DumpRegs語句后面的指令的偏移地址,DumpRegs函數咋提調試程序的時候可能非常有用,因為它能夠顯示程序運行時CPU的狀態快照。該過程沒有輸入參數和返回值。
?
總結
以上是生活随笔為你收集整理的Intel汇编语言程序设计学习-第五章 过程-上的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows核心编程-第一章 对程序错
- 下一篇: windows核心编程-第二章 Unic