收藏 分享(赏)

汇编语言0668301.ppt

上传人:dreamzhangning 文档编号:3316180 上传时间:2018-10-12 格式:PPT 页数:81 大小:802KB
下载 相关 举报
汇编语言0668301.ppt_第1页
第1页 / 共81页
汇编语言0668301.ppt_第2页
第2页 / 共81页
汇编语言0668301.ppt_第3页
第3页 / 共81页
汇编语言0668301.ppt_第4页
第4页 / 共81页
汇编语言0668301.ppt_第5页
第5页 / 共81页
点击查看更多>>
资源描述

1、第 6 章,教学重点,在16位8086指令系统基础上,我们扩展到32位80x86指令系统。重点掌握: 32位编程环境 32位寻址方式 32位指令编程方法 Windows应用程序编程,IA-32结构的指令系统,整数指令集 16位整数指令集 32位整数指令集 浮点指令集 MMX指令集 SSE指令集 SSE2指令集 SSE3指令集,主要指令集 在16指令基础上形成的 32位整数指令集,6.1 32位指令的运行环境,实地址方式保护方式虚拟8086方式,16位逻辑段:段地址和偏移地址都是16位 段地址左移4位加偏移地址形成20位物理地址 32位逻辑段:段地址和偏移地址都是32位 段地址加偏移地址形成32

2、位线性地址,实地址方式,实方式(Real Mode)与8086/80186的工作方式以及80286的实地址方式具有相同的基本结构 32位x86 CPU只能寻址1MB物理存储器空间,分段最大64KB,采用16位逻辑段 32位x86 CPU可以使用32位寄存器和32位操作数,也可以采用32位寻址方式 相当于可以进行32位处理的快速8086,保护方式,保护方式(Protected Mode)不仅具有段式存储管理功能,还提供页式存储管理功能,可以更好地支持虚拟存储器 在保护方式下,32位x86 CPU才能发挥其全部功能,可以充分利用其强大的存储管理和保护能力 在保护方式下,32位x86 CPU可以使用

3、全部32条地址线,使微处理器可寻址的物理存储器达到4GB,采用32位逻辑段,其段地址和偏移量都是32位,虚拟8086方式,虚拟8086方式(Virtual-8086 Mode)是一种在保护方式下运行的类似实方式的工作环境 虚拟8086方式下仍然采用16位逻辑段:段寄存器的使用与实方式一样,左移4位加16位偏移量得到20位地址 多个8086程序可以利用分页机构将各自的逻辑1MB空间映射到不同的物理地址,从而实现共存于主存并行运行 虚拟8086方式的程序在最低特权层3下运行,6.1.1 寄存器组,8个32位通用寄存器: EAX EBX ECX EDX ESI EDI EBP ESP 6个16位段寄

4、存器: CS SS DS ES FS GS 32位指令指针寄存器:EIP 32位标志寄存器:EFLAGS 其他的32位系统用寄存器,在原有16位寄存器 基础上扩展成为32位,6.1.2 寻址方式,32位有效地址 基址寄存器(变址寄存器比例)位移量,基址寄存器任何8个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, eb

5、x+esi mov eax, ebx+esi+80h mov eax, esi*2 mov eax, ebx+esi*4 mov eax, ebx+esi*8+80h,6.1.3 机器代码格式,6.2 32位扩展指令,16位指令系统从两个方面向32位扩展 支持32位操作数 支持32位寻址方式mov ax,bx ;16位操作数mov eax,ebx ;32位操作数mov ax,ebx ;16位操作数,32位寻址方式mov eax,ebx ;32位操作数,32位寻址方式 有些指令扩大了工作范围,或指令功能实现了向32位的自然增强,将立即数压入堆栈,PUSH i8/i16/i32 ;把16位或32位

6、立即数i16/i32压入堆栈。若是8位立即数i8,经符号扩展成16位后再压入堆栈,push word ptr 1234h ;压入16位立即数 push dword ptr 87654321h ;压入32位立即数 call helloabc add esp,6 ;平衡堆栈,通用寄存器全部进出栈,PUSHA ;顺序将AX/CX/DX/BX/SP/BP/SI/DI压入堆栈,POPA ;顺序从堆栈弹出DI/SI/BP/SP/BX/DX/CX/AX(与PUSHA相反) ;其中应进入SP的值被舍弃,并不进入SP,SP通过增加16来恢复,符号扩展和零位扩展,MOVSX r16,r8/m8 ;把r8/m8符号

7、扩展并传送至r16 MOVSX r32,r8/m8/r16/m16 ;把r8/m8/r16/m16符号扩展并传送至r32 MOVZX r16,r8/m8 ;把r8/m8零位扩展并传送至r16 MOVZX r32,r8/m8/r16/m16 ;把r8/m8/r16/m16零位扩展并传送至r32,mov bl,92h movsx ax,bl ;ax=ff92h movsx esi,bl ;esi=ffffff92h movzx edi,ax ;edi=0000ff92h,串输入/输出,INS ; I/O串输入 ;存储单元ES:(E)DI I/O端口DX ;(E)DI(E)DI1/2/4,OUTS

8、; I/O串输出 ;I/O端口DX 存储单元DS:(E)SI ;(E)SI(E)SI1/2/4,串指令能以双字为传送单位(4)在16位段,采用SI、DI、CX在32位段,采用ESI、EDI、ECX,条件转移,Jcc label ;cc为真,转移到label指定的段内偏移地址处JECXZ label ;ECX=0,转移到label指定的段内偏移地址处LOOP/LOOPZ/LOOPNZ label ;循环指令,32位段采用ECX作为计数器,;将AX的每一位依次重复一次;所得的32位结果保存于EAX中mov ecx,16mov bx,ax next: shr ax,1rcr edx,1shr bx,

9、1rcr edx,1loop nextmov eax,edx,例6.1,;利用双字串传送MOVSD指令提高字符串复制效率mov edx,ecx ;字符串长度,转存EDXshr ecx,2 ;长度除以4rep movsd ;以双字为单位重复传送mov ecx,edx and ecx,11b ;求出剩余的字符串长度rep movsb ;以字节为单位传送剩余字符,例6.2,6.3 DOS下的32位程序设计,指定汇编程序识别新指令 处理16位段和32位段 注意有些指令在16位逻辑段和32位逻辑段的差别,DOS环境(实地址方式和虚拟8086方式),只能使用16位段Windows 32位保护方式,可以使用

10、32位段,例6.51/2,.model small.386 ;采用32位指令.stack.data qvar dq 1234567887654321h ;数据定义.code.startupmov eax,dword ptr qvarmov edx,dword ptr qvar4,例6.52/2,mov ecx,8 start1: shl eax,1rcl edx,1loop start1mov dword ptr qvar,eaxmov dword ptr qvar4,edx.exit 0end,例6.61/10,.model small.386 ;采用32位指令.stack.data cou

11、nt equ 10 darray dd 20,4500h,3f40h,-1,7f000080hdd 81000000h,0fffffff1hdd -45000011,12345678dd 87654321.code.startup,例6.62/10,xor esi,esimov si,offset darray ;原序显示mov ecx,count start1: mov eax,esicall EAXdispadd esi,4dec ecxjz start2mov dl, ;用逗号分隔数据mov ah,2int 21hjmp start1,例6.63/10,start2: mov dl,0d

12、h ;回车和换行mov ah,2int 21hmov dl,0ahmov ah,2int 21hxor esi,esimov si,offset darray ;排序mov ecx,countcall sorting,例6.64/10,xor esi,esimov si,offset darray ;降序显示mov ecx,count start3: mov eax,esicall EAXdispadd esi,4dec ecxjz start4mov dl,mov ah,2int 21hjmp start3 start4: .exit 0,例6.65/10,;32位有符号数据的排序子程序(降

13、序) ;入口参数:DS:ESI=缓冲区首地址,ECX=个数 sorting procpush eaxpush edxdec ecx outlp: mov edx,0 inlp: cmp edx,ecx ;内循环,使最高地址存储单元具有最小数据jae short botmmov eax,esi+edx*4+4cmp esi+edx*4,eax ;比较前后两个数据的大小,例6.66/10,jge short nswapxchg esi+edx*4,eaxmov esi+edx*4+4,eax nswap: inc edxjmp inlp botm: loop outlppop edxpop eax

