在 C++中使用内联汇编(4)_C/C++语言_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

在 C++中使用内联汇编(4)

作者:黑客防线网安C/C++教程基地 来源:黑客防线网安C/C++教程基地 浏览次数:0

本篇关键词:汇编使用 NULL
黑客防线网安网讯:  注意:函数参数是从右向左压栈。   ?不能够访问C++中的类成员函数,但是可以访问extern "C"函数。   ?如果调用Windows API函数,则不需要自己清除堆栈,因为API的返回指令是RET n,会自动...
  注意:函数参数是从右向左压栈 
 ?不能够访问C++中的类成员函数但是可以访问extern "C"函数 
 ?如果调用Windows API函数则不需要自己清除堆栈,因为API的返回指令是RET n,会自动清除堆栈 
 ?比如下面的例子: 
 ???#include <windows.h> 
 ???char szAppName[] = "API Test"; 
 ???void main() 
 ???{ 
 ?????char szHello[] = "Hello, world!"; 
 ?????__asm 
 ?????{ 
 ???????PUSH??MB_OK or MB_ICONINformATION 
 ???????PUSH??OFFSET szAppName??; 全局变量用OFFSET 
 ???????LEA?? EAX, szHello????; 局部变量用LEA 
 ???????PUSH??EAX 
 ???????PUSH??0 
 ???????CALL??DWORD PTR [MessageBoxA]?? ; 注意这里,我费了好大周折才发现不是CALL MessageBoxA 
 ?????} 
 ???} 
 ?一般来说,在Visual C++中使用内联汇编是为了提高速度,因此这些函数调用尽可能用C/C++写。
八、一个例子 
 ?下面的例子是在VS.NET(即VC7)中C语言写的。先建一个工程,将下列代码放到工程中的.c文件中编译,无需作特别的设置,即可编译通过。
