WEB开发网
开发学院软件开发汇编语言 Win32汇编小试 阅读

Win32汇编小试

 2008-10-14 09:35:20 来源:WEB开发网   
核心提示:深入分析:看一下源程序,有这么两行:call messageboxa\call exitprocess,Win32汇编小试(2),大家一看都知道,这是子程序调用,实际上用一条指令也可完成,如下:ml /coff /I d:\masm7\include 3.asm /link /subsystem:windows /li

深入分析:

看一下源程序,有这么两行:call messageboxa\call exitprocess。大家一看都知道,这是子程序调用,但是我们并没写这样的子程序,事实上,这些是API函数。作为函数,我们在调用时可能需要传送给函数一些参数,程序怎么知道传送的参数有哪些,类型是什么呢?就是通过函数原型定义,如下所示:

ExitProcess PROTO :DWORD

MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

可以看出,ExitProcess有一个参数,MessageBoxA有四个参数,这些参数都是DWORD类型。

在Win32中,参数的传递都是通过堆栈来完成的。象MessageBoxA这个函数有四个参数,究竟是左边的先压入堆栈还是右边的先入栈呢?.model flat,stdcall给出了答案。stdcall 指定参数是从右到左压入堆栈的,且调整堆栈是在子程序返回时完成的。在源程序中不需要用“add sp,值”来保持堆栈平衡。对MessageBox,在API手册中是这样定义的:


int MessageBox(
    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
    )
    ;所以会有我们的程序段:
    push MB_OK
    lea eax,szCaption
    push eax
    lea eax,szText
    push eax
    push NULL
    call messageboxa

看看上面的程序,不难想到,假如在写程序时,少往堆栈里压入一个数据,那将是一个致命的错误。能不能将这种检查参数个数是否匹配的工作交给计算机来完成呢?这是可以的,INVOKE指令可以帮助我们完成这样的工作。假如你的参数个数不正确,连接器将给出错误提示。所以,极力建议你使用invoke代替call来调用子程序,当然,这不是绝对的。使用invoke上面的指令就可简写成下面的样子,看起来简炼多啦,查错也方便啦!

invoke messageboxa, NULL,addr szText,addr szCaption,MB_OK

另外,像NULL,MB_OK都是一些常量,这样的常量有很多,还有很多的结构,如果在我们的程序中一开始都写这么多的东西,可能一下子就把你吓怕啦,也容易出错,更不便于看程序的主要部分。hutch整理的windows.inc包含了WIN32编程所需要的常量和结构体的定义,我们可简单的用一个include指令将这些常量和结构的定义插入到我们的文件中:本文来自编程入门网

include d:\masm32\include\windows.inc

但是windows.inc中并不包含函数原型的声明,还要从其他的头文件中得到函数原型的声明,比如:messageboxa的原型声明在user32.inc文件中,exitprocess在kernel32.inc文件中。这些头文件都放在 \masm32\include文件夹下。

还有,要用windows.inc,必须使用option casemap:none,它的意思是告诉 MASM 要区分符号的大小写,譬如:start和START是不一样的。否则,一个小小的程序,可能会出成百上千的错误呀!

其他的,就不再细说啦,到此,上面的程序可重新修改如下:

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


;最终的结果
    .386          ;表示要用到386指令
    .model flat,stdcall   ;32位程序,要用flat啦!
    option casemap:none   ;区别大小写
include  windows.inc ;常量及结构定义
include  kernel32.inc ;函数原型声明
include  user32.inc
includelib kernel32.lib ;用到的引入库
includelib user32.lib
    .data
szText  db "Hello, world!",0
szCaption db "Win32Asm",0
    .code
start:
    invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
    invoke ExitProcess,NULL     ;程序退出
    end start


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

编译链接:

ml  /c /coff /I d:\masm7\include 3.asm  ;注意开关符识别大小写

link /subsystem:windows /libpath:d:\masm7\lib 3.obj

/I d:\masm7\include 表示*.inc文件的位置,也可设置环境变量Set include=d:\masm7\include来简化操作,也可在程序中明确指出*.inc的位置。

前面讲的都是用两条指令来完成编译链接,实际上用一条指令也可完成,如下:

ml /coff /I d:\masm7\include 3.asm /link /subsystem:windows /libpath:lib

若*.inc及引入库在源程序中都明确指出其位置,则可简化为:

ml /coff 3.asm /link /subsystem:windows

累,先写到这儿吧!

上一页  1 2 

Tags:Win 汇编 小试

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接