版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第 9 章 32位指令及其編程,教學(xué)重點(diǎn),在16位8086指令系統(tǒng)基礎(chǔ)上,我們擴(kuò)展到32位80x86指令系統(tǒng)。重點(diǎn)掌握:32位編程環(huán)境32位尋址方式32位指令編程方法Windows應(yīng)用程序編程,IA-32結(jié)構(gòu)的指令系統(tǒng),整數(shù)指令集16位整數(shù)指令集32位整數(shù)指令集浮點(diǎn)指令集MMX指令集SSE指令集SSE2指令集SSE3指令集,主要指令集在16指令基礎(chǔ)上形成的32位整數(shù)指令集,6.1 32位指令的運(yùn)行環(huán)境,實(shí)
2、地址方式 保護(hù)方式 虛擬8086方式,16位邏輯段:段地址和偏移地址都是16位——段地址左移4位加偏移地址形成20位物理地址32位邏輯段:段地址和偏移地址都是32位——段地址加偏移地址形成32位線性地址,實(shí)地址方式,實(shí)方式(Real Mode)與8086/80186的工作方式以及80286的實(shí)地址方式具有相同的基本結(jié)構(gòu)32位x86 CPU只能尋址1MB物理存儲(chǔ)器空間,分段最大64KB,采用16位邏輯段32位x86 CPU可
3、以使用32位寄存器和32位操作數(shù),也可以采用32位尋址方式相當(dāng)于可以進(jìn)行32位處理的快速8086,保護(hù)方式,保護(hù)方式(Protected Mode)不僅具有段式存儲(chǔ)管理功能,還提供頁(yè)式存儲(chǔ)管理功能,可以更好地支持虛擬存儲(chǔ)器在保護(hù)方式下,32位x86 CPU才能發(fā)揮其全部功能,可以充分利用其強(qiáng)大的存儲(chǔ)管理和保護(hù)能力在保護(hù)方式下,32位x86 CPU可以使用全部32條地址線,使微處理器可尋址的物理存儲(chǔ)器達(dá)到4GB,采用32位邏輯段,其
4、段地址和偏移量都是32位,虛擬8086方式,虛擬8086方式(Virtual-8086 Mode)是一種在保護(hù)方式下運(yùn)行的類似實(shí)方式的工作環(huán)境虛擬8086方式下仍然采用16位邏輯段:段寄存器的使用與實(shí)方式一樣,左移4位加16位偏移量得到20位地址多個(gè)8086程序可以利用分頁(yè)機(jī)構(gòu)將各自的邏輯1MB空間映射到不同的物理地址,從而實(shí)現(xiàn)共存于主存并行運(yùn)行虛擬8086方式的程序在最低特權(quán)層3下運(yùn)行,6.1.1 寄存器組,8個(gè)32位通用寄存器
5、:EAX EBX ECX EDXESI EDI EBP ESP6個(gè)16位段寄存器:CS SS DS ES FS GS32位指令指針寄存器:EIP32位標(biāo)志寄存器:EFLAGS其他的32位系統(tǒng)用寄存器,在原有16位寄存器基礎(chǔ)上擴(kuò)展成為32位,6.1.2 尋址方式,32位有效地址=基址寄存器+(變址寄存器×比例)+位移量,基址寄存器——任何
6、8個(gè)32位通用寄存器之一變址寄存器——除ESP之外的任何32位通用寄存器之一比例——可以是1 / 2 / 4 / 8位移量——可以是8 / 32位值,32位尋址方式,⑴ mov eax, 44332211h⑵ mov eax, ebx⑶ mov eax, [1234h]⑷ mov eax, [ebx]⑸ mov eax, [ebx+80h]⑹ mov eax, [ebx+esi]⑺
7、 mov eax, [ebx+esi+80h]⑻ mov eax, [esi*2]⑼ mov eax, [ebx+esi*4]⑽ mov eax, [ebx+esi*8+80h],6.1.3 機(jī)器代碼格式,6.2 32位擴(kuò)展指令,16位指令系統(tǒng)從兩個(gè)方面向32位擴(kuò)展⑴ 支持32位操作數(shù)⑵ 支持32位尋址方式mov ax,bx;16位操作數(shù)mov eax,ebx;32位操作數(shù)mov ax,
8、[ebx];16位操作數(shù),32位尋址方式mov eax,[ebx];32位操作數(shù),32位尋址方式有些指令擴(kuò)大了工作范圍,或指令功能實(shí)現(xiàn)了向32位的自然增強(qiáng),將立即數(shù)壓入堆棧,PUSH i8/i16/i32;把16位或32位立即數(shù)i16/i32壓入堆棧。若是8位立即數(shù)i8,經(jīng)符號(hào)擴(kuò)展成16位后再壓入堆棧,push 1234h;壓入16位立即數(shù)push 87654321h;壓入16位立即數(shù)call helloabcad
9、d esp,6;平衡堆棧,通用寄存器全部進(jìn)出棧,PUSHA;順序?qū)X/CX/DX/BX/SP/BP/SI/DI壓入堆棧,POPA;順序從堆棧彈出DI/SI/BP/SP/BX/DX/CX/AX(與PUSHA相反);其中應(yīng)進(jìn)入SP的值被舍棄,并不進(jìn)入SP,SP通過增加16來恢復(fù),符號(hào)擴(kuò)展和零位擴(kuò)展,MOVSX r16,r8/m8;把r8/m8符號(hào)擴(kuò)展并傳送至r16MOVSX r32,r8/m8/r16/m16;把r8/m8/
10、r16/m16符號(hào)擴(kuò)展并傳送至r32MOVZX r16,r8/m8;把r8/m8零位擴(kuò)展并傳送至r16MOVZX r32,r8/m8/r16/m16;把r8/m8/r16/m16零位擴(kuò)展并傳送至r32,mov bl,92hmovsx ax,bl;ax=ff92hmovsx esi,bl;esi=ffffff92hmovzx edi,ax;edi=0000ff92h,串輸入/輸出,INS; I/O串輸入;存儲(chǔ)單元E
11、S:[(E)DI] ← I/O端口[DX];(E)DI←(E)DI±1/2/4,OUTS; I/O串輸出;I/O端口[DX] ← 存儲(chǔ)單元DS:[(E)SI];(E)SI←(E)SI±1/2/4,串指令能以雙字為傳送單位(±4) 在16位段,采用SI、DI、CX 在32位段,采用ESI、EDI、ECX,條件轉(zhuǎn)移,Jcc label;cc為真,轉(zhuǎn)移到label指定的段內(nèi)偏移地址處JECXZ
12、label;ECX=0,轉(zhuǎn)移到label指定的段內(nèi)偏移地址處LOOP/LOOPZ/LOOPNZ label;循環(huán)指令,32位段采用ECX作為計(jì)數(shù)器,例6.1,;將AX的每一位依次重復(fù)一次;所得的32位結(jié)果保存于EAX中mov ecx,16mov bx,axnext:shr ax,1rcr edx,1shr bx,1rcr edx,1loop nextmov eax,edx,例6
13、.2,;在16位段;把CX字節(jié)長(zhǎng)度的數(shù)據(jù)塊從DS∶SI源存儲(chǔ)區(qū);搬到ES∶DI目的存儲(chǔ)區(qū)ror ecx,2;cx的低2位移入了ecx的高2位rep movsd;每次傳送雙字rol ecx,1rep movsw;傳送可能余下的字rol ecx,1rep movsb;傳送可能余下的字節(jié),6.3 32位指令的程序設(shè)計(jì),指定匯編程序識(shí)別新指令處理16位段和32位段注意有些指令在16位邏輯段和32位邏
14、輯段的差別,DOS環(huán)境(實(shí)地址方式和虛擬8086方式),只能使用16位段 Windows 32位保護(hù)方式,可以使用32位段,例6.5-1/2,.model small.386;采用32位指令.stack.dataqvardq 1234567887654321h;數(shù)據(jù)定義.code.startupmov eax,dword ptr qvarmov edx,dword ptr qvar[4],例6.5-
15、2/2,mov ecx,8start1:shl eax,1rcl edx,1loop start1mov dword ptr qvar,eaxmov dword ptr qvar[4],edx.exit 0 end,例6.6-1/10,.model small.386;采用32位指令.stack.datacountequ 10darraydd 20,4500h,3f40h,-1,7f0
16、00080hdd 81000000h,0fffffff1hdd -45000011,12345678dd 87654321.code.startup,例6.6-2/10,xor esi,esimov si,offset darray;原序顯示mov ecx,countstart1:mov eax,[esi]call EAXdispadd esi,4dec ecxjz start2mo
17、v dl,’,’;用逗號(hào)分隔數(shù)據(jù)mov ah,2int 21hjmp start1,例6.6-3/10,start2:mov dl,0dh;回車和換行mov ah,2int 21hmov dl,0ahmov ah,2int 21hxor esi,esimov si,offset darray;排序mov ecx,countcall sorting,例6.6-4/10,xor esi
18、,esimov si,offset darray;降序顯示mov ecx,countstart3:mov eax,[esi]call EAXdispadd esi,4dec ecxjz start4mov dl,’,’mov ah,2int 21hjmp start3start4:.exit 0,例6.6-5/10,;32位有符號(hào)數(shù)據(jù)的排序子程序(降序);入口參數(shù):DS:ESI=緩沖區(qū)
19、首地址,ECX=個(gè)數(shù)sortingprocpush eaxpush edxdec ecxoutlp:mov edx,0inlp:cmp edx,ecx;內(nèi)循環(huán),使最高地址存儲(chǔ)單元具有最小數(shù)據(jù)jae short botmmov eax,[esi+edx*4+4]cmp [esi+edx*4],eax;比較前后兩個(gè)數(shù)據(jù)的大小,例6.6-6/10,jge short nswapxchg [esi+e
20、dx*4],eaxmov [esi+edx*4+4],eaxnswap:inc edxjmp inlpbotm:loop outlppop edxpop eaxretsortingendp,例6.6-7/10,;以十進(jìn)制形式顯示32位有符號(hào)數(shù)據(jù)的子程序;入口參數(shù):EAX=有符號(hào)數(shù)據(jù)EAXdispprocpush ebxpush edxtest eax,eax;判斷是零、正或負(fù)jnz
21、 eaxdisp0mov dl,’0’;為零,顯示“0”mov ah,2int 21hjmp eaxdisp4,例6.6-8/10,eaxdisp0:jns eaxdisp1neg eax;為負(fù)數(shù),求絕對(duì)值mov ebx,eaxmov dl,’-’;則顯示一個(gè)符號(hào)“-”mov ah,2int 21hmov eax,ebxeaxdisp1:mov ebx,10push bx;壓入1
22、0作為結(jié)束標(biāo)志eaxdisp2:cmp eax,0jz eaxdisp3;EAX=0(數(shù)據(jù)為0),則退出,例6.6-9/10,sub edx,edx;edx=0div ebx ;EDX.EAX÷EBX(10)add dl,30h;余數(shù)轉(zhuǎn)換為ASCII碼push dx;將除10得到的各位數(shù)依次壓入堆棧jmp eaxdisp2eaxdisp3:pop dx;將各位數(shù)依次出棧cmp
23、dl,10je eaxdisp4 ;是結(jié)束標(biāo)志(10),則退出,例6.6-10/10,mov ah,2;顯示int 21hjmp eaxdisp3eaxdisp4:pop edxpop ebxretEAXdispendpend,6.4.1 80386新增指令,80386的執(zhí)行單元可以實(shí)現(xiàn)快速移位操作,80386新增的指令主要就是有關(guān)位操作的80386還增加了條件設(shè)置指令,以及對(duì)控制、調(diào)試和測(cè)試寄存
24、器的傳送指令MASM 5.0開始支持80386指令系統(tǒng),位測(cè)試指令,BT dest,src;把目的操作數(shù)dest中由源操作數(shù)src指定的位送CF標(biāo)志BTC dest,src;把dest中由src指定的位送CF標(biāo)志,然后對(duì)那一位求反BTR dest,src;把dest中由src指定的位送CF標(biāo)志,然后對(duì)那一位復(fù)位BTS dest,src;把dest中由src指定的位送CF標(biāo)志,然后對(duì)那一位置位,mov eax,12345
25、678h;EAX=12345678hbt eax,5;EAX=12345678h,CF←1=EAX的D5位btc eax,10;EAX=12345278h,CF←1=EAX的D10位btr eax,20;EAX=12245278h,CF←1=EAX的D20位bts eax,34;EAX=1224527Ch,CF←0=EAX的D2位,條件設(shè)置指令,SETcc r8/m8;若條件cc成立,則r8/m8為1;否則,為0,
26、6.4.2 80486新增指令,80486的指令系統(tǒng)是在80386指令集的基礎(chǔ)上增加了6條新指令,新增的指令主要用于對(duì)多處理器系統(tǒng)和片上高速緩沖存儲(chǔ)器的支持為了讓匯編程序匯編這些指令,源程序中必須具有.486或.486P偽指令MASM 6.0開始支持80486指令系統(tǒng),字節(jié)交換指令,BSWAP r32 ;將32位通用寄存器值的第1和4字節(jié)、第2和3字節(jié)互換,mov eax,00112233h;EAX=00112233hbsw
27、ap eax;EAX=33221100h,交換加指令,XADD reg/mem, reg;reg/mem←→reg,reg/mem←reg+reg/mem,mov bl,12hmov dl,02hxadd bl,dl;BL=14h,DL=12h,比較交換指令,CMPXCHG reg/mem,reg;AL/AX/EAX-reg/mem;相等:ZF=1,reg/mem←reg;不等:ZF=0,AL/AX/EAX←reg/me
28、m,mov al,12hmov bl,12hmov dl,02hcmpxchg bl,dl;AL=12h,BL←DL=02h,ZF=1cmpxchg bl,dl;AL←BL=02h,DL=02h,ZF=0,6.4.3 Pentium新增指令,Pentium新增了幾條非常實(shí)用的特權(quán)指令源程序中必須具有.586或.586P偽指令MASM 6.11開始支持Pentium指令系統(tǒng)較低版本的匯編程序可以定義宏實(shí)現(xiàn):CPU_I
29、D MACRO;;CPUID指令的機(jī)器代碼DB 0FH,0A2H;;0F A2ENDM也可以直接在該指令處用:DB 0FH,0A2H,比較交換指令,CMPXCHG reg/mem,reg;AL/AX/EAX-reg/mem;相等:ZF=1,reg/mem←reg;不等:ZF=0,AL/AX/EAX←reg/mem,mov al,12hmov bl,12hmov dl,02hcmpxchg bl,dl;AL
30、=12h,BL←DL=02h,ZF=1cmpxchg bl,dl;AL←BL=02h,DL=02h,ZF=0,6.4.4 Pentium Pro新增指令,Pentium Pro指令系統(tǒng)新增3條實(shí)用的指令程序中必須具有.686或.686P偽指令MASM 6.12開始支持Pentium Pro指令,條件傳送指令,CMOVcc r16,r16/m16;若條件cc成立,則r16←r16/m16;否則,不傳送CMOVcc r32,r
31、32/m32;若條件cc成立,則r32←r32/m32;否則,不傳送,6.5 用匯編語言編寫32位Windows應(yīng)用程序,采用匯編語言可以編寫32位Windows應(yīng)用程序調(diào)用Windows的應(yīng)用程序接口API借助MASM32開發(fā)環(huán)境可以利用Windows的高級(jí)特性,生成的可執(zhí)行文件相對(duì)較小、性能更高從更深層次理解Windows運(yùn)行機(jī)制及程序設(shè)計(jì)思想介紹匯編語言編寫Win32程序的基本思想、框架結(jié)構(gòu)和開發(fā)環(huán)境,16位DOS與3
32、2位Windows-1,16位DOS操作系統(tǒng)工作于實(shí)地址方式DOS是單任務(wù)操作系統(tǒng),一個(gè)正在運(yùn)行的程序獨(dú)占了所有系統(tǒng)資源DOS系統(tǒng)只有一個(gè)特權(quán)級(jí)別,任何程序和操作系統(tǒng)都是同級(jí)的,32位Windows操作系統(tǒng)運(yùn)行于保護(hù)工作方式Windows是多任務(wù)操作系統(tǒng),系統(tǒng)資源由多個(gè)程序共享Windows系統(tǒng)存在兩個(gè)特權(quán)級(jí)別,操作系統(tǒng)運(yùn)行在最高級(jí)別0級(jí),應(yīng)用程序都運(yùn)行于最低級(jí)別3級(jí),16位DOS與32位Windows-2,DOS平臺(tái)下只有1
33、MB物理存儲(chǔ)空間必須分成不大于64KB的邏輯段,Windows平臺(tái)下直接使用32位地址尋址一個(gè)不分段的、達(dá)4GB的主存空間Windows應(yīng)用程序只有代碼段和數(shù)據(jù)段無須和段寄存器打交道,16位DOS與32位Windows-3,DOS操作系統(tǒng)為程序員提供中斷服務(wù)程序以中斷調(diào)用的方法進(jìn)行系統(tǒng)功能調(diào)用DOS中斷調(diào)用采用寄存器傳遞參數(shù),對(duì)程序員來說,操作系統(tǒng)由其提供的系統(tǒng)功能調(diào)用定義,Windows操作系統(tǒng)提供了動(dòng)態(tài)鏈接庫(kù)DDL利
34、用應(yīng)用程序接口API調(diào)用動(dòng)態(tài)鏈接庫(kù)中的函數(shù)Windows的API也曾被稱為軟件開發(fā)包SDK,16位和32位Windows的API分別被稱為Win16和Win32Windows應(yīng)用程序利用堆棧傳遞參數(shù),16位DOS與32位Windows-4,DOS下的程序以字符方式顯示給用戶程序需要用戶輸入時(shí),就停下來;用戶不輸入就不再執(zhí)行;而且,需要輸入一個(gè)數(shù)據(jù),用戶不能輸入另一個(gè)數(shù)據(jù)。,Windows程序采用圖形用戶界面它時(shí)刻等待用戶的操作。
35、用戶的每個(gè)操作都會(huì)形成消息(Message)傳遞給程序,程序則給予響應(yīng),6.5.2 32位Windows控制臺(tái)程序,Windows應(yīng)用程序開始運(yùn)行創(chuàng)建控制臺(tái)(Console)窗口或創(chuàng)建圖形界面窗口32位Windows控制臺(tái)程序像增強(qiáng)版的MS-DOS程序使用標(biāo)準(zhǔn)控制臺(tái):輸入設(shè)備(鍵盤)和輸出設(shè)備(顯示器)32位控制臺(tái)程序運(yùn)行在保護(hù)方式通過API使用Windows的動(dòng)態(tài)鏈接庫(kù)函數(shù),例6.11-1/4,.386.model
36、flat,stdcalloption casemap:noneIncludelibkernel32.libExitProcessproto,:DWORDGetStdHandleproto,:DWORDWriteConsoleAproto,:DWORD,:DWORD,:DWORD,:DWORD,:DWORDWriteConsoleequ ReadConsoleAproto,:DWORD,:DWORD,:DWOR
37、D,:DWORD,:DWORDReadConsoleequ STD_INPUT_HANDLE= -10STD_OUTPUT_HANDLE= -11,源程序格式,動(dòng)態(tài)鏈接庫(kù),例6.11-2/4,.dataouthandledd ?outbufferdb 'Welcome to the Win32 Console !',0dh,0ahdb 'Please enter your name:
38、9;,0dh,0ahoutbufsize= $-outbufferoutsizedd ?inhandledd ?inbufsize= 80inbufferdb inbufsize dup(?),0,0insizedd ?,例6.11-3/4,.codestart:;獲得輸出句柄invoke GetStdHandle,STD_OUTPUT_HANDLEmov outhandle,eax;顯示信息
39、invokeWriteConsole,outhandle,addr outbuffer,outbufsize,addr outsize,0,控制臺(tái)句柄,控制臺(tái)輸出,例6.11-4/4,;獲得輸入句柄invoke GetStdHandle,STD_INPUT_HANDLEmov inhandle,eax;等待用戶輸入invokeReadConsole,inhandle,addr inbuffer,inbuf
40、size,addr insize,0;退出invoke ExitProcess,0end start,程序退出,控制臺(tái)輸入,源程序格式,簡(jiǎn)化段定義格式含有.386等偽指令采用平展模式(Flat)API的參數(shù)傳遞采用標(biāo)準(zhǔn)調(diào)用方式(Stdcall),API函數(shù)區(qū)別大小寫使用庫(kù)文件包含偽指令I(lǐng)NCLUDELIB指明程序需要的API函數(shù)所在的庫(kù)文件使用過程聲明PROTO偽指令進(jìn)行函數(shù)聲明使用過程調(diào)用INVOKE偽指令調(diào)用
41、API函數(shù),動(dòng)態(tài)鏈接庫(kù),靜態(tài)鏈接:將子程序插入最終的可執(zhí)行代碼中動(dòng)態(tài)鏈接:程序運(yùn)行,才會(huì)將其加載到主存動(dòng)態(tài)鏈接庫(kù)是Windows操作系統(tǒng)的基礎(chǔ)kernel32.dll:主要處理內(nèi)存管理和進(jìn)程調(diào)度user32.dll:主要控制用戶界面gdi32.dll:負(fù)責(zé)圖形方面的操作動(dòng)態(tài)鏈接庫(kù)DLL文件對(duì)應(yīng)有導(dǎo)入庫(kù)文件連接程序把相關(guān)信息從導(dǎo)入庫(kù)文件中找出插入到可執(zhí)行文件中,程序退出,Windows使用ExitProcess函數(shù)實(shí)現(xiàn)在W
42、in32程序員參考手冊(cè)的定義:VOID ExitProcess( UINT uExitCode // exit code for all threads );匯編語言的聲明:ExitProcess PROTO ,:DWORD匯編語言的調(diào)用:invoke ExitProcess,0,控制臺(tái)句柄,控制臺(tái)函數(shù)要求將控制臺(tái)句柄作為第一個(gè)參數(shù)句柄是一個(gè)32位無符號(hào)整數(shù),確定一個(gè)對(duì)象標(biāo)準(zhǔn)輸出句柄STD_OUTP
43、UT_HANDLE (-11)標(biāo)準(zhǔn)輸入句柄STD_INPUT_HANDLE (-10)GetStdHandle函數(shù)獲取控制臺(tái)輸入或輸出的句柄實(shí)例匯編語言的聲明:GetStdHandleproto,nstdhandle:DWORD匯編語言的使用:invoke GetStdHandle,STD_OUTPUT_HANDLEmov outhandle,eax,控制臺(tái)輸出函數(shù),WriteConsole函數(shù)將一個(gè)字符串輸出到屏
44、幕上Win32 API中可以使用兩種字符集8位ASCII字符集,函數(shù)名以字母A結(jié)尾16位的Unicode字符集,函數(shù)名以字母W結(jié)尾匯編語言利用等價(jià)偽指令將函數(shù)名重新定義:WriteConsole equ WriteConsole函數(shù)在匯編語言中可以如下聲明:WriteConsoleA proto,handle:DWORD,;輸出句柄pBuffer:DWORD, ;輸出緩沖區(qū)指針bufsize:DW
45、ORD, ;輸出緩沖區(qū)大小pCount:DWORD, ;實(shí)際輸出字符數(shù)量的指針lpReserved:DWORD;保留(必須為0),控制臺(tái)輸入函數(shù),ReadConsole函數(shù)將鍵盤輸入的文本保存到一個(gè)緩沖區(qū)匯編語言中的聲明如下:ReadConsoleA proto,handle:DWORD,;輸入句柄pBuffer:DWORD, ;輸入緩沖區(qū)指針maxsize:DWORD, ;要讀取字符的最大數(shù)量
46、pBytesRead:DWORD, ;實(shí)際輸入字符數(shù)量指針notUsed:DWORD;未使用(例如0),匯編和連接,MASM匯編的命令:ML /c /coff /Fl /Zi lt611.asm參數(shù)“/coff”表示生成COFF格式的OBJ模塊文件需要32位增量式鏈接器文件,更名為L(zhǎng)INK32.EXE,連接命令:LINK32 /subsystem:console /debug lt611.obj參數(shù)“/su
47、bsystem:console”生成控制臺(tái)程序本程序使用了kernel32.lib庫(kù)文件,該文件也應(yīng)該復(fù)制到MASM目錄,6.5.3 MASM32開發(fā)環(huán)境,Steve Hutchesson的免費(fèi)軟件包( http://www.movsd.com/ )編輯器geditor.exeMASM 6.14匯編程序和鏈接程序相當(dāng)完整的Win32的包含文件、庫(kù)文件以及教程和示例等,一個(gè)最簡(jiǎn)單的Win32匯編語言程序顯示標(biāo)準(zhǔn)Windows消
48、息窗口的程序,6.5.4 創(chuàng)建消息窗口,例6.12-1/2,.386.model flat,stdcalloption casemap:noneIncludeinclude\windows.incIncludeinclude\kernel32.incIncludeinclude\user32.incIncludeliblib\kernel32.libIncludeliblib\user32.lib,例6.12
49、-2/2,.dataszCaptiondb 'Win32示例',0szText db '歡迎進(jìn)入32位Windows世界!',0.codestart:invoke MessageBox,NULL,\addr szText, addr szCaption,MB_OKinvoke ExitProcess,NULLend start,對(duì)比C++程序,C++調(diào)用API,#include
50、int API ENTRY WinMain(HINSTACE hInstance, HINSTACE hPrevInstance, LPSTR lpCmdLine,int nCmdshow){MessageBox(NULL,TEXT(“歡迎進(jìn)入32位Windows世界!”),TEXT(“Win32示例”),0);return 0;},MessageBox函數(shù),在Win32程序員參考手冊(cè)中的定義:int MessageBox(
51、 HWND hWnd,// handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType// style of message box );在user32.inc的聲明:M
52、essageBoxPROTO :DWORD,:DWORD,:DWORD,:DWORDMessageBox equ ,ExitProcess函數(shù),在Win32程序員參考手冊(cè)中的定義:VOID ExitProcess( UINT uExitCode// exit code for all threads );在user32.inc的聲明:ExitProcess PROTO :DWORD在windows
53、.inc 的定義:NULLequ 0MB_OKequ 0,6.5.5 創(chuàng)建窗口應(yīng)用程序,用匯編語言創(chuàng)建32位Windows應(yīng)用程序與用C++采用API開發(fā)沒有太大區(qū)別程序框架、用到的函數(shù)基本上一樣例6.13程序創(chuàng)建一個(gè)標(biāo)準(zhǔn)的Windows窗口程序包括標(biāo)題欄及客戶區(qū)能夠進(jìn)行標(biāo)準(zhǔn)的窗口操作例6.14程序點(diǎn)擊鼠標(biāo)左鍵彈出消息框,例6.13-1/6,.codestart:;調(diào)用主過程invoke GetMo
54、duleHandle,NULLmov hInstance,eax;獲得實(shí)例句柄,保存invoke GetCommandLinemov CommandLine,eax;獲得命令行參數(shù)地址指針,保存invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULTinvoke ExitProcess,eax,主過程WinMain,主過程WinMain,Win
55、Main函數(shù)的C++原型:int API ENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)大寫字符串表示參數(shù)類型,對(duì)應(yīng)雙字DWORD類型hInstance:當(dāng)前句柄,GetModuleHandle函數(shù)獲得hPrevInstance:前一個(gè)實(shí)例句柄,總是NULLlpCmdLine
56、:命令行參數(shù),GetCommandLine函數(shù)獲得nCmdShow:窗口的顯示方式,SW_SHOWDEFAULT(默認(rèn)窗口)WinMain返回是一個(gè)整型數(shù)值,包含在EAX寄存器,例6.13-2/6,;WinMain主過程WinMain prochInst:DWORD ,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORDLOCAL wc:WNDCLASSEX;定義窗口屬性的結(jié)構(gòu)變量
57、LOCAL msg:MSG;定義消息變量LOCAL hwnd:DWORD;定義窗口句柄變量,WinMain主要任務(wù),WinMain函數(shù)的主要任務(wù),初始化窗口類結(jié)構(gòu),對(duì)窗口類進(jìn)行注冊(cè); 創(chuàng)建窗口、顯示窗口,并更新窗口;進(jìn)入消息循環(huán),也就是不停地檢測(cè)有無消息,并把它發(fā)送給窗口進(jìn)程去處理。如果是退出消息,則返回WinMain函數(shù)首先用LOCAL偽指令定義了WNDCLASSEX結(jié)構(gòu)的局部變量wc,然后給結(jié)構(gòu)成員進(jìn)行賦值,例6.
58、13-3/6,;初始化窗口類變量mov wc.cbSize,SIZEOF WNDCLASSEXmov wc.style,CS_HREDRAW or CS_VREDRAWmov wc.lpfnWndProc,OFFSET WndProcmov wc.cbClsExtra,NULLmov wc.cbWndExtra,NULLpush hInstancepop wc.hInstance
59、mov wc.hbrBackground,COLOR_WINDOW+1mov wc.lpszMenuName,NULLmov wc.lpszClassName,OFFSET ClassNameinvoke LoadIcon,NULL,IDI_APPLICATIONmov wc.hIcon,eaxmov wc.hIconSm,eaxinvoke LoadCursor,NULL,IDC_ARROW
60、mov wc.hCursor,eaxinvoke RegisterClassEx, addr wc;注冊(cè)窗口類,窗口類,窗口類,cbSize:指定該結(jié)構(gòu)的大小style:窗口類風(fēng)格lpfnWndProc:處理窗口消息的窗口過程的地址指針cbClsExtra:分配給窗口類結(jié)構(gòu)之后的額外字節(jié)數(shù)cbWndExtra:分配給窗口實(shí)例之后的額外字節(jié)數(shù)hInstance:當(dāng)前應(yīng)用程序的句柄實(shí)例hIcon:窗口類
61、的圖標(biāo),使用LoadIcon函數(shù)獲得hCursor:窗口類的光標(biāo),使用LoadCursor函數(shù)獲得hbrBackground:窗口類的背景顏色lpszMenuName:菜單的句柄lpszClassName:窗口類名稱hIconSm:圖標(biāo)的句柄,例6.13-4/6,INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,C
62、W_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULLmov hwnd,eax;創(chuàng)建窗口invoke ShowWindow,hwnd,SW_SHOWNORMAL;顯示窗口invoke UpdateWindow,hwnd;更新窗口,CreateWindowEx函數(shù),CreateWindowEx函數(shù),HWND Crea
63、teWindowEx(DWORD dwExStyle,// 窗口的擴(kuò)展風(fēng)格LPCTSTR lpClassName,// 指向注冊(cè)的窗口類名稱LPCTSTR lpWindowName,// 指向窗口程序名稱DWORD dwStyle,// 窗口風(fēng)格int x,// 窗口水平位置int y,// 窗口垂直位置int nWidth,// 窗口寬度int nHeight,// 窗口高度HWND
64、 hWndParent,// 父窗口句柄HMENU hMenu,// 菜單句柄,或子窗口標(biāo)識(shí)符HINSTANCE hInstance,// 應(yīng)用程序?qū)嵗浔鶯PVOID lpParam // 指向窗口數(shù)據(jù) );,例6.13-5/6,.WHILE TRUE;消息循環(huán)invoke GetMessage, ADDR msg,NULL,0,0;獲得消息.BREAK .IF (!eax);.WHILE T
65、RUE形成無條件循環(huán);此處當(dāng)EAX等于0則跳出循環(huán)invoke TranslateMessage,ADDR msg;翻譯消息invoke DispatchMessage,ADDR msg;分派消息.ENDWmov eax,msg.wParamretWinMain endp,消息循環(huán),消息循環(huán),每個(gè)Windows程序維持一個(gè)消息隊(duì)列當(dāng)一個(gè)輸入事件發(fā)生時(shí),Windows操作系統(tǒng)翻譯該事件成為一個(gè)消息,并
66、放置于消息隊(duì)列中例題程序使用WHILE循環(huán)結(jié)構(gòu)形成消息循環(huán)消息循環(huán)開始,GetMessage函數(shù)從消息隊(duì)列檢索一個(gè)消息使用TranslateMessage函數(shù)將虛擬鍵消息翻譯成字符消息,并放回到應(yīng)用程序的消息隊(duì)列利用DispatchMessage函數(shù)將消息分派給窗口過程,也就是在注冊(cè)窗口時(shí)的WndProc過程,例6.13-6/6,WndProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,l
67、Param:DWORD.IF uMsg==WM_DESTROYinvoke PostQuitMessage,NULL;處理關(guān)閉程序的消息.ELSE;不處理的消息由系統(tǒng)默認(rèn)操作invoke DefWindowProc,hWnd,uMsg,wParam,lParamret.ENDIFxor eax,eaxretWndProcendp,窗口過程,窗口過程,窗口過程決定了在客戶區(qū)的顯示內(nèi)容,以及程
68、序如何響應(yīng)用戶輸入窗口過程根據(jù)參數(shù)uMsg得到消息,轉(zhuǎn)到不同的分支去處理窗口過程處理的消息,返回時(shí)要在EAX中賦值0處理WM_DESTROY消息:調(diào)用PostQuitMessage函數(shù),向消息隊(duì)列發(fā)送WM_QUIT消息,并返回不處理的消息,調(diào)用DefWindowProc函數(shù),例6.14,;彈出消息的窗口應(yīng)用程序;數(shù)據(jù)段增加一個(gè)字符串:szTextdb '歡迎進(jìn)入32位Windows世界!',0;窗口過
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 51指令
- 輻射4指令
- mcs-51指令
- 8051指令表
- 3指令系統(tǒng)
- 一種兼容MIPS32指令集的32位軟核處理器設(shè)計(jì).pdf
- 蓋世3指令集合
- 個(gè)人整理的80387指令
- 兼容51指令的8位MCU IP CORE開發(fā).pdf
- 數(shù)控車g71_g70指令的編程加工實(shí)例
- mcs-51指令系統(tǒng)
- mcs-51指令集
- 數(shù)控車g71,g70指令的編程加工實(shí)例
- 基于ARMv4指令集的32位RISC微控制器的設(shè)計(jì)與實(shí)現(xiàn).pdf
- PLC9指令表.dwg
- PLC10指令表.dwg
- PLC9指令表.dwg
- PLC11指令表.dwg
- PLC11指令表.dwg
- PLC9指令表.dwg
評(píng)論
0/150
提交評(píng)論