14、ret sorting endp,例6.67/10,;以十进制形式显示32位有符号数据的子程序 ;入口参数:EAX=有符号数据 EAXdisp procpush ebxpush edxtest eax,eax ;判断是零、正或负jnz eaxdisp0mov dl,0 ;为零,显示“0”mov ah,2int 21hjmp eaxdisp4,例6.68/10,eaxdisp0: jns eaxdisp1neg eax ;为负数,求绝对值mov ebx,eaxmov dl,- ;则显示一个符号“-”mov ah,2int 21hmov eax,ebx eaxdisp1: mov ebx,10pu

15、sh bx ;压入10作为结束标志 eaxdisp2: cmp eax,0jz eaxdisp3;EAX=0(数据为0),则退出,例6.69/10,sub edx,edx ;edx=0div ebx ;EDX.EAXEBX(10)add dl,30h ;余数转换为ASCII码push dx ;将除10得到的各位数依次压入堆栈jmp eaxdisp2 eaxdisp3: pop dx ;将各位数依次出栈cmp dl,10je eaxdisp4;是结束标志(10),则退出,例6.610/10,mov ah,2 ;显示int 21hjmp eaxdisp3 eaxdisp4: pop edxpop

16、ebxret EAXdisp endpend,6.4.1 80386新增指令,80386的执行单元可以实现快速移位操作,80386新增的指令主要就是有关位操作的 80386还增加了条件设置指令,以及对控制、调试和测试寄存器的传送指令 MASM 5.0开始支持80386指令系统,位测试指令,BT dest,src ;把目的操作数dest中由源操作数src指定的位送CF标志 BTC dest,src ;把dest中由src指定的位送CF标志,然后对那一位求反 BTR dest,src ;把dest中由src指定的位送CF标志,然后对那一位复位 BTS dest,src ;把dest中由src指定的

17、位送CF标志,然后对那一位置位,mov eax,12345678h ;EAX=12345678h bt eax,5 ;EAX=12345678h,CF1=EAX的D5位 btc eax,10 ;EAX=12345278h,CF1=EAX的D10位 btr eax,20 ;EAX=12245278h,CF1=EAX的D20位 bts eax,34 ;EAX=1224527Ch,CF0=EAX的D2位,条件设置指令,SETcc r8/m8;若条件cc成立,则r8/m8为1;否则,为0,6.4.2 80486新增指令,80486的指令系统是在80386指令集的基础上增加了6条新指令,新增的指令主要用

18、于对多处理器系统和片上高速缓冲存储器的支持 为了让汇编程序汇编这些指令,源程序中必须具有.486或.486P伪指令 MASM 6.0开始支持80486指令系统,字节交换指令,BSWAP r32 ;将32位通用寄存器值的第1和4字节、第2和3字节互换,mov eax,00112233h ;EAX=00112233h bswap eax ;EAX=33221100h,交换加指令,XADD reg/mem, reg ;reg/memreg,reg/memreg+reg/mem,mov bl,12h mov dl,02h xadd bl,dl ;BL=14h,DL=12h,比较交换指令,CMPXCHG

19、 reg/mem,reg ;AL/AX/EAXreg/mem ;相等:ZF=1,reg/memreg ;不等:ZF=0,AL/AX/EAXreg/mem,mov al,12h mov bl,12h mov dl,02h cmpxchg bl,dl ;AL=12h,BLDL=02h,ZF=1 cmpxchg bl,dl ;ALBL=02h,DL=02h,ZF=0,6.4.3 Pentium新增指令,Pentium新增了几条非常实用的特权指令 源程序中必须具有.586或.586P伪指令 MASM 6.11开始支持Pentium指令系统 较低版本的汇编程序可以定义宏实现: CPU_ID MACRO

20、;CPUID指令的机器代码DB 0FH,0A2H ;0F A2ENDM 也可以直接在该指令处用:DB 0FH,0A2H,8字节比较交换指令,CMPXCHG8B m64 ;EDX.EAXm64 ;相等:ZF=1,m64ECX.EBX ;不等:ZF=0,EDX.EAXm64,cmpxchg8b qword ptr si,6.4.4 Pentium Pro新增指令,Pentium Pro指令系统新增3条实用的指令 程序中必须具有.686或.686P伪指令 MASM 6.12开始支持Pentium Pro指令,条件传送指令,CMOVcc r16,r16/m16 ;若条件cc成立,则r16r16/m16

21、;否则,不传送 CMOVcc r32,r32/m32 ;若条件cc成立,则r32r32/m32;否则,不传送,6.5 用汇编语言编写32位Windows应用程序,采用汇编语言可以编写32位Windows应用程序 调用Windows的应用程序接口API 借助MASM32开发环境 可以利用Windows的高级特性,生成的可执行文件相对较小、性能更高 从更深层次理解Windows运行机制及程序设计思想 介绍汇编语言编写Win32程序的基本思想、框架结构和开发环境,16位DOS与32位Windows1,16位DOS操作系统工作于实地址方式 DOS是单任务操作系统,一个正在运行的程序独占了所有系统资源

22、DOS系统只有一个特权级别,任何程序和操作系统都是同级的,32位Windows操作系统运行于保护工作方式 Windows是多任务操作系统,系统资源由多个程序共享 Windows系统存在两个特权级别,操作系统运行在最高级别0级,应用程序都运行于最低级别3级,16位DOS与32位Windows2,DOS平台下 只有1MB物理存储空间 必须分成不大于64KB的逻辑段,Windows平台下 直接使用32位地址寻址一个不分段的、达4GB的主存空间 Windows应用程序只有代码段和数据段 无须和段寄存器打交道,16位DOS与32位Windows3,对程序员来说, 操作系统由其提供的系统功能调用定义,DO

23、S操作系统为程序员提供中断服务程序 以中断调用的方法进行系统功能调用 DOS中断调用采用寄存器传递参数,Windows操作系统提供了动态链接库DDL 利用应用程序接口API调用动态链接库中的函数 Windows的API也曾被称为软件开发包SDK,16位和32位Windows的API分别被称为Win16和Win32 Windows应用程序利用堆栈传递参数,16位DOS与32位Windows4,DOS下的程序以字符方式显示给用户 程序需要用户输入时,就停下来;用户不输入就不再执行;而且,需要输入一个数据,用户不能输入另一个数据。,Windows程序采用图形用户界面 它时刻等待用户的操作。用户的每个

24、操作都会形成消息(Message)传递给程序,程序则给予响应,6.5.2 32位Windows控制台程序,Windows应用程序开始运行 创建控制台(Console)窗口 或创建图形界面窗口 32位Windows控制台程序 像增强版的MS-DOS程序 使用标准控制台:输入设备(键盘)和输出设备(显示器) 32位控制台程序运行在保护方式 通过API使用Windows的动态链接库函数,.386.model flat,stdcalloption casemap:none includelib bin32kernel32.lib ExitProcess proto,:DWORD GetStdHandl

25、e proto,:DWORD WriteConsoleA proto,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD WriteConsole equ ReadConsoleA proto,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD ReadConsole equ STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11,例6.111/4,源程序格式,动态链接库,.data outhandle dd ? outbuffer db Welcome to the Win32 Console !,0dh,0ahdb

26、Please enter your name:,0dh,0ah outbufsize = $-outbuffer outsize dd ? inhandle dd ? inbufsize = 80 inbuffer db inbufsize dup(?),0,0 insize dd ?,例6.112/4,.code start:;获得输出句柄invoke GetStdHandle,STD_OUTPUT_HANDLEmov outhandle,eax;显示信息invoke WriteConsole,outhandle, addr outbuffer,outbufsize, addr outsiz

27、e,0,例6.113/4,控制台句柄,控制台输出,;获得输入句柄invokeGetStdHandle,STD_INPUT_HANDLEmov inhandle,eax;等待用户输入invoke ReadConsole,inhandle, addr inbuffer,inbufsize,addr insize,0;退出invoke ExitProcess,0end start,例6.114/4,程序退出,控制台输入,源程序格式,简化段定义格式 含有.386等伪指令 采用平展模式(Flat) API的参数传递采用标准调用方式(Stdcall),API函数区别大小写 使用库文件包含伪指令INCLUD

28、ELIB指明程序需要的API函数所在的库文件 使用过程声明PROTO伪指令进行函数声明 使用过程调用INVOKE伪指令调用API函数,动态链接库,静态链接:将子程序插入最终的可执行代码中 动态链接:程序运行,才会将其加载到主存 动态链接库是Windows操作系统的基础 kernel32.dll:主要处理内存管理和进程调度 user32.dll:主要控制用户界面 gdi32.dll:负责图形方面的操作 动态链接库DLL文件对应有导入库文件 连接程序把相关信息从导入库文件中找出插入到可执行文件中,程序退出,Windows使用ExitProcess函数实现 在Win32程序员参考手册的定义:VOID

29、 ExitProcess(UINT uExitCode / exit code for all threads ); 汇编语言的声明:ExitProcess PROTO ,:DWORD 汇编语言的调用:invoke ExitProcess,0,控制台句柄,控制台函数要求将控制台句柄作为第一个参数 句柄是一个32位无符号整数,确定一个对象 标准输出句柄STD_OUTPUT_HANDLE (-11) 标准输入句柄STD_INPUT_HANDLE (-10) GetStdHandle函数获取控制台输入或输出的句柄实例 汇编语言的声明:GetStdHandle proto,nstdhandle:DWO

30、RD 汇编语言的使用:invoke GetStdHandle,STD_OUTPUT_HANDLEmov outhandle,eax,控制台输出函数,WriteConsole函数将一个字符串输出到屏幕上 Win32 API中可以使用两种字符集 8位ASCII字符集,函数名以字母A结尾 16位的Unicode字符集,函数名以字母W结尾 汇编语言利用等价伪指令将函数名重新定义: WriteConsole equ WriteConsole函数在汇编语言中可以如下声明: WriteConsoleA proto,handle:DWORD, ;输出句柄pBuffer:DWORD, ;输出缓冲区指针bufsi

31、ze:DWORD, ;输出缓冲区大小pCount:DWORD, ;实际输出字符数量的指针lpReserved:DWORD ;保留(必须为0),控制台输入函数,ReadConsole函数将键盘输入的文本保存到一个缓冲区 汇编语言中的声明如下: ReadConsoleA proto,handle:DWORD, ;输入句柄pBuffer:DWORD, ;输入缓冲区指针maxsize:DWORD, ;要读取字符的最大数量pBytesRead:DWORD, ;实际输入字符数量指针notUsed:DWORD ;未使用(例如0),6.5.3 Windows应用程序的开发,1. 进入MASM开发环境 快捷方法

32、:在资源管理器下双击WIN.BAT 2. 源程序的汇编ML /c /coff /Fl /Zi lt611.asm参数“/coff”表示生成COFF格式的OBJ模块文件 3. 目标代码的连接 需要32位增量式链接器文件(假设在BIN32目录) BIN32LINK /subsystem:console /debug lt611.obj 参数“/subsystem:console”生成控制台程序 参数“/subsystem:windows”生成图形窗口程序,一个最简单的Win32汇编语言程序,6.5.4 创建消息窗口,例6.121/2,.386.model flat,stdcalloption ca

33、semap:none includelib bin32kernel32.lib includelib bin32user32.lib ExitProcess proto,:dword MessageBoxA proto :dword,:dword,:dword,:dword MessageBox equ NULL equ 0 MB_OK equ 0,.data szCaption db Win32示例,0 szText db 欢迎进入32位Windows世界!,0.code start: invoke MessageBox,NULL, addr szText, addr szCaption,M

34、B_OKinvoke ExitProcess,NULLend start,例6.122/2,对比C+程序,#include int API ENTRY WinMain(HINSTACE hInstance, HINSTACE hPrevInstance, LPSTR lpCmdLine,int nCmdshow) MessageBox(NULL,TEXT(“欢迎进入32位Windows世界!”),TEXT(“Win32示例”),0); return 0; ,C+调用API,MessageBox函数,在Win32程序员参考手册中的定义: int MessageBox(HWND hWnd, / h

35、andle of owner windowLPCTSTR lpText, / address of text in message boxLPCTSTR lpCaption, / address of title of message box UINT uType / style of message box); 用MASM汇编语言声明:MessageBoxPROTO :DWORD,:DWORD,:DWORD,:DWORDMessageBox equ ,ExitProcess函数,在Win32程序员参考手册中的定义: VOID ExitProcess(UINT uExitCode / exit

36、 code for all threads ); 用MASM汇编语言声明:ExitProcess PROTO :DWORD 用MASM汇编语言定义:NULL equ 0MB_OK equ 0,6.5.5 创建窗口应用程序,用汇编语言创建32位Windows应用程序 与用C+采用API开发没有太大区别 程序框架、用到的函数基本上一样 例6.13程序 创建一个标准的Windows窗口程序 包括标题栏及客户区 能够进行标准的窗口操作 例6.14程序 点击鼠标左键 弹出消息框,MASM32开发环境,Steve Hutchesson的免费软件包 ( http:/ ) 编辑器geditor.exe MAS

37、M 6.14汇编程序和链接程序 相当完整的Win32的包含文件、库文件以及教程和示例等,.code start: ;调用主过程invoke GetModuleHandle,NULLmov hInstance,eax;获得实例句柄,保存invoke GetCommandLinemov CommandLine,eax;获得命令行参数地址指针,保存invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULTinvoke ExitProcess,eax,例6.131/6,主过程WinMain,主过程WinMain,WinMain函数的C+原型:i

38、nt API ENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) 大写字符串表示参数类型,对应双字DWORD类型 hInstance:当前句柄,GetModuleHandle函数获得 hPrevInstance:前一个实例句柄,总是NULL lpCmdLine:命令行参数,GetCommandLine函数获得 nCmdShow:窗口的显示方式,SW_SHOWDEFAULT(默认窗口) WinMain返回是一个整型数值,包含在EAX寄存器,;WinMain主过程 WinMa

39、in proc hInst:DWORD ,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORDLOCAL wc:WNDCLASSEX ;定义窗口属性的结构变量LOCAL msg:MSG;定义消息变量LOCAL hwnd:DWORD;定义窗口句柄变量,例6.132/6,WinMain主要任务,WinMain函数的主要任务,初始化窗口类结构,对窗口类进行注册; 创建窗口、显示窗口,并更新窗口; 进入消息循环,也就是不停地检测有无消息,并把它发送给窗口进程去处理。如果是退出消息,则返回 WinMain函数首先用LOCAL伪指令定义了WNDCLASSEX结构的局部变量

40、wc,然后给结构成员进行赋值,;初始化窗口类变量mov wc.cbSize,SIZEOF WNDCLASSEXmov wc.style,CS_HREDRAW or CS_VREDRAWmov wc.lpfnWndProc,OFFSET WndProcmov wc.cbClsExtra,NULLmov wc.cbWndExtra,NULLpush hInstancepop wc.hInstancemov wc.hbrBackground,COLOR_WINDOW+1mov wc.lpszMenuName,NULLmov wc.lpszClassName,OFFSET ClassNameinvok

41、e LoadIcon,NULL,IDI_APPLICATIONmov wc.hIcon,eaxmov wc.hIconSm,eaxinvoke LoadCursor,NULL,IDC_ARROWmov wc.hCursor,eaxinvoke RegisterClassEx, addr wc ;注册窗口类,例6.133/6,窗口类,窗口类,cbSize:指定该结构的大小style:窗口类风格lpfnWndProc:处理窗口消息的窗口过程的地址指针cbClsExtra:分配给窗口类结构之后的额外字节数cbWndExtra:分配给窗口实例之后的额外字节数hInstance:当前应用程序的句柄实例h

42、Icon:窗口类的图标,使用LoadIcon函数获得hCursor:窗口类的光标,使用LoadCursor函数获得hbrBackground:窗口类的背景颜色lpszMenuName:菜单的句柄lpszClassName:窗口类名称hIconSm:图标的句柄,INVOKE CreateWindowEx, NULL,ADDR ClassName,ADDR AppName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInst,NULLmov hwnd,eax ;创

43、建窗口invoke ShowWindow, hwnd,SW_SHOWNORMAL ;显示窗口invoke UpdateWindow,hwnd ;更新窗口,例6.134/6,CreateWindowEx函数,CreateWindowEx函数,HWND CreateWindowEx(DWORD dwExStyle, / 窗口的扩展风格LPCTSTR lpClassName, / 指向注册的窗口类名称LPCTSTR lpWindowName, / 指向窗口程序名称DWORD dwStyle, / 窗口风格int x, / 窗口水平位置int y, / 窗口垂直位置int nWidth, / 窗口宽度

44、int nHeight, / 窗口高度HWND hWndParent, / 父窗口句柄HMENU hMenu, / 菜单句柄,或子窗口标识符HINSTANCE hInstance, / 应用程序实例句柄LPVOID lpParam / 指向窗口数据);,.WHILE TRUE ;消息循环invoke GetMessage, ADDR msg,NULL,0,0 ;获得消息.BREAK .IF (!eax);.WHILE TRUE形成无条件循环;此处当EAX等于0则跳出循环invoke TranslateMessage,ADDR msg;翻译消息invoke DispatchMessage,ADD

45、R msg;分派消息.ENDWmov eax,msg.wParamret WinMain endp,例6.135/6,消息循环,消息循环,每个Windows程序维持一个消息队列 当一个输入事件发生时,Windows操作系统翻译该事件成为一个消息,并放置于消息队列中 例题程序使用WHILE循环结构形成消息循环 消息循环开始,GetMessage函数从消息队列检索一个消息 使用TranslateMessage函数将虚拟键消息翻译成字符消息,并放回到应用程序的消息队列 利用DispatchMessage函数将消息分派给窗口过程,也就是在注册窗口时的WndProc过程,WndProc proc hWn

46、d:DWORD, uMsg:DWORD,wParam:DWORD,lParam:DWORD.IF uMsg=WM_DESTROYinvoke PostQuitMessage,NULL ;处理关闭程序的消息.ELSE;不处理的消息由系统默认操作invoke DefWindowProc, hWnd,uMsg,wParam,lParamret.ENDIFxor eax,eaxret WndProc endp,例6.136/6,窗口过程,窗口过程,窗口过程决定了在客户区的显示内容,以及程序如何响应用户输入 窗口过程根据参数uMsg得到消息,转到不同的分支去处理 窗口过程处理的消息,返回时要在EAX中赋

47、值0 处理WM_DESTROY消息:调用PostQuitMessage函数,向消息队列发送WM_QUIT消息,并返回 不处理的消息,调用DefWindowProc函数,;弹出消息的窗口应用程序;数据段增加一个字符串: szText db 欢迎进入32位Windows世界!,0;窗口过程增加两条语句:invoke PostQuitMessage,NULL;处理关闭程序的消息.ELSEIF uMsg=WM_LBUTTONDOWN;处理单击鼠标左键的消息invoke MessageBox,NULL, addr szText, addr AppName,MB_OK.ELSE;不处理的消息由系统默认操作,例6.14,第6章 教学要求,熟悉32位80x86CPU的3种工作方式和32位寄存器组,掌握32位寻址方式 理解16位指令如何实现32位扩展,熟悉常用16位指令的32位扩展功能及应用,了解常用的32位新增指令 掌握在DOS环境32位指令编程方法 熟悉开发32位Windows控制台和窗口应用程序的方法,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报