Win32汇编语言教程

Tasm 5.0 很好的汇编工具, 体现在写病毒方面. 立即下载
一、引言

Win32应用程序一般使用C语言编程,但是在某些需要进行深层编程的情况下,例如Win32应用程序执行机制分析、病毒清除、加密解密等深层编程,或者对于某些速度要求较高的程序,需要使用汇编语言(甚至机器语言)直接编写Win32应用程序。Win32应用程序虽然和其他32位应用程序(例如32位保护模式DOS程序)一样可以使用386汇编语言和保护模式编程,但是Win32应用程序的执行机制与其他32位应用程序有一定的差别,例如消息循环、动态链接等,Win32汇编语言也有其特殊的编程方式。目前国内极少看到有关Win32汇编语言的资料,市面上的汇编语言书籍一般只介绍DOS实模式汇编语言和386保护模式汇编语言,金山公司的《深入Windows编程》一书虽然介绍了使用汇编语言写Windows应用程序的方法,可惜该书只介绍了Win16汇编语言。为了使大家能对Win32汇编语言的基本编程方法有一定的了解,近日得闲,笔者编写了本教程,旨在抛砖引玉,如果本教程能够带领你走进神秘的Win32汇编语言世界,笔者心愿足矣。使用本教程,要求读者具有C语言编写Win32应用程序(Win32SDK编程)的基础。

二、进行Win32汇编语言编程的基本软件

进行Win32汇编语言编程,应该准备下列基本软件:
1、MASM 6.11以上版本的汇编器
MASM是Microsoft公司的汇编器,这是最基本的软件,必需MASM 6.11以上版本才能够汇编Win32汇编语言源程序。不过进行Win32汇编语言编程不必要全套的MASM 6.11,只要一个ML.EXE文件就可以了,Windows 95 DDK中带有MASM 6.11c的ML.EXE文
件,Windows 98 DDK中带有MASM 6.11d的ML.EXE文件,都可以使用。Turbo MASM 5.0(TASM)是Borland公司的汇编器,也可以用来汇编Win32汇编语言源程序,但是TASM的部分语法与MASM不同,用于MASM的Win32汇编语言源程序可能需要修改后才能用TASM汇编。本教程中的所有Win32汇编语言源程序都基于MASM。
2、Win32SDK
进行Win32汇编语言编程需要用到Win32SDK中的资源编译器(RC.EXE)和连接器(LINK.EXE),还需要用到Win32SDK中的引入库文件(KERNEL32.LIB、USER32.LIB、GDI32.LIB等)。如果没有Win32SDK,Platform SDK也可以,还可以安装Visual C++ 2.0以上版本的Visual C++,笔者使用的是Visual C++ 6.0。Borland C++ 4.0以上版本的Borland C++也可以使用,只是资源编译器和连接器的
文件名不同,分别是BRC.EXE(BRC32.EXE)和TLINK.EXE(TLINK32.EXE),选项也不尽相同,另外Borland C++不支持COFF格式的OBJ文件,汇编时不能使用/coff选项。
3、汇编语言编辑器
一个普通的文本编辑器,用于编辑Win32汇编语言源程序。EDIT、PWB等都可以,Visual C++等编程语言中的编辑器也可以,甚至WORD、WPS 97等可以编辑文本文件的字处理软件都可以,不过笔者推荐使用ASMEDIT,这是一个专用的汇编语言编辑
器,效果非常好。Win32汇编语言一般使用命令行方式汇编连接,经过一定的设置也可以在某些集成
环境(PWB、Visual C++、ASMEDIT等)下汇编连接,还可以使用NMAKE工具,不过本教程中只使用命令行方式汇编连接,也不使用NMAKE工具。

三、ANSI字符集API与UNICODE字符集API

Win32 API中凡是与字符有关的API都有两种不同的类型:ANSI字符集API和UNICODE字符集API,分别对应ANSI字符和UNICODE字符,Windows NT支持两种类型的API,Windows 95/98只支持ANSI字符集API。在WINDOWS.H头文件和其他Win32 API定义
头文件中,凡是与字符有关的API都有两种不同的定义,ANSI字符集API以API名称加字符“A”表示,UNICODE字符集API以API名称加字符“W”表示,并使用条件编译和宏定义实现自动根据当前字符集使用对应的API定义,例如GetModuleHandle函数的定义(包括在WINBASE.H头文件中):

WINBASEAPI
HMODULE
WINAPI
GetModuleHandleA(
    LPCSTR lpModuleName
    );
WINBASEAPI
HMODULE
WINAPI
GetModuleHandleW(
    LPCWSTR lpModuleName
    );
#ifdef UNICODE
#define GetModuleHandle  GetModuleHandleW
#else
#define GetModuleHandle  GetModuleHandleA
#endif // !UNICODE

与字符有关的数据结构也有类似的定义。本教程考虑到汇编语言使用条件汇编会导致不太直观,全部使用ANSI字符集API,这样也可以保证在Windows 95/98和Windows NT环境下的兼容性,所以本教程中许多API名称和数据结构的名称都加有“A”字符,读者可以方便地改用UNICODE字符集API。

四、一个简单的Win32汇编语言程序

读者可能一听到“汇编语言”四个字就觉得十分头疼!汇编语言给人的第一印象就是一大堆难以看懂又不直观的指令,而且不结构化,大量的标号、无条件跳转指令(JMP)和条件跳转指令让你难以看懂程序;过程(或者函数)的调用参数传递又不直观,要么直接使用寄存器传递参数,不符合结构化程序设计原则;要么使用堆栈传递参数,又不能有效地检验参数类型……想必Win32汇编语言更麻烦吧!还好,MASM 6.0以上版本的汇编器提供了很多结构化汇编语言伪指令,可以方便地实现汇编语言结构化程序设计,当你看完本教程以后,你可能会感觉到:Win32汇编语言并不比C语言麻烦多少。(如果读者看不懂本教程中的汇编语言源程序也不要紧,可以对照MASM 6.11的帮助看)和C语言Win32编程需要WINDOWS.H头文件和其他Win32 API定义头文件定义常量、数据结构和API一样,Win32汇编语言也需要包含文件(INC文件)定义常量、数据结构和API。不过笔者找了很长时间也没有找到一个完整的可用于Win32汇编语言的WINDOWS.INC文件或者WIN32.INC文件(倒是找到了用于Win16汇编语言的WINDOWS.INC文件),Turbo MASM 5.0中提供的WIN32.INC文件也不完整,只能用于自带的WAP32例子程序,而且与MASM 6.11不太兼容(听说NASM中有完整的WIN32.INC文件,可惜没有找到,也不知道与MASM 6.11是否兼容)。笔者只好自己定义常量、数据结构和API(根据WINDOWS.H头文件和其他Win32 API定义头文件定义),不过这倒
带来了不少好处——可以更好地了解Win32汇编语言的编程方法和原理。笔者编写了一个简单的Win32汇编语言程序,该程序的功能很简单:在屏幕上显示一个消息框。本程序只调用了两个API函数:MessageBox函数和ExitProcess函数,程序如下:
包含文件(MSGBOX.INC):

UINT  TYPEDEF  DWORD
LPSTR  TYPEDEF  PTR BYTE
LPCSTR  TYPEDEF  LPSTR
PVOID  TYPEDEF  PTR
HANDLE  TYPEDEF  PVOID
HWND  TYPEDEF  HANDLE

MB_ICONINFORMATION =  00000040h
MB_OK   =  00000000h

MessageBoxA  PROTO stdcall, :HWND,:LPCSTR,:LPCSTR,:UINT
ExitProcess  PROTO stdcall, :UINT

源程序(MSGBOX.ASM):

.386p

.MODEL flat,stdcall

INCLUDE MSGBOX.INC

.STACK 4096

.DATA
WindowTitle BYTE  'MsgBox',0
Message1 BYTE  'This is a simple MessageBox
Win32 application.',0

.CODE

_start:
INVOKE MessageBoxA,0,ADDR Message1,ADDR WindowTitle,
MB_ICONINFORMATION or MB_OK
INVOKE ExitProcess,0

PUBLIC _start

END

汇编连接本程序的命令如下:

ml /c /coff /Cp msgbox.asm
link /subsystem:windows /entry:_start msgbox.obj kernel32.lib user32.lib

汇编命令中的/c选项表示只汇编,不自动连接;/coff选项表示生成COFF格式的OBJ文件(如果使用Borland的连接器不能使用/coff参数);/Cp选项表示标识符区分大小写。连接命令中/subsystem:windows选项表示连接器生成普通Windows可执行文件;/entry:_start选项表示程序入口点是_start标识符。连接时连接KERNEL32.LIB和USER32.LIB引入库。运行汇编连接后生成的MSGBOX.EXE文件,屏幕上将显示出一个消息框,消息框的标题是“MsgBox”,消息框中的字符串是“This is a simple MessageBox Win32 application.”。Win32汇编语言源程序应该由.386p伪指令和.MODEL flat,stdcall伪指令开始,指示汇编器汇编386保护模式指令,并使用平坦内存模式(Win32内存模式)和stdcall函数调用方式(Win32标准函数调用方式)。PROTO伪指令定义函数原型(与C语言中函数原型的定义相似),可以定义函数名、调用方式和参数,INVOKE伪指令调用由PROTO伪指令定义的函数,可以方便地传递参数和检查参数类型。MSGBOX.INC文件中使用PROTO伪指令定义API函数,MSGBOX.ASM文件中使用INVOKE伪指令调用API函数,可见MASM 6.0以上版本的汇编器提供的结构化汇编语言伪指令大大简化了Win32汇编语言编程(本程序一条汇编语言指令也没有用到)。本程序调用了MessageBox函数显示消息框以后,调用了ExitProcess函数终止程序的执行,ExitProcess函数的作用是终止当前进程。

五、显示一个窗口的Win32汇编语言程序

学习过Win32SDK编程的读者编写的第一个应用程序可能就是显示一个窗口的C语言程序,笔者也编写了这样一个C语言程序,该程序文件名为SIMPLE.C,程序如下:

#include

static char szWindowClass[]="SIMPLE";

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nShowCmd)
{
WNDCLASSEXA wcex;
HWND hWnd;
MSG msg;
if(!hPrevInstance)
{
  wcex.cbSize=sizeof(WNDCLASSEXA);
  wcex.style=CS_HREDRAW|CS_VREDRAW;
  wcex.cbClsExtra=0;
  wcex.cbWndExtra=0;
  wcex.lpfnWndProc=WndProc;
  wcex.hInstance=hInstance;
  wcex.hIcon=LoadIconA(hInstance,IDI_APPLICATION);
  wcex.hCursor=LoadCursorA(0,IDC_ARROW);
  wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName=NULL;
  wcex.lpszClassName=szWindowClass;
  wcex.hIconSm=LoadIconA(hInstance,IDI_APPLICATION);
  if(!RegisterClassExA(&wcex)) return FALSE;
}
hWnd=CreateWindowExA(0,szWindowClass,"SIMPLE",
WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
       0,0,hInstance,NULL);
if(!hWnd) return FALSE;
ShowWindow(hWnd,nShowCmd);
UpdateWindow(hWnd);
while(GetMessageA(&msg,0,0,0))
{
  TranslateMessage(&msg);
  DispatchMessageA(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
HDC hDC;
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
  hDC=BeginPaint(hWnd,&ps);
  EndPaint(hWnd,&ps);
  return 0;
case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
default:
  return DefWindowProcA(hWnd,message,wParam,lParam);
}
return -1;
}

本程序与一般的显示一个窗口的C语言程序基本相同,只是只使用ANSI字符集。现在笔者用Win32汇编语言程序实现本程序的功能,程序如下:
包含文件(SIMPLE.INC):

UINT  TYPEDEF  DWORD
LONG  TYPEDEF  DWORD
LPSTR  TYPEDEF  PTR BYTE
LPCSTR  TYPEDEF  LPSTR
PVOID  TYPEDEF  PTR
LPVOID  TYPEDEF  PVOID
HANDLE  TYPEDEF  PVOID
HINSTANCE TYPEDEF  HANDLE
HWND  TYPEDEF  HANDLE
HMENU  TYPEDEF  HANDLE
HDC  TYPEDEF  HANDLE
HGDIOBJ  TYPEDEF  HANDLE
HICON  TYPEDEF  HANDLE
HCURSOR  TYPEDEF  HANDLE
HBRUSH  TYPEDEF  HANDLE

tagWNDCLASSEXA STRUCT
cbSize  UINT  ?
style  UINT  ?
lpfnWndProc DWORD  ?
cbClsExtra DWORD  ?
cbWndExtra DWORD  ?
hInstance DWORD  ?
hIcon  DWORD  ?
hCursor  DWORD  ?
hbrBackground DWORD  ?
lpszMenuName DWORD  ?
lpszClassName DWORD  ?
hIconSm  DWORD  ?
tagWNDCLASSEXA ENDS

WNDCLASSEXA TYPEDEF  tagWNDCLASSEXA

tagPOINT STRUCT
x  LONG  ?
y  LONG  ?
tagPOINT ENDS

POINT  TYPEDEF  tagPOINT

tagMSG  STRUCT
message  UINT  ?
wParam  DWORD  ?
lParam  DWORD  ?
time  DWORD  ?
pt  POINT  <>
tagMSG  ENDS

MSG  TYPEDEF  tagMSG
LPMSG  TYPEDEF  PTR MSG

tagRECT  STRUCT
left  LONG  ?
top  LONG  ?
right  LONG  ?
bottom  LONG  ?
tagRECT  ENDS

RECT  TYPEDEF  tagRECT

tagPAINTSTRUCT STRUCT
hdc  DWORD  ?
fErase  DWORD  ?
rcPaint  RECT  <>
fRestore DWORD  ?
fIncUpdate DWORD  ?
rgbReserved BYTE  32 DUP(?)
tagPAINTSTRUCT ENDS

PAINTSTRUCT TYPEDEF  tagPAINTSTRUCT
LPPAINTSTRUCT TYPEDEF  PTR PAINTSTRUCT

NULL   =  0

TRUE   =  0ffffffffh
FALSE   =  0

SW_SHOWDEFAULT  =  10

CS_HREDRAW  =  0002h
CS_VREDRAW  =  0001h

IDI_APPLICATION  =  32512
IDC_ARROW  =  32512

COLOR_WINDOW  =  5

WS_OVERLAPPEDWINDOW =  00cf0000h

CW_USEDEFAULT  =  80000000h

WM_PAINT  =  000fh
WM_DESTROY  =  0002h

GetModuleHandleA PROTO stdcall, :LPCSTR
GetCommandLineA  PROTO stdcall
ExitProcess  PROTO stdcall, :UINT
LoadIconA  PROTO stdcall, :HINSTANCE,:LPCSTR
LoadCursorA  PROTO stdcall, :HINSTANCE,:LPCSTR
RegisterClassExA PROTO stdcall, :PTR WNDCLASSEXA
CreateWindowExA  PROTO stdcall, :DWORD,:LPCSTR,:LPCSTR,:DWORD,:
DWORD,:DWORD,:DWORD,:DWORD,:HWND,:HMENU,:HINSTANCE,:LPVOID
ShowWindow  PROTO stdcall, :HWND,:DWORD
UpdateWindow  PROTO stdcall, :HWND
GetMessageA  PROTO stdcall, :LPMSG,:HWND,:UINT,:UINT
TranslateMessage PROTO stdcall, :PTR MSG
DispatchMessageA PROTO stdcall, :PTR MSG
BeginPaint  PROTO stdcall, :HWND,:LPPAINTSTRUCT
EndPaint  PROTO stdcall, :HWND,:PTR PAINTSTRUCT
PostQuitMessage  PROTO stdcall, :DWORD
DefWindowProcA  PROTO stdcall, :HWND,:UINT,:DWORD,:DWORD

源程序(SIMPLE.ASM):

.386p

.MODEL flat,stdcall

INCLUDE SIMPLE.INC

WinMain   PROTO stdcall, :HINSTANCE,:HINSTANCE,:LPSTR,:
DWORD

.STACK 4096

.DATA
WindowClass BYTE  'SIMPLE',0
WindowTitle BYTE  'SIMPLE',0
hInst1  HINSTANCE 0
lpCmdLine1 LPSTR  0

.CODE

_start:
INVOKE GetModuleHandleA,NULL
mov hInst1,eax
INVOKE GetCommandLineA
mov lpCmdLine1,eax
INVOKE WinMain,hInst1,NULL,lpCmdLine1,SW_SHOWDEFAULT
INVOKE ExitProcess,eax  

WinMain PROC hInst:HINSTANCE,hPrevInst:HINSTANCE,lpCmdLine:LPSTR,
nShowCmd:DWORD
LOCAL wcex:WNDCLASSEXA
LOCAL hWnd:HWND
LOCAL msg:MSG
.IF !hPrevInst
  mov wcex.cbSize,SIZEOF WNDCLASSEXA
  mov wcex.style,CS_HREDRAW or CS_VREDRAW
  mov wcex.cbClsExtra,0
  mov wcex.cbWndExtra,0
  mov wcex.lpfnWndProc,OFFSET WndProc
  mov eax,hInst
  mov wcex.hInstance,eax
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIcon,eax
  INVOKE LoadCursorA,0,IDC_ARROW
  mov wcex.hCursor,eax
  mov wcex.hbrBackground,COLOR_WINDOW+1
  mov wcex.lpszMenuName,NULL
  mov wcex.lpszClassName,OFFSET WindowClass
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIconSm,eax
  INVOKE RegisterClassExA,ADDR wcex
  .IF !eax
   mov eax,FALSE
   ret
  .ENDIF
.ENDIF
INVOKE CreateWindowExA,0,ADDR WindowClass,ADDR WindowTitle,
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,0,0,hInst,NULL
mov hWnd,eax
.IF !eax
  mov eax,FALSE
  ret
.ENDIF
INVOKE ShowWindow,hWnd,nShowCmd
INVOKE UpdateWindow,hWnd
.WHILE TRUE
  INVOKE GetMessageA,ADDR msg,0,0,0
  .BREAK .IF !eax
  INVOKE TranslateMessage,ADDR msg
  INVOKE DispatchMessageA,ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain ENDP

WndProc PROC hWnd:HWND,message:UINT,wParam:DWORD,lParam:DWORD
LOCAL hDC:HDC
LOCAL ps:PAINTSTRUCT
.IF message==WM_PAINT
  INVOKE BeginPaint,hWnd,ADDR ps
  mov hDC,eax
  INVOKE EndPaint,hWnd,ADDR ps
  mov eax,0
  ret
.ELSEIF message==WM_DESTROY
  INVOKE PostQuitMessage,0
  mov eax,0
  ret
.ELSE
  INVOKE DefWindowProcA,hWnd,message,wParam,lParam
  ret
.ENDIF
mov eax,0ffffffffh
ret
WndProc ENDP

PUBLIC _start

END

汇编连接本程序的命令如下:

ml /c /coff /Cp simple.asm
link /subsystem:windows /entry:_start simple.obj kernel32.lib user32.lib
gdi32.lib

运行汇编连接后生成的SIMPLE.EXE文件,屏幕上将显示出一个标准的窗口,窗口的标题是“SIMPLE”。学习过Win32SDK编程的读者都知道,Win32应用程序的入口点是WinMain函数,实际上WinMain函数是被C语言的初始化和结束代码调用的,Win32应用程序的真正入口点和DOS应用程序没有什么区别,都是在文件头中指定的应用程序起始点。Win32汇编语言没有C语言的初始化和结束代码,必须自己编写初始化和结束代码调用
WinMain函数(过程),WinMain函数的原型是:

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nShowCmd);

WinMain函数有4个参数,分别是:
hInstance——应用程序当前实例的句柄,可以通过调用GetModuleHandle函数获取.
hPrevInstance——应用程序前一个实例的句柄,Win32中当前地址空间中不会有应用程序的其他实例在运行,该参数通常设置为NULL(提供该参数只是便于移植Win16应用程序源程序)。
lpCmdLine——命令行参数,可以通过调用GetCommandLine函数获取。nShowCmd——主窗口的显示状态,可以设置成SW_SHOWDEFAULT(缺省状态)。本程序的初始化和结束代码如下:

INVOKE GetModuleHandleA,NULL
mov hInst1,eax
INVOKE GetCommandLineA
mov lpCmdLine1,eax
INVOKE WinMain,hInst1,NULL,lpCmdLine1,SW_SHOWDEFAULT
INVOKE ExitProcess,eax  

Win32标准函数调用方式,函数返回值通过EAX寄存器返回。可见本程序的初始化和结束代码很简单,只是调用GetModuleHandle函数获取应用程序当前实例的句柄,调用GetCommandLine函数获取命令行参数,然后调用WinMain函数(过程),WinMain函数返回后调用ExitProcess函数终止程序的执行。将本程序与SIMPLE.C程序比较,可以看出程序结构十分相似,本程序大量使用了MASM 6.0以上版本的汇编器提供的结构化汇编语言伪指令,并不比C语言麻烦多少。
六、资源在Win32汇编语言程序中的使用

资源在Win32应用程序中是很重要的,笔者编写了一个使用资源的C语言程序,该程序实现了菜单和一个“About”对话框,程序如下:
源程序(GENERIC.C):

#include
#include "resource.h"

static HINSTANCE hInst;
static char szWindowClass[]="GENERIC";

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam);
BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM
lParam);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nShowCmd)
{
WNDCLASSEXA wcex;
HWND hWnd;
MSG msg;
hInst=hInstance;
if(!hPrevInstance)
{
  wcex.cbSize=sizeof(WNDCLASSEXA);
  wcex.style=CS_HREDRAW|CS_VREDRAW;
  wcex.cbClsExtra=0;
  wcex.cbWndExtra=0;
  wcex.lpfnWndProc=WndProc;
  wcex.hInstance=hInstance;
  wcex.hIcon=LoadIconA(hInstance,IDI_APPLICATION);
  wcex.hCursor=LoadCursorA(0,IDC_ARROW);
  wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName=MAKEINTRESOURCE(IDR_MAINMENU);
  wcex.lpszClassName=szWindowClass;
  wcex.hIconSm=LoadIconA(hInstance,IDI_APPLICATION);
  if(!RegisterClassExA(&wcex)) return FALSE;
}
hWnd=CreateWindowExA(0,szWindowClass,"Generic",
WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
       0,0,hInstance,NULL);
if(!hWnd) return FALSE;
ShowWindow(hWnd,nShowCmd);
UpdateWindow(hWnd);
while(GetMessageA(&msg,0,0,0))
{
  TranslateMessage(&msg);
  DispatchMessageA(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
HDC hDC;
PAINTSTRUCT ps;
switch(message)
{
case WM_COMMAND:
  switch(LOWORD(wParam))
  {
  case IDM_EXIT:
   SendMessageA(hWnd,WM_CLOSE,0,0);
   return 0;
  case IDM_ABOUT:
   DialogBoxParamA(hInst,MAKEINTRESOURCE(IDD_ABOUT),
hWnd,(DLGPROC)AboutDlgProc,0);
   return 0;
  default:
   return DefWindowProcA(hWnd,message,wParam,lParam)
;
  }
case WM_PAINT:
  hDC=BeginPaint(hWnd,&ps);
  EndPaint(hWnd,&ps);
  return 0;
case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
default:
  return DefWindowProcA(hWnd,message,wParam,lParam);
}
return -1;
}

BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM
lParam)
{
switch(message)
{
case WM_INITDIALOG:
  return TRUE;
case WM_COMMAND:
  if((LOWORD(wParam)==IDOK)||(LOWORD(wParam)==IDCANCEL))
  {
   EndDialog(hDlg,LOWORD(wParam));
   return TRUE;
  }
  return FALSE;
default:
  return FALSE;
}
}

资源源文件(GENERIC.RC,使用Visual C++ 6.0建立):

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
////////////////////////////////////////////////////////////////////////
/////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

////////////////////////////////////////////////////////////////////////
/////
#undef APSTUDIO_READONLY_SYMBOLS

////////////////////////////////////////////////////////////////////////
/////
// Chinese (P.R.C.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

////////////////////////////////////////////////////////////////////////
/////
//
// Menu
//

IDR_MAINMENU MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Exit",                       IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About...",                   IDM_ABOUT
    END
END


#ifdef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////
/////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
    "resource.h/0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
    "#include ""afxres.h""/r/n"
    "/0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
    "/r/n"
    "/0"
END

#endif    // APSTUDIO_INVOKED


////////////////////////////////////////////////////////////////////////
/////
//
// Dialog
//

IDD_ABOUT DIALOG DISCARDABLE  0, 0, 92, 65
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 9, "宋体"
BEGIN
    LTEXT           "Generic V1.0",IDC_STATIC1,20,10,50,10
    DEFPUSHBUTTON   "OK",IDOK,20,40,50,15
END


////////////////////////////////////////////////////////////////////////
/////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
    IDD_ABOUT, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 85
        TOPMARGIN, 7
        BOTTOMMARGIN, 58
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // Chinese (P.R.C.) resources
////////////////////////////////////////////////////////////////////////
/////



#ifndef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////
/////
//
// Generated from the TEXTINCLUDE 3 resource.
//


////////////////////////////////////////////////////////////////////////
/////
#endif    // not APSTUDIO_INVOKED


资源头文件(RESOURCE.H,Visual C++ 6.0自动建立):

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by GENERIC.rc
//
#define IDR_MAINMENU                    101
#define IDD_ABOUT                       102
#define IDC_STATIC1                     1000
#define IDM_EXIT                        40001
#define IDM_ABOUT                       40002

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        103
#define _APS_NEXT_COMMAND_VALUE         40003
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

本程序与一般Win32编程资料中的GENERIC程序基本相同,只是只使用ANSI字符集。
现在笔者用Win32汇编语言程序实现本程序的功能,程序如下:
包含文件(GENERIC.INC):

UINT  TYPEDEF  DWORD
LONG  TYPEDEF  DWORD
LPSTR  TYPEDEF  PTR BYTE
LPCSTR  TYPEDEF  LPSTR
PVOID  TYPEDEF  PTR
LPVOID  TYPEDEF  PVOID
HANDLE  TYPEDEF  PVOID
HINSTANCE TYPEDEF  HANDLE
HWND  TYPEDEF  HANDLE
HMENU  TYPEDEF  HANDLE
HDC  TYPEDEF  HANDLE
HGDIOBJ  TYPEDEF  HANDLE
HICON  TYPEDEF  HANDLE
HCURSOR  TYPEDEF  HANDLE
HBRUSH  TYPEDEF  HANDLE

tagWNDCLASSEXA STRUCT
cbSize  UINT  ?
style  UINT  ?
lpfnWndProc DWORD  ?
cbClsExtra DWORD  ?
cbWndExtra DWORD  ?
hInstance DWORD  ?
hIcon  DWORD  ?
hCursor  DWORD  ?
hbrBackground DWORD  ?
lpszMenuName DWORD  ?
lpszClassName DWORD  ?
hIconSm  DWORD  ?
tagWNDCLASSEXA ENDS

WNDCLASSEXA TYPEDEF  tagWNDCLASSEXA

tagPOINT STRUCT
x  LONG  ?
y  LONG  ?
tagPOINT ENDS

POINT  TYPEDEF  tagPOINT

tagMSG  STRUCT
message  UINT  ?
wParam  DWORD  ?
lParam  DWORD  ?
time  DWORD  ?
pt  POINT  <>
tagMSG  ENDS

MSG  TYPEDEF  tagMSG
LPMSG  TYPEDEF  PTR MSG

tagRECT  STRUCT
left  LONG  ?
top  LONG  ?
right  LONG  ?
bottom  LONG  ?
tagRECT  ENDS

RECT  TYPEDEF  tagRECT

tagPAINTSTRUCT STRUCT
hdc  DWORD  ?
fErase  DWORD  ?
rcPaint  RECT  <>
fRestore DWORD  ?
fIncUpdate DWORD  ?
rgbReserved BYTE  32 DUP(?)
tagPAINTSTRUCT ENDS

PAINTSTRUCT TYPEDEF  tagPAINTSTRUCT
LPPAINTSTRUCT TYPEDEF  PTR PAINTSTRUCT

NULL   =  0

TRUE   =  0ffffffffh
FALSE   =  0

SW_SHOWDEFAULT  =  10

CS_HREDRAW  =  0002h
CS_VREDRAW  =  0001h

IDI_APPLICATION  =  32512
IDC_ARROW  =  32512

COLOR_WINDOW  =  5

WS_OVERLAPPEDWINDOW =  00cf0000h

CW_USEDEFAULT  =  80000000h

WM_COMMAND  =  0111h
WM_CLOSE  =  0010h
WM_PAINT  =  000fh
WM_DESTROY  =  0002h
WM_INITDIALOG  =  0110h

IDOK   =  1
IDCANCEL  =  2

GetModuleHandleA PROTO stdcall, :LPCSTR
GetCommandLineA  PROTO stdcall
ExitProcess  PROTO stdcall, :UINT
LoadIconA  PROTO stdcall, :HINSTANCE,:LPCSTR
LoadCursorA  PROTO stdcall, :HINSTANCE,:LPCSTR
RegisterClassExA PROTO stdcall, :PTR WNDCLASSEXA
CreateWindowExA  PROTO stdcall, :DWORD,:LPCSTR,:LPCSTR,:DWORD,:
DWORD,:DWORD,:DWORD,:DWORD,:HWND,:HMENU,:HINSTANCE,:LPVOID
ShowWindow  PROTO stdcall, :HWND,:DWORD
UpdateWindow  PROTO stdcall, :HWND
GetMessageA  PROTO stdcall, :LPMSG,:HWND,:UINT,:UINT
TranslateMessage PROTO stdcall, :PTR MSG
DispatchMessageA PROTO stdcall, :PTR MSG
SendMessageA  PROTO stdcall, :HWND,:UINT,:DWORD,:DWORD
DialogBoxParamA  PROTO stdcall, :HINSTANCE,:LPCSTR,:HWND,:DWORD,:
DWORD
BeginPaint  PROTO stdcall, :HWND,:LPPAINTSTRUCT
EndPaint  PROTO stdcall, :HWND,:PTR PAINTSTRUCT
PostQuitMessage  PROTO stdcall, :DWORD
DefWindowProcA  PROTO stdcall, :HWND,:UINT,:DWORD,:DWORD
EndDialog  PROTO stdcall, :HWND,:DWORD

资源包含文件(RESOURCE.INC):

IDR_MAINMENU  =  101
IDD_ABOUT  =  102
IDC_STATIC1  =  1000
IDM_EXIT  =  40001
IDM_ABOUT  =  40002

源程序(GENERIC.ASM):

.386p

.MODEL flat,stdcall

INCLUDE GENERIC.INC
INCLUDE RESOURCE.INC

WinMain   PROTO stdcall, :HINSTANCE,:HINSTANCE,:LPSTR,:
DWORD

.STACK 4096

.DATA
WindowClass BYTE  'GENERIC',0
WindowTitle BYTE  'Generic',0
hInst1  HINSTANCE 0
lpCmdLine1 LPSTR  0

.CODE

_start:
INVOKE GetModuleHandleA,NULL
mov hInst1,eax
INVOKE GetCommandLineA
mov lpCmdLine1,eax
INVOKE WinMain,hInst1,NULL,lpCmdLine1,SW_SHOWDEFAULT
INVOKE ExitProcess,eax  

WinMain PROC hInst:HINSTANCE,hPrevInst:HINSTANCE,lpCmdLine:LPSTR,
nShowCmd:DWORD
LOCAL wcex:WNDCLASSEXA
LOCAL hWnd:HWND
LOCAL msg:MSG
.IF !hPrevInst
  mov wcex.cbSize,SIZEOF WNDCLASSEXA
  mov wcex.style,CS_HREDRAW or CS_VREDRAW
  mov wcex.cbClsExtra,0
  mov wcex.cbWndExtra,0
  mov wcex.lpfnWndProc,OFFSET WndProc
  mov eax,hInst
  mov wcex.hInstance,eax
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIcon,eax
  INVOKE LoadCursorA,0,IDC_ARROW
  mov wcex.hCursor,eax
  mov wcex.hbrBackground,COLOR_WINDOW+1
  mov wcex.lpszMenuName,IDR_MAINMENU and 0000ffffh
  mov wcex.lpszClassName,OFFSET WindowClass
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIconSm,eax
  INVOKE RegisterClassExA,ADDR wcex
  .IF !eax
   mov eax,FALSE
   ret
  .ENDIF
.ENDIF
INVOKE CreateWindowExA,0,ADDR WindowClass,ADDR WindowTitle,
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,0,0,hInst,NULL
mov hWnd,eax
.IF !eax
  mov eax,FALSE
  ret
.ENDIF
INVOKE ShowWindow,hWnd,nShowCmd
INVOKE UpdateWindow,hWnd
.WHILE TRUE
  INVOKE GetMessageA,ADDR msg,0,0,0
  .BREAK .IF !eax
  INVOKE TranslateMessage,ADDR msg
  INVOKE DispatchMessageA,ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain ENDP

WndProc PROC hWnd:HWND,message:UINT,wParam:DWORD,lParam:DWORD
LOCAL hDC:HDC
LOCAL ps:PAINTSTRUCT
.IF message==WM_COMMAND
  mov eax,wParam
  .IF ax==IDM_EXIT
   INVOKE SendMessageA,hWnd,WM_CLOSE,0,0
   mov eax,0
   ret
  .ELSEIF ax==IDM_ABOUT
   mov ebx,OFFSET AboutDlgProc
   INVOKE DialogBoxParamA,hInst1,IDD_ABOUT and
0000ffffh,hWnd,ebx,0
   mov eax,0
   ret
  .ELSE
   INVOKE DefWindowProcA,hWnd,message,wParam,
lParam
   ret
  .ENDIF
.ELSEIF message==WM_PAINT
  INVOKE BeginPaint,hWnd,ADDR ps
  mov hDC,eax
  INVOKE EndPaint,hWnd,ADDR ps
  mov eax,0
  ret
.ELSEIF message==WM_DESTROY
  INVOKE PostQuitMessage,0
  mov eax,0
  ret
.ELSE
  INVOKE DefWindowProcA,hWnd,message,wParam,lParam
  ret
.ENDIF
mov eax,0ffffffffh
ret
WndProc ENDP

AboutDlgProc PROC hDlg:HWND,message:UINT,wParam:DWORD,lParam:DWORD
.IF message==WM_INITDIALOG
  mov eax,TRUE
  ret
.ELSEIF message==WM_COMMAND
  mov eax,wParam
  .IF (ax==IDOK)||(ax==IDCANCEL)
   INVOKE EndDialog,hDlg,ax
   mov eax,TRUE
   ret
  .ENDIF
  mov eax,FALSE
  ret
.ELSE
  mov eax,FALSE
  ret
.ENDIF
mov eax,FALSE
ret
AboutDlgProc ENDP

PUBLIC _start

END

汇编连接本程序的命令如下:

ml /c /coff /Cp generic.asm
rc generic.rc
link /subsystem:windows /entry:_start generic.obj generic.res kernel32.
lib user32.lib gdi32.lib

运行汇编连接后生成的GENERIC.EXE文件,屏幕上将显示出一个带有菜单的窗口,窗口的标题是“Generic”,菜单有两个主菜单项,分别是“File”和“Help”,选择“File”菜单项下的“Exit”菜单项可以退出程序,选择“Help”菜单项下的“About”菜单项可以显示“About”对话框。本程序与SIMPLE.C程序很相似,Win32汇编语言程序中使用资源的方法也与C语言程序没有很大的差别,都可以用资源编辑工具生成资源源文件和资源头文件,然后使用资源编译器编译资源源文件,将生成的资源文件(RES文件)与汇编器生成的目标文件和引入库文件连接在一起就可以了(资源头文件需要移植到汇编语言上,建立一个资源包含文件)。
C语言程序中的MAKEINTRESOURCE宏的实质是将资源标识符数值的高位字(不用)清零,然后强行转换成字符指针,Win32汇编语言程序中可以将资源标识符数值与0000FFFFH作AND运算。

七、控制台Win32汇编语言程序

学习过Win32SDK编程的读者一定知道控制台Win32应用程序,控制台Win32应用程序运行在控制台(MS-DOS窗口)下,与DOS下的C语言程序十分相似,程序入口点是main函数,使用标准C语言I/O函数进行I/O,也可以调用API。实际上控制台Win32应用程序与普通Win32应用程序没有本质上的区别,标准C语言I/O函数实际上还是调用了API,在控制台上进行I/O。控制台Win32汇编语言程序与C语言程序有一定的差别,需要获取控制台I/O句柄,然后使用控制台I/O句柄进行I/O(与文件句柄I/O相似),笔者以MASM 6.11中自带的控制台Win32汇编语言程序实例(HELLO.ASM)为例,程序如下:

.386
.MODEL flat, stdcall

STD_OUTPUT_HANDLE EQU -11

GetStdHandle PROTO NEAR32 stdcall,
    nStdHandle:DWORD

WriteFile PROTO NEAR32 stdcall,
    hFile:DWORD, lpBuffer:NEAR32, nNumberOfBytesToWrite:DWORD,
    lpNumberOfBytesWritten:NEAR32, lpOverlapped:NEAR32

ExitProcess PROTO NEAR32 stdcall,
    dwExitCode:DWORD

.STACK 4096

.DATA

msg DB "Hello, world.", 13, 10
written DD 0
hStdOut DD 0

.CODE
_start:
    INVOKE  GetStdHandle,
        STD_OUTPUT_HANDLE      ; Standard output handle
    mov hStdOut, eax

    INVOKE  WriteFile,
        hStdOut,               ; File handle for screen
        NEAR32 PTR msg,        ; Address of string
        LENGTHOF msg,          ; Length of string
        NEAR32 PTR written,    ; Bytes written
        0                      ; Overlapped mode

    INVOKE  ExitProcess,
        0                      ; Result code for parent process

PUBLIC _start
END

汇编连接本程序的命令如下:

ml /c /coff /Cp hello.asm
link /subsystem:console /entry:_start hello.obj kernel32.lib

连接命令中/subsystem:console选项表示连接器生成控制台Win32应用程序。在MS-DOS窗口(控制台)下运行汇编连接后生成的HELLO.EXE文件,将会像MS-DOS程序一样显示出“Hello, world.”字符串。本程序调用了GetStdHandle函数获取标准控制台输出设备句柄,然后调用WriteFile函数向标准控制台输出设备句柄写字符串,完成控制台字符串输出,最后调用了ExitProcess函数终止程序的执行。

八、结束语

本教程读者阅读到这里,可能会莞尔一笑,原来Win32汇编语言也不过就是这么回事呀,确实,MASM 6.0以上版本的汇编器提供的结构化汇编语言伪指令大大简化了Win32汇编语言编程。汇编语言确实比较复杂,但是Win32汇编语言对某些特殊方面有高级语言不可比拟的优点,如果你正在想编程清除Win32病毒(例如CIH病毒),或者你正在编写对速度要求较高的程序(例如大量计算的程序),不妨试试Win32汇编语言——或许正能够解决你的燃眉之急。本教程还简单介绍了Win32应用程序的执行机制,相信会对你探索Win32深层有一定的帮助。本教程所有的源程序已经整理打包,需要者可以直接与笔者联系,更欢迎与笔者交流经验,笔者的E-mail:kv_nt@hotmail.com。
Tasm 5.0 安装版 运行在DOS操作系统中的经典汇编器。这是安装版。 立即下载

相关推荐

win32汇编语言教程,不能错过的好教程

很好的一部教材,需要的人绝对不能错过!!

Win32汇编学习——windows汇编语法(小甲鱼教程)

Win32汇编学习——windows汇编语法(小甲鱼教程) 1)指令集 .386 语句是汇编语句的伪指令,类似指令有:.8086 、 .186 、.286 、.386/.386p 、 .486/.486p 和 .586/.586p 用于告诉编译器在本程序中使用的指令集。 在DOS的汇编中默认使用的是8086指令集,那时候如果在源程序中写入 80386所特有的指令 或使...

team39的博客 7758

BORLAND公司开发的汇编编译器TASM 5.0.zip

BORLAND公司开发的汇编编译器TASM 5.0.zip

【Win32汇编】学习Win32汇编

本文主要是梳理了一下Win32的基础知识。因为有的内容和16位汇编基本一样,就没有详细说明,可以参考之前的汇编语言的博客。

Arcus 5188

TBsoft-GUI V0.20试用版

支持真正事件驱动程序设计的嵌入式GUI

Codex CLI 的多模型切换实战:如何在中转 API 环境下灵活选择最佳模型

本文详细介绍了在Codex CLI中实现多模型切换的实战技巧,重点解析了如何在中转API环境下灵活选择最佳AI模型。通过配置Node.js环境和智能路由策略,开发者可以根据任务类型、编程语言和成本考量,在GPT-5、Claude和DeepSeek等模型间高效切换,提升代码生成、审查和优化的效率。

weixin_29291185的博客 836

Win32汇编语言基础(1)

汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址.在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令,普遍地说,特定的汇编语言和特定的机器语言指令集是相互...

weixin_30950237的博客 629

SAP CO-PA数据传送避坑指南:销售开票与FI/MM记账的日常配置实操(含KEKF/KE4I/KEI2)

本文深入解析SAP CO-PA数据传送中的常见配置问题,特别是销售开票与FI/MM记账环节的实操避坑指南。通过KEKF/KE4I/KEI2等关键配置点的详细说明,帮助用户避免数据失真和重复记录,提升获利能力分析的准确性。文章结合实战案例,揭示官方文档未提及的'数据黑洞'形成机制,为SAP顾问提供实用的排雷手册。

weixin_26905487的博客 390

WIN32汇编语言程序设计——API和动态链接

最后有一个最重要的概念一定要牢记:动态链接库是被映射到其他应用程序的地址空间中执行的,它和应用程序可以看成是“一体”的,动态链接库可以使用应用程序的资源,它所拥有的资源也可以被应用程序使用,它的任何操作都是代表应用程序进行的,当动态链接库进行打开文件、分配内存和创建窗口等操作后,这些文件、内存和窗口都是为应用程序所拥有的。1. 在程序中声明函数。当PE文件被执行的时候,Windows装载器将文件装入内存并将导入表中登记的DLL文件一并装入,再根据DLL文件中的函数导出信息对被执行文件的IAT表进行修正。

evagenius的博客 1261

CentOS校园网Web Portal认证自动化实战

Web Portal认证是一种基于HTTP重定向与表单提交的强制网络准入机制,其原理是网关劫持未认证流量并跳转至登录页,验证通过后通过Cookie维持会话授权。该技术广泛应用于高校、机场、酒店等场景,核心价值在于细粒度访问控制与用户身份绑定。典型应用包括Linux命令行环境下的校园网接入、无GUI设备的自动联网、以及实验室集群的集中认证管理。本文聚焦CentOS系统,深入解析curl、cookie持久化、动态表单参数提取等关键技术环节,提供可调试、可复现、可工程化的完整认证流水线。

