对于汇编语言来说,Win32环境中的参数实际上只有一种类型,那就是一个32位的整数,所有像HWND,LPCTSTR,UINT这些类型都是汇编的dword,之所以定义那么多,是为了说明其用途。
在汇编里,WIN API函数的参数都是从右至左依次进栈。
在源程序编译链接成可执行文件后, call MessageBox 语句中的MessageBox会被换成一个地址,指向PE文件的导入表,导入表中指向MessageBox函数的实际地址会在程序装入内存的时候,根据User32.dll在内存中的位置由系统动态填入。
若API函数有返回值,永远放在EAX中,如果要返回的内容不是一个EAX所能容纳的,那就在eax中返回一个指向返回数据的指针,或者在调用参数中提供一个缓冲区地址,干脆把数据直接返回到缓冲区中去。
在调用API函数的时候,函数原型也必须预先声明,否则,编译器会不认这个函数。
格式: 函数名 proto [距离] [语言] [参数1]: 数据类型,[参数2]:数据类型,
.
Win32是平坦的段,没有距离,忽略。
语言就是.model那些类型,忽略就使用.model定义的默认值
对于编译器来说,只关心参数的个数,名称也可以省略。
如:
MessageBox Proto hWnd: dword, lpText: dword, lpCaption: dword, uType: dword
MessageBox :dword,:dword,:dword,:dword
在Win32环境中,和字符串相关的API有两类: 1 .处理ANSI字符集的,此类函数尾部带 " A " ,适用于欧洲语言体系。 2 .处理Unicode字符集的,此类函数尾部带 " W " ,适用于东方语系。
为了程序更有移植性,一般是使用宏汇编中的条件汇编来统一替换,比如:
if UNICODE
MessageBox equ <MessageBoxW>
else
MessageBox equ <MessageBoxA>
endif
然后在源程序的头部置顶UNICODE=1或者UNICODE= 0 ,重新编译后就能产生不同的版本。
Win32里,用函数库来定位函数信息,一个DLL文件对应一个导入库,如User32.dll文件用于编程的导入库是User32.lib,使用格式:
includelib 库文件名
在汇编里,WIN API函数的参数都是从右至左依次进栈。
在源程序编译链接成可执行文件后, call MessageBox 语句中的MessageBox会被换成一个地址,指向PE文件的导入表,导入表中指向MessageBox函数的实际地址会在程序装入内存的时候,根据User32.dll在内存中的位置由系统动态填入。
若API函数有返回值,永远放在EAX中,如果要返回的内容不是一个EAX所能容纳的,那就在eax中返回一个指向返回数据的指针,或者在调用参数中提供一个缓冲区地址,干脆把数据直接返回到缓冲区中去。
在调用API函数的时候,函数原型也必须预先声明,否则,编译器会不认这个函数。
格式: 函数名 proto [距离] [语言] [参数1]: 数据类型,[参数2]:数据类型,
![](https://www.cnblogs.com/Images/dot.gif)
Win32是平坦的段,没有距离,忽略。
语言就是.model那些类型,忽略就使用.model定义的默认值
对于编译器来说,只关心参数的个数,名称也可以省略。
如:
MessageBox Proto hWnd: dword, lpText: dword, lpCaption: dword, uType: dword
MessageBox :dword,:dword,:dword,:dword
在Win32环境中,和字符串相关的API有两类: 1 .处理ANSI字符集的,此类函数尾部带 " A " ,适用于欧洲语言体系。 2 .处理Unicode字符集的,此类函数尾部带 " W " ,适用于东方语系。
为了程序更有移植性,一般是使用宏汇编中的条件汇编来统一替换,比如:
if UNICODE
MessageBox equ <MessageBoxW>
else
MessageBox equ <MessageBoxA>
endif
然后在源程序的头部置顶UNICODE=1或者UNICODE= 0 ,重新编译后就能产生不同的版本。
Win32里,用函数库来定位函数信息,一个DLL文件对应一个导入库,如User32.dll文件用于编程的导入库是User32.lib,使用格式:
includelib 库文件名