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