weixin_30522983的博客 264

视觉SLAM十四讲--第13讲 实践:设计SLAM系统(最详细的代码调试运行步骤)

最详细的代码调试运行避坑说明,也包含了我自己对代码的理解,如有理解错误的地方,欢迎指正交流。

记录和分享 1万+

Win32汇编:基础知识入门

汇编语言是所有程序设计语言中最古老的,它与计算机机器语言最为接近,通过汇编语言可以直接访问计算机的硬件,能够直接与CPU对话,可以说汇编语言是所有编程语言中语法格式最自由的,但自由的代价就是需要了解计算机体系结构和操作系统的大量细节,每编写一段程序都需要考虑各种硬件的状态,从而导致使用汇编写程序效率非常低.

微软技术分享 7603

告别社区5级:一个脚本搞定小米/红米BL解锁的账号绑定限制(附资源下载与避坑指南)

本文提供了一种绕过小米/红米设备Bootloader解锁社区等级限制的技术方案,适用于MIUI 12.5-14和HyperOS 1.0系统。通过自动化脚本临时修改系统组件,用户可快速完成账号绑定和设备解锁流程,附详细操作指南和常见问题解决方案。

weixin_27330481的博客 726

Win32汇编语言实战编写软件教程即将开始录制

Win32汇编语言实战编写软件教程即将开始录制 敬请关注!!

HUA的专栏 888

7、布尔网络的基础定义

本文介绍了布尔网络的基础定义及其在系统生物学中的应用。布尔网络是一种描述复杂系统动态行为的数学模型,由布尔变量和布尔函数组成,能够模拟生物系统中基因调控、信号传导和细胞代谢等过程。文章详细阐述了布尔网络的基本结构、动力学特征(如状态转移图和吸引子),以及其在生物建模中的重要价值,并探讨了优化和简化技术(如Backward Boolean Equivalence)如何提升其计算效率。

yhn45678901的博客 262

实战:RK3568 Android14 点亮 LVDS 屏幕

4组数据 (D0~D3) + 1组时钟 (CLK)。最大支持 1280x800 @ 60Hz。8组数据 (Even03, Odd03) + 2组时钟。支持 1080P 及以上。/ {/* 背光与电源 *//** 关键配置:数据格式映射* 可选值: "jeida-18", "jeida-24", "vesa-24"* 6位屏选 xx-18, 8位屏选 xx-24* 颜色不对(偏色/底片效果)就换 VESA <-> JEIDA*/

qq_33427070的博客 1165

Win32汇编语言教程(1)

一、引言 Win32应用程序一般使用C语言编程,但是在某些需要进行深层编程的情况下,例如Win32应用程序执行机制分析、病毒清除、加密解密等深层编程,或者对于某些速度要求较高的程序,需要使用汇编语言(甚至机器语言)直接编写Win32应用程序。Win32应用程序虽然和其他32

郁闷阳光的专栏 828

Autosar诊断实战系列23-NRC优先级解析

NRC分类,优先级判断逻辑及测试注意事项介绍。

initiallizer的博客 2617

汇编语言全接触-65.Win32汇编教程九

本篇的例子程序是一个复杂形状的窗口,窗口的形状是根据位图自动计算得到的,这也就是在我编写的小闹钟中使用的技术(大家可以到我的软件发布中下载一个看看),由于以前在网上看到的有关特殊形状窗口的例子最多就是画一个圆形,或者几个方块和椭圆结合的形状,没有一篇文章指出如何画出如“唐老鸭”这样一个造型的窗口。本文使用的算法可以自动根据位图的形状计算窗口形状。CombineRgn(hDest,hSource1,hSource2,CombineMode) - 合并区域。

qq_41237850的博客 969

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: C++ 控件之 CTree
xmlscript
博客等级 码龄25年 1粉丝 0原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值