//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//预处理 
 ?#include <Windows.h> 
 ?////////////////////////////////////////////////////////////////////////////////////////////////////
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//全局变量 
 ?HWND g_hWnd; 
 ?HINSTANCE g_hInst; 
 ?TCHAR szTemp[1024]; 
 ?TCHAR szAppName[] = "CRC32 Sample"; 
 ?////////////////////////////////////////////////////////////////////////////////////////////////////
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//函数声明 
 ?DWORD GetCRC32(const BYTE *pbData, int nSize); 
 ?int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow); 
 ?LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
 ?////////////////////////////////////////////////////////////////////////////////////////////////////
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//主函数 
 ?int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) 
 ?{ 
 ???MSG msg; 
 ???WNDCLASSEX wndClassEx; 
 ???g_hInst = hInstance; 
 ???wndClassEx.cbSize = sizeof(WNDCLASSEX); 
 ???wndClassEx.style = CS_VREDRAW | CS_HREDRAW; 
 ???wndClassEx.lpfnWndProc = (WNDPROC) WindowProc; 
 ???wndClassEx.cbClsExtra = 0; 
 ???wndClassEx.cbWndExtra = 0; 
 ???wndClassEx.hInstance = g_hInst; 
 ???wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
 ???wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); 
 ???wndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW); 
 ???wndClassEx.lpszMenuName = NULL; 
 ???wndClassEx.lpszClassName = szAppName; 
 ???wndClassEx.hIconSm = NULL; 
 ???RegisterClassEx(&wndClassEx); 
 ???g_hWnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICK<I>FRame</I> | WS_MINIMIZEBOX, 
 ?????CW_USEDEFAULT, CW_USEDEFAULT, 300, 70, 
 ?????NULL, NULL, g_hInst, NULL); 
 ???ShowWindow(g_hWnd, iCmdShow); 
 ???UpdateWindow(g_hWnd); 
 ???while (GetMessage(&msg, NULL, 0, 0)) 
 ???{ 
 ?????TranslateMessage(&msg); 
 ?????DispatchMessage(&msg); 
 ???} 
 ???return ((int) msg.wParam); 
 ?} 
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//主窗口回调函数 
 ?LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
 ?{ 
 ???switch (uMsg) 
 ???{ 
 ???case WM_CREATE: 
 ?????CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL | WS_OVERLAPPED, 
 ???????7, 12, 220, 22, 
 ???????hWnd, (HMENU)1000, g_hInst, NULL); 
 ?????CreateWindowEx(0, "BUTTON", "&OK", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_OVERLAPPED | BS_FLAT, 
 ???????244, 12, 40, 20, 
 ???????hWnd, (HMENU)IDOK, g_hInst, NULL); 
 ?????break; 
 ???case WM_COMMAND: 
 ?????switch (LOWORD(wParam)) 
 ?????{ 
 ?????case IDOK: 
 ???????GetDlgItemText(g_hWnd, 1000, szTemp + 100, 800); 
 ???????wsprintf(szTemp, "当前文本框内的字符串的CRC32校验码是: 0x%lX", GetCRC32(szTemp + 100, (int)strlen(szTemp + 100))); 
 ???????MessageBox(g_hWnd, szTemp, szAppName, MB_OK|MB_ICONINformATION); 
 ?????} 
 ?????break; 
 ???case WM_DESTROY: 
 ?????PostQuitMessage(0); 
 ?????break; 
 ???default: 
 ?????return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 
 ???} 
 ???return (0); 
 ?} 
 ?////////////////////////////////////////////////////////////////////////////////////////////////////
 ?//////////////////////////////////////////////////////////////////////////////////////////////////// 
 ?//GetCRC32: 求字节流的CRC32校验码 
 ?//参数: 
 ?//???pbData: 指向字节流缓冲区首地址 
 ?//???nSize: 字节流长度 
 ?// 
 ?//返回值: 
 ?//???字节流的CRC32校验码 
 ?// 
 ?//这里使用查表法求CRC32校验码,这部分是参考老罗的文章《 矛与盾的较量(2)——CRC原理篇》该写的。 
 ?// 
 ?//下面使用内联汇编求CRC32校验码,充分使用了CPU中的寄存器,速度和方便性都是使用C/C++所不能比拟的 
 ?// 
 ?DWORD GetCRC32(const BYTE *pbData, int nSize) 
 ?{ 
 ???DWORD dwCRC32Table[256]; 
 ???__asm? //这片内联汇编是初始化CRC32表 
 ???{ 
 ?????MOV?? ECX, 256 
 ?_NextTable: 
 ?????LEA?? EAX, [ECX-1] 
 ?????PUSH??ECX 
 ?????MOV?? ECX, 8 
 ?_NextBit: 
 ?????SHR?? EAX, 1 
 ?????JNC?? _NotCarry 
 ?????XOR?? EAX, 0xEDB88320 
 ?_NotCarry: 
 ?????DEC?? ECX 
 ?????JNZ?? _NextBit 
 ?????POP?? ECX 
 ?????MOV?? [dwCRC32Table + ECX*4 - 4], EAX 
 ?????DEC?? ECX 
 ?????JNZ?? _NextTable 
 ???} 
 ???__asm? //下面是求CRC32校验码 
 ???{ 
 ?????MOV?? EAX, -1 
 ?????MOV?? EBX, pbData 
 ?????OR???EBX, EBX 
 ?????JZ???_Done 
 ?????MOV?? ECX, nSize 
 ?????OR???ECX, ECX 
 ?????JZ???_Done 
 ?_NextByte: 
 ?????MOV?? DL, [EBX] 
 ?????XOR?? DL, AL 
 ?????MOVZX? EDX, DL 
 ?????SHR?? EAX, 8 
 ?????XOR?? EAX, [dwCRC32Table + EDX*4] 
 ?????INC?? EBX 
 ?????LOOP??_NextByte 
 ?_Done: 
 ?????NOT?? EAX 
 ???} 
 ?} 
    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-15155-1.html
网站维护教程更新时间:2023-02-15 11:05:19  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer