⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn技术中心 在visual c++中使用内联汇编.htm

📁 vc和汇编的混合编程
💻 HTM
📖 第 1 页 / 共 4 页
字号:
            &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV EBX, OFFSET 
            hal <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV ECX, 
            [EBX]hal.same_name ; 必须使用 'hal' <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp;MOV ESI, [EBX].weasel &nbsp; &nbsp; &nbsp; ; 可以省略 'hal' 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;} <BR><BR>&nbsp; 
            &nbsp;注意,省略了变量名仅仅是为了写代码的方便,生成的汇编指令的还是一样的。 <BR><BR>&nbsp; 
            &nbsp;可以不受限制地访问C++成员变量,但是不能调用C++的成员函数。 <BR><BR><BR><BR><FONT 
            color=#ff8c00>五、寄存器使用</FONT> <BR><BR>&nbsp; 
            &nbsp;一般来说,在__asm块开始的时候,寄存器是空的,不能在两个__asm之间保存寄存器的值。(这是MSDN上说的,我在实际使用时发现,好像并不是这样。不过它是说"一般",我是特殊:)) 
            <BR><BR>&nbsp; 
            &nbsp;如果一个函数被声明成了__fastcall,则其参数将放在寄存器中,这将给寄存器的管理带来问题。所以,如果要将一个函数声明成__fastcall,必须保存ECX寄存器。为了避免以上的冲突,在声明为__fastcall的函数中不要有__asm块。如果用了/Gr编译选项(它全局的变成__fastcall),将每个函数声明成__cdecl或者__stdcall,这个属性告诉编译器用传统的C方法。 
            <BR><BR>&nbsp; 
            &nbsp;如果使用EAX、EBX、ECX、EDX、ESI和EDI寄存器,你不需要保存它;但如果你用到了DS、 
            SS、SP、BP和标志寄存器,那就应该PUSH保存这些寄存器。 <BR><BR>&nbsp; 
            &nbsp;如果程序中改变了用于STD和CLD的方向标志,你必须将其恢复到原来的值。 <BR><BR><BR><BR><BR><FONT 
            color=#ff8c00>六、转跳</FONT> <BR><BR>&nbsp; 
            &nbsp;可以在C里面使用goto调到__asm块中的标号处,也可以在__asm块中转跳到__asm块里面和外面的标号处。__asm块内的标号是不区分大小写的(指令、指示符等也是不区分大小写的)。例: 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;void func() <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;goto C_Dest; &nbsp; &nbsp;/* 合法 */ <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto c_dest; &nbsp; &nbsp;/* 错误 */ 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto 
            A_Dest; &nbsp; &nbsp;/* 合法 */ <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;goto a_dest; &nbsp; &nbsp;/* 合法 */ 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__asm 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;JMP C_Dest &nbsp;; 合法 <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JMP 
            c_dest &nbsp;; MSDN上说合法,但是我在VS.NET中编译,认为这样不合法 <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;JMP A_Dest &nbsp;; 合法 <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JMP a_dest &nbsp;; 
            合法 <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;a_dest: &nbsp; &nbsp; ; __asm 
            标号 <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;C_Dest: &nbsp; &nbsp; /* C的标号 */ 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;return; <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;} <BR><BR><BR>&nbsp; 
            &nbsp;不要使用函数名称当作标号,否则将使其跳到函数执行而不是标号处。如下所示: <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;; 错误: 使用函数名作为标号 <BR>&nbsp; &nbsp; &nbsp; &nbsp;JNE exit 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;. <BR>&nbsp; &nbsp; &nbsp; &nbsp;. 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;. <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;exit: <BR>&nbsp; &nbsp; &nbsp; &nbsp;; 下面是更多的ASM代码 
            <BR><BR><BR>&nbsp; &nbsp;美元符号$用于指定当前位置,如下所用,常用于条件跳转: <BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;JNE $+5 ; 下面这条指令的长度是5个字节 <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;JMP farlabel <BR>&nbsp; &nbsp; &nbsp; &nbsp;;$+5,跳到了这里 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;. <BR>&nbsp; &nbsp; &nbsp; &nbsp;. 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;. <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;farlabel: <BR><BR><BR><BR><FONT color=#ff8c00>七、调用函数</FONT> 
            <BR><BR>&nbsp; &nbsp;内联汇编调用C/C++函数必须自己清除堆栈,下面是一个调用C/C++函数例子: 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;#include &lt;stdio.h&gt; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;char szformat[] = "%s %s\n"; 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;char szHello[] = "Hello"; <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;char szWorld[] = " world"; <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;void main() <BR>&nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__asm <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX, OFFSET szWorld <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EAX 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV 
            &nbsp; &nbsp; EAX, OFFSET szHello <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;EAX <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX, 
            OFFSET szformat <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;PUSH &nbsp; &nbsp;EAX <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;CALL &nbsp; &nbsp;printf <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//内联汇编调用C函数必须自己清除堆栈 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;//用不使用的EBX寄存器清除堆栈,或ADD ESP, 12 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EBX <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POP &nbsp; &nbsp; EBX 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POP 
            &nbsp; &nbsp; EBX <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;} <BR><BR>&nbsp; 
            &nbsp;注意:函数参数是从右向左压栈。 <BR><BR>&nbsp; 
            &nbsp;不能够访问C++中的类成员函数,但是可以访问extern "C"函数。 <BR><BR>&nbsp; 
            &nbsp;如果调用Windows API函数,则不需要自己清除堆栈,因为API的返回指令是RET n,会自动清除堆栈 
            <BR><BR>&nbsp; &nbsp;比如下面的例子: <BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;#include &lt;windows.h&gt; <BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;char szAppName[] = "API Test"; <BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;void main() <BR>&nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;char szHello[] = "Hello, world!"; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__asm <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;MB_OK OR 
            MB_ICONINformATION <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp;PUSH &nbsp; &nbsp;OFFSET szAppName &nbsp; &nbsp;; 
            全局变量用OFFSET <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;LEA &nbsp; &nbsp; EAX, szHello &nbsp; &nbsp; &nbsp; &nbsp;; 
            局部变量用LEA <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;PUSH &nbsp; &nbsp;EAX <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;PUSH &nbsp; &nbsp;0 <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CALL &nbsp; &nbsp;DWORD PTR 
            [MessageBoxA] &nbsp; &nbsp; ; 注意这里,我费了好大周折才发现不是CALL MessageBoxA 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;} <BR><BR>&nbsp; &nbsp;一般来说,在Visual 
            C++中使用内联汇编是为了提高速度,因此这些函数调用尽可能用C/C++写。 <BR><BR><BR><BR><FONT 
            color=#ff8c00>八、一个例子</FONT> <BR><BR>&nbsp; 
            &nbsp;下面的例子是在VS.NET(即VC7)中C语言写的。先建一个工程,将下列代码放到工程中的.c文件中编译,无需作特别的设置,即可编译通过。 
            <BR><BR><FONT color=#888888>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//预处理 <BR>&nbsp; &nbsp;#include &lt;Windows.h&gt; 
            <BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR><BR><BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//全局变量 <BR>&nbsp; &nbsp;HWND g_hWnd; <BR>&nbsp; 
            &nbsp;HINSTANCE g_hInst; <BR><BR>&nbsp; &nbsp;TCHAR szTemp[1024]; 
            <BR><BR>&nbsp; &nbsp;TCHAR szAppName[] = "CRC32 Sample"; <BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR><BR><BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//函数声明 <BR>&nbsp; &nbsp;DWORD GetCRC32(const BYTE 
            *pbData, int nSize); <BR>&nbsp; &nbsp;int WINAPI WinMain(HINSTANCE 
            hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow); 
            <BR>&nbsp; &nbsp;LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, 
            WPARAM wParam, LPARAM lParam); <BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR><BR><BR><BR><BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//主函数 <BR>&nbsp; &nbsp;int WINAPI WinMain(HINSTANCE 
            hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) 
            <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp;MSG msg; 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;WNDCLASSEX wndClassEx; <BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;g_hInst = hInstance; <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;wndClassEx.cbSize = sizeof(WNDCLASSEX); <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;wndClassEx.style = CS_VREDRAW | CS_HREDRAW; 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.lpfnWndProc = (WNDPROC) 
            WindowProc; <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.cbClsExtra = 
            0; <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.cbWndExtra = 0; 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.hInstance = g_hInst; 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.hIcon = LoadIcon(NULL, 
            IDI_APPLICATION); <BR>&nbsp; &nbsp; &nbsp; &nbsp;wndClassEx.hCursor 
            = LoadCursor(NULL, IDC_ARROW); <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp;wndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW); <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;wndClassEx.lpszMenuName = NULL; <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;wndClassEx.lpszClassName = szAppName; <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;wndClassEx.hIconSm = NULL; <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;RegisterClassEx(&amp;wndClassEx); <BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;g_hWnd = CreateWindowEx(0, szAppName, szAppName, 
            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | 
            WS_MINIMIZEBOX, <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;CW_USEDEFAULT, CW_USEDEFAULT, 300, 70, <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;NULL, NULL, g_hInst, NULL); 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;ShowWindow(g_hWnd, iCmdShow); 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;UpdateWindow(g_hWnd); <BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;while (GetMessage(&amp;msg, NULL, 0, 0)) 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp;TranslateMessage(&amp;msg); <BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;DispatchMessage(&amp;msg); <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp;} <BR>&nbsp; &nbsp; &nbsp; &nbsp;return ((int) 
            msg.wParam); <BR>&nbsp; &nbsp;} <BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR><BR><BR><BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//主窗口回调函数 <BR>&nbsp; &nbsp;LRESULT CALLBACK 
            WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
            <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp;switch (uMsg) 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp;case 
            WM_CREATE: <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | 
            WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL | 
            ES_NOHIDESEL | WS_OVERLAPPED, <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;7, 12, 220, 22, <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;hWnd, (HMENU)1000, g_hInst, NULL); 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CreateWindowEx(0, 
            "BUTTON", "&amp;OK", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | 
            WS_OVERLAPPED | BS_FLAT, <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;244, 12, 40, 20, <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;hWnd, (HMENU)IDOK, g_hInst, NULL); 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;case WM_COMMAND: <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;switch (LOWORD(wParam)) <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp;case IDOK: <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp;GetDlgItemText(g_hWnd, 1000, szTemp + 100, 800); 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;wsprintf(szTemp, "当前文本框内的字符串的CRC32校验码是: 0x%lX", 
            GetCRC32(szTemp + 100, (int)strlen(szTemp + 100))); <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(g_hWnd, 
            szTemp, szAppName, MB_OK|MB_ICONINformATION); <BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp;} <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;break; <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;case WM_DESTROY: 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PostQuitMessage(0); 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break; <BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;default: <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp;return (DefWindowProc(hWnd, uMsg, wParam, lParam)); <BR>&nbsp; 
            &nbsp; &nbsp; &nbsp;} <BR>&nbsp; &nbsp; &nbsp; &nbsp;return (0); 
            <BR>&nbsp; &nbsp;} <BR>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR><BR><BR><BR></FONT><BR><FONT color=#32cd32>&nbsp; 
            &nbsp;//////////////////////////////////////////////////////////////////////////////////////////////////// 
            <BR>&nbsp; &nbsp;//GetCRC32: 求字节流的CRC32校验码 <BR>&nbsp; &nbsp;//参数: 
            <BR>&nbsp; &nbsp;// &nbsp; &nbsp; &nbsp;pbData: 指向字节流缓冲区首地址 
            <BR>&nbsp; &nbsp;// &nbsp; &nbsp; &nbsp;nSize: 字节流长度 <BR>&nbsp; 
            &nbsp;// <BR>&nbsp; &nbsp;//返回值: <BR>&nbsp; &nbsp;// &nbsp; &nbsp; 
            &nbsp;字节流的CRC32校验码 <BR>&nbsp; &nbsp;// <BR>&nbsp; 
            &nbsp;//这里使用查表法求CRC32校验码,这部分是参考老罗的文章《 矛与盾的较量(2)——CRC原理篇》该写的。 
            <BR>&nbsp; &nbsp;//原文的具体内容请参看: <A 
            href="http://asp.7i24.com/netcool/laoluo/articles/show_article.asp?Article_ID=15" 
            target=_blank>http://asp.7i24.com/netcool/laoluo/articles/show_article.asp?Article_ID=15</A> 
            <BR>&nbsp; &nbsp;// <BR>&nbsp; 
            &nbsp;//下面使用内联汇编求CRC32校验码,充分使用了CPU中的寄存器,速度和方便性都是使用C/C++所不能比拟的 
            <BR>&nbsp; &nbsp;//</FONT> <BR><FONT color=#6495ed>&nbsp; 
            &nbsp;DWORD GetCRC32(const BYTE *pbData, int nSize) <BR>&nbsp; 
            &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp;DWORD dwCRC32Table[256]; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp;__asm &nbsp; //这片内联汇编是初始化CRC32表 
            <BR>&nbsp; &nbsp; &nbsp; &nbsp;{ <BR>&nbsp; &nbsp; &nbsp; &nbsp; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -