亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 002.txt

?? 會變語言實現(xiàn)的一些程序
?? TXT
字號:
第二課 消息框


--------------------------------------------------------------------------------

在本課中,我們將用匯編語言寫一個 Windows 程序,程序運行時將彈出一個消息框并顯示"Win32 assembly is great!"。

理論:

Windows 為編寫應用程序提供了大量的資源。其中最重要的是Windows API (Application Programming Interface)。 Windows API是一大組功能強大的函數(shù),它們本身駐扎在 Windows 中供人們隨時調用。這些函數(shù)的大部分被包含在幾個動態(tài)鏈接庫(DLL)中,譬如:kernel32.dll、 user32.dll 和 gdi32.dll。 Kernel32.dll中的函數(shù)主要處理內存管理和進程調度;user32.dll中的函數(shù)主要控制用戶界面;gdi32.dll中的函數(shù)則負責圖形方面的操作。除了上面主要的三個動態(tài)鏈接庫,您還可以調用包含在其他動態(tài)鏈接庫中的函數(shù),當然您必須要有關于這些函數(shù)的足夠的資料。

動態(tài)鏈接庫,顧名思義,這些 API 的代碼本身并不包含在 Windows 可執(zhí)行文件中,而是當要使用時才被加載。為了讓應用程序在運行時能找到這些函數(shù),就必須事先把有關的重定位信息嵌入到應用程序的可執(zhí)行文件中。這些信息存在于引入庫中,由鏈接器把相關信息從引入庫中找出插入到可執(zhí)行文件中。您必須指定正確的引入庫,因為只有正確的引入庫才會有正確的重定位信息。

當應用程序被加載時 Windows 會檢查這些信息,這些信息包括動態(tài)鏈接庫的名字和其中被調用的函數(shù)的名字。若檢查到這樣的信息,Windows 就會加載相應的動態(tài)鏈接庫,并且重定位調用的函數(shù)語句的入口地址,以便在調用函數(shù)時控制權能轉移到函數(shù)內部。

如果從和字符集的相關性來分,API 共有兩類:一類是處理 ANSI 字符集的,另一類是處理 UNICODE 字符集的。前一類函數(shù)名字的尾部帶一個"A"字符,處理UNICODE的則帶一個"W"字符(我想"W"也許是代表寬字符的意思吧)。我們比較熟悉的ANSI字符串是以 NULL 結尾的一串字符數(shù)組,每一個ANSI字符是一個 BYTE 寬。對于歐洲語言體系,ANSI 字符集已足夠了,但對于有成千上萬個唯一字符的幾種東方語言體系來說就只有用 UNICODE 字符集了。每一個 UNICODE 字符占有兩個 BYTE 寬,這樣一來就可以在一個字符串中使用 65336 個不同字符了。

這也是為什么引進 UNICODE 的原因。在大多數(shù)情況下我們都可以用一個包含頭文件,在其中定義一個宏,然后在實際調用函數(shù)時,函數(shù)名后不需要加后綴"A"或"W"。
<譯者注:如在頭文件中定義函數(shù)foo();
#ifdef UNICODE
#define foo() fooW()
#else
#define foo() fooA()
#endif
>

例子:

我先把框架程序放在下面,然后我們再向里面加東西。

.386
.model flat, stdcall
.data
.code
start:
end start

應用程序的執(zhí)行是從 END 定義的標識符后的第一條語句開始的。在上面的框架程序中就是從 START 開始。程序逐條語句執(zhí)行一直到遇到 JMP,JNE,JE,RET 等跳轉指令。這些跳轉指令將把執(zhí)行權轉移到其他語句上,若程序要退出 Windows,則必須調用函數(shù) ExitProcess。

ExitProcess proto uExitCode:DWORD

上面一行是函數(shù)原型。函數(shù)原型會告訴編譯器和鏈接器該函數(shù)的屬性,這樣在編譯和鏈接時,編譯器和鏈接器就會作相關的類型檢查。 函數(shù)的原型定義如下: 

FunctionName PROTO [ParameterName]:DataType,[ParameterName]:DataType,... 

簡言之,就是在函數(shù)名后加偽指令PROTO,再跟一串由逗號相隔的數(shù)據(jù)類型鏈表。在前面的 ExitProcess 定義中,該函數(shù)有一個 DWORD 類型的參數(shù)。當您使用高層調用語句 INVOKE 時,使用函數(shù)原型定義特別有用,您可以簡單地認為 INVOKE 是一個有參數(shù)類型檢查的調用語句。譬如,假設您這樣寫:

call ExitProcess

若您事先沒把一個DWORD類型參數(shù)壓入堆棧,編譯器和鏈接器都不會報錯,但毫無疑問,在您的程序運行時將引起崩潰。但是,當您這樣寫:

invoke ExitProcess

連接器將報錯提醒您忘記壓入一個 DWORD 類型參數(shù)。所以我建議您用 INVOKE 指令而不是CALL去調用一個函數(shù)。INVOKE 的語法如下:

INVOKE expression [,arguments]

expression 既可以是一個函數(shù)名也可以是一個函數(shù)指針。參數(shù)由逗號隔開。大多數(shù)API函數(shù)的原型放在頭文件中。 如果您用的是 hutch 的 MASM32,這些頭文件在文件夾MASM32/include 下, 這些頭文件的擴展名為 INC,函數(shù)名和 DLL 中的函數(shù)名相同,譬如:KERNEL32.LIB 引出的函數(shù) ExitProcess 的函數(shù)原形聲明于kernel.inc中。您也可以自己聲明函數(shù)原型。 在我的教學課程中都使用 hutch 的windows。inc,這些頭文件您可以從http://win32asm.cjb.net下載。

好,我們現(xiàn)在回到ExitProcess 函數(shù),參數(shù)uExitCode 是您希望當您的應用程序結束時傳遞 Windows 的。 您可以這樣寫: 

invoke ExitProcess,0 

把這一行放到開始標識符下,這個應用程序就會立即退出 Windows,當然毫無疑問個應用程序本身是一個完整的 Windows 程序。

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

.data
.code
start:
invoke ExitProcess,0
end start

option casemap:none 一句的意思是告訴 MASM 要區(qū)分標號的大小寫,譬如:start 和 START 是不同的。請注意新的偽指令 include,跟在其后的文件名所指定的文件在編譯時將“插”在該處。在我們上面的程序段中,當MASM處理到語句 include \masm\include\windows.inc 時,它就會打開文件夾\MASM32\include 中的文件windows.inc,這和您把整個文件都粘貼到您的源程序中的效果是一樣的。 hutch 的 windows.inc 包含了 WIN32 編程所需要的常量和結構體的定義。 但是它不包含函數(shù)原型的定義。盡管 hutch 和我盡力包含所有的常量和結構體的定義,但仍會有不少遺漏,為此我們將不斷加入新的內容。請隨時注意我們主頁,下載最新的頭文件。

您的應用程序除了從 windows.inc 中得到相關變量結構體的定義外,還需要從其他的頭文件中得到函數(shù)原型的聲明,這些頭文件都放在 \masm32\include 文件夾中。 在我們上面的例子中調用了駐扎在 kernel.dll 中的函數(shù),所以需要包含有這個函數(shù)原型聲明的頭文件 kernel.inc。如果用文本編輯器打開該文件您會發(fā)現(xiàn)里面全是從 kernel.dll中引出的函數(shù)的聲明。如果您不包含kernel.inc,您仍然可以調用(call)ExitProcess,但不能夠調用(invoke)ExitProcess(這會無法通過編譯器和連接器的參數(shù)合法性檢查)。所以若用 invoke 去調用一個函數(shù),您就必須事先聲明,當然不一定要包含我們的頭文件,您完全可以在調用該函數(shù)前在源代碼的適當位置進行聲名。包含頭文件主要是為了節(jié)省時間(譯者:當然還有正確性)

接下來我們來看看 includelib 偽指令,和 include 不同,它僅僅是告訴編譯器您的程序引用了哪個庫。當編譯器處理到該指令時會在生成的目標文件中插入鏈接命令告訴鏈接器鏈入什么庫。當然您還可以通過在鏈接器的命令行指定引入庫名稱的方法來達到和用includelib指令相同的目的,但考慮到命令行僅能夠傳遞128個字符而且要不厭其煩地在命令行敲字符,所以這種方法是非常不可取的。

好了,現(xiàn)在保存例子,取名為msgbox.asm。把 ml.exe 的路徑放到 PATH 環(huán)境變量中,鍵入下面一行 進行編譯:

ml /c /coff /Cp msgbox。asm (譯者注:命令行參數(shù)大小寫是有區(qū)別的)

/c 是告訴MASM只編譯不鏈接。這主要是考慮到在鏈接前您可能還有其他工作要做。 
/coff 告訴MASM產生的目標文件用 coff 格式。MASM 的 coff 格式是COFF(Common Object File Format:通用目標文件格式) 格式的一種變體。在 UNIX 下的 COFF 格式又有不同。 
/Cp 告訴 MASM 不要更改用戶定義的標識符的大小寫。若您用的是 hutch 的包含文件的話,在.model 指令下加入 "option casemap:none" 語句,可達到同樣的效果。 
當您成功的編譯了 msgbox.asm 后,編譯器會產生 msgbox.obj 目標文件,目標文件和可執(zhí)行文件只一步之遙,目標文件中包含了以二進制形式存在的指令和數(shù)據(jù),比可執(zhí)行文件相差的只是鏈接器加入的重定位信息。 

好,我們來鏈接目標文件:

link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib msgbox.obj

/SUBSYSTEM:WINDOWS 告訴鏈接器可執(zhí)行文件的運行平臺 
/LIBPATH:〈path to import library〉 告訴鏈接器引入庫的路徑。 
鏈接器做的工作就是根據(jù)引入庫往目標文件中加入重定位信息,最后產生可執(zhí)行文件。 既然得到了可執(zhí)行文件,我們來運行一下。好,一、二、三,GO!屏幕上什么都沒有。哦,對了,我們除了調用了 ExitProcess 函數(shù)外,甚麼都還沒做呢!但是別一點成就感都沒有哦,因為我們用匯編所寫的是一個真正 Windows 程序,不信的話,查查您磁盤上的 msgbox.exe文件,在我的機器上它的大小足有1,536字節(jié)呢。

下面我們來做一點可以看的見摸的著的,我們在程序中加入一個對話框。該函數(shù)的原型如下:

MessageBox PROTO hwnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD 

hWnd 是父窗口的句柄。句柄代表您引用的窗口的一個地址指針。它的值對您編 Windows 程序并不重要(譯者注:如果您想成為高手則是必須的),您只要知道它代表一個窗口。當您要對窗口做任何操作時,必須要引用該窗口的指針。 
lpText 是指向您要顯示的文本的指針。指向文本串的指針事實上就是文本串的首地址。 
lpCaption 是指向您要顯示的對話框的標題文本串指針。 
uType 是顯示在對話框窗口上的小圖標的類型。 
下面是源程序

.386 
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib 

.data 
MsgBoxCaption  db "Iczelion Tutorial No.2",0 
MsgBoxText       db "Win32 Assembly is Great!",0 

.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK 
invoke ExitProcess, NULL 
end start 

編譯、鏈接上面的程序段,得到可執(zhí)行文件。運行,哈哈,窗口上彈出了一個對話框,上面有一行字:“Win32 Assembly is Great!”。想一想,我們是用匯編寫出來的,所以我們有理由為編寫了一個最簡單的 WIN32 程序感到高興。(譯者注:如果明天我們能夠像在 DOS 下那樣每一行都用匯編寫,那我們有理由為自己感到自豪。)

好,我們回過頭來看看上面的源代碼。我們在.DATA“分段”定義了兩個NULL結尾的字符串。我們用了兩個常量:NULL 和 MB_OK。這些常量在windows.inc 文件中有定義,使用常量使得您的程序有較好的可讀性。 addr 操作符用來把標號的地址傳遞給被調用的函數(shù),它只能用在 invoke 語句中,譬如您不能用它來把標號的地址賦給寄存器或變量,如果想這樣做則要用 offset 操作符。在 offset 和 addr 之間有如下區(qū)別:

addr不可以處理向前引用,offset則能。所謂向前引用是指:標號的定義是在invoke 語句之后,譬如在如下的例子:
invoke MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK

...... 

MsgBoxCaption db "Iczelion Tutorial No.2",0
MsgBoxText db "Win32 Assembly is Great!",0

如果您是用 addr 而不是 offset 的話,那 MASM 就會報錯。 
addr可以處理局部變量而 offset 則不能。局部變量只是在運行時在堆棧中分配內存空間。而 offset 則是在編譯時由編譯器解釋,這顯然不能用offset 在運行時來分配內存空間。編譯器對 addr 的處理是先檢查處理的是全局還是局部變量,若是全局變量則把其地址放到目標文件中,這一點和 offset 相同,若是局部變量,就在執(zhí)行 invoke 語句前產生如下指令序列: 
lea eax, LocalVar
push eax
因為lea指令能夠在運行時決定標號的有效地址,所以有了上述指令序列,就可以保證 invoke 的正確執(zhí)行了。 

--------------------------------------------------------------------------------


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲三级小视频| 久久久不卡网国产精品二区 | 亚洲欧美在线另类| 久久婷婷国产综合精品青草| 日韩三级高清在线| 日韩一区二区免费高清| 欧美一级理论片| 欧美sm美女调教| 久久精品这里都是精品| 国产丝袜美腿一区二区三区| 欧美mv和日韩mv的网站| 国产三级欧美三级| 中文字幕一区二区日韩精品绯色| 亚洲欧洲性图库| 亚洲已满18点击进入久久| 日韩黄色免费电影| 精品一区二区三区av| 国产精品18久久久久久vr| 欧美日韩欧美一区二区| 欧美日韩国产综合一区二区三区 | 日韩精品一区二区三区中文精品 | 成人黄色在线看| 91精品福利在线| 日韩精品专区在线影院观看| 久久久久国产精品免费免费搜索| 欧美激情一区二区在线| 亚洲午夜精品在线| 国产在线一区二区综合免费视频| 高潮精品一区videoshd| 在线观看日韩av先锋影音电影院| 日韩一区国产二区欧美三区| 亚洲国产精品国自产拍av| 亚洲一卡二卡三卡四卡五卡| 国产呦精品一区二区三区网站| av在线这里只有精品| 日韩欧美亚洲国产另类| 亚洲欧洲综合另类| 久久精品国产99国产| 色天使色偷偷av一区二区| 日韩视频不卡中文| 一区二区三区中文字幕在线观看| 男男视频亚洲欧美| 91看片淫黄大片一级| 欧美一区二区三区思思人| 18成人在线视频| 精品一区二区三区影院在线午夜 | 欧美精品久久99久久在免费线| 久久久久久亚洲综合影院红桃| 最新久久zyz资源站| 精品亚洲欧美一区| 欧美日韩精品一二三区| 一区二区三区不卡在线观看| 国产91清纯白嫩初高中在线观看| 欧美乱熟臀69xxxxxx| 国产精品大尺度| 岛国一区二区三区| 亚洲精品在线免费播放| 日本美女视频一区二区| 精品视频在线视频| 亚洲精品欧美在线| 91麻豆福利精品推荐| 国产午夜亚洲精品午夜鲁丝片 | 日韩视频在线观看一区二区| 亚洲美女少妇撒尿| 99精品视频在线免费观看| 国产三级精品三级| 成人毛片老司机大片| 久久精品人人做人人综合 | 国产人久久人人人人爽| 老鸭窝一区二区久久精品| 91精品国产色综合久久不卡蜜臀| 亚洲精品视频观看| 日本乱人伦aⅴ精品| 亚洲精品中文在线观看| av在线不卡网| 亚洲色图19p| 色哟哟亚洲精品| 亚洲精品你懂的| 欧美性生活久久| 亚洲成av人片在线| 91麻豆精品国产自产在线| 天天操天天干天天综合网| 欧美精品在线视频| 免费三级欧美电影| 337p日本欧洲亚洲大胆色噜噜| 国产在线不卡一区| 国产精品美女一区二区三区 | 亚洲第一成年网| 欧美二区三区的天堂| 精品一区二区免费在线观看| 国产亚洲欧美激情| 99热在这里有精品免费| 一区二区三区高清| 精品入口麻豆88视频| 处破女av一区二区| 亚洲一区二区精品视频| 欧美一卡2卡3卡4卡| 国产激情视频一区二区在线观看 | 亚洲国产精品天堂| 精品乱码亚洲一区二区不卡| 国产电影一区二区三区| 伊人婷婷欧美激情| 日韩欧美中文一区二区| 波多野结衣中文字幕一区二区三区 | 精品国产成人在线影院| 成人午夜免费视频| 一区av在线播放| 日韩免费看的电影| 一本大道综合伊人精品热热| 日韩中文字幕亚洲一区二区va在线 | 国产精品99久久久久久久vr| 亚洲男人的天堂网| 精品国产一区二区三区忘忧草| 成人a免费在线看| 日韩不卡手机在线v区| 国产日韩亚洲欧美综合| 91麻豆精品国产| 成人av影院在线| 久久电影网电视剧免费观看| 亚洲乱码国产乱码精品精的特点| 日韩一级欧美一级| 欧美午夜精品电影| 成人福利电影精品一区二区在线观看 | 中文成人综合网| 欧美一区二区三区免费| 91性感美女视频| 国产精品1区2区3区| 日韩av不卡在线观看| 亚洲免费高清视频在线| 欧美经典三级视频一区二区三区| 在线播放日韩导航| 在线观看国产精品网站| 国产成人亚洲综合a∨婷婷| 毛片av一区二区| 天天综合色天天| 亚洲成av人综合在线观看| 亚洲色图都市小说| 国产精品麻豆久久久| 国产欧美日韩在线视频| 久久精品亚洲一区二区三区浴池| 91精品国产欧美一区二区| 欧美亚洲综合色| 欧日韩精品视频| 欧美做爰猛烈大尺度电影无法无天| 国产suv精品一区二区6| 国产成人av电影在线| 国产精品一区二区在线播放 | 青青青伊人色综合久久| 偷拍日韩校园综合在线| 亚洲一区免费在线观看| 亚洲免费观看高清在线观看| 亚洲欧美日韩中文播放| 综合欧美亚洲日本| 中文字幕一区二区视频| 亚洲另类春色国产| 亚洲国产视频直播| 免费人成在线不卡| 精品一区二区久久久| 国精产品一区一区三区mba桃花| 蜜桃av一区二区三区电影| 精品在线一区二区三区| 国产乱人伦偷精品视频不卡| 高清国产一区二区三区| www.亚洲色图.com| 91麻豆国产精品久久| 欧美日韩一区中文字幕| 在线播放国产精品二区一二区四区 | 欧美不卡一区二区三区| 久久嫩草精品久久久精品一| 国产午夜精品一区二区三区四区| 国产嫩草影院久久久久| 国产精品国产成人国产三级| 亚洲精品一二三| 日本欧美一区二区| 国产伦精品一区二区三区免费迷| 国产成a人亚洲精品| 一本到不卡免费一区二区| 制服丝袜亚洲网站| 中文字幕欧美日本乱码一线二线| 最新不卡av在线| 日韩av一级电影| 成人动漫在线一区| 欧美日韩1234| 中文字幕欧美激情一区| 亚洲高清视频中文字幕| 国产一区二区精品久久| 在线观看不卡一区| 精品久久久久久久久久久久久久久 | 亚洲另类春色校园小说| 青青草国产精品97视觉盛宴| 国产精品一区2区| 欧美色网一区二区| 国产丝袜在线精品| 午夜精品久久久久久不卡8050| 久久99精品久久久久久| 欧美午夜精品久久久久久孕妇 | 成人午夜伦理影院| 在线电影院国产精品| ●精品国产综合乱码久久久久| 日韩和欧美一区二区三区|