Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > 汇编语言 > C++与汇编的混合编程
【标  题】:C++与汇编的混合编程
【关键字】:C++
【来  源】:http://blog.csdn.net/yegong168/archive/2007/04/16/1566060.aspx

C++与汇编的混合编程

Your Ad Here

C++与汇编的混合编程 

一个人不应该用猜的方式,或是等待某大师的宣判,才确定"何时提供一个copy construtor而何时不需要"。--- Stanley B.Lippman

之所以用到汇编,一是关键程序需要极高的效率,需要用汇编来优化;二是有些功能高级语言是做不到的。

混合汇编一般有两种形式:内置汇编和外置汇编。

内置汇编比较简单,主要是因为
(1)一般不需要考虑寄存器的保存与恢复
(2)不需要考虑函数的命名问题和调用规则
(3)可以在程序中直接访问C/C++的局部变量和全局变量,访问C++中的成员变量也是比较容易的
其不足是失去了模块性

外置汇编刚好反过来了。

下面的程序是我最近作的一个小东西里的一个模块。采用外置汇编,nasm格式;C++用的是VC6。

为了简单起见,我去掉了头文件。所以一共两个文件:(1)cpu.cpp;(2)cpuAsm.asm

(1)cpu.cpp:

#include <iostream>

class cpu;

extern 
"C" void _stdcall setCPUInfo_via_asm(cpu* cpu);

class cpu  
{
    
//friend std::ostream& operator<<(std::ostream& out, const cpu& cpu);
public:
    cpu();
    
int getCUPID() const;           // support cupid directive ? 1 : 0;
    int getFPU() const;             // support FPU ? 1 : 0;
    int getMMX() const;             // support MMX ? 1 : 0;
    int get3DNow() const;           // support 3DNow ? 1 : 0;
    const char* getOEM() const;     // OEM
    const char* getSpec() const;    // SPEC
private:    
    
int m_iCPUID;               
    
int m_iFPU;                 
    
int m_iMMX;                 
    
int m_i3DNow;                
    
char m_szOEM[16];
    
char m_szSpecification[52];
}
;

cpu::cpu(): m_iCPUID(
0), m_iFPU(0), m_iMMX(0), m_i3DNow(0)
{
    
/* set string null, in fact this will be done in function setCPUInfo_via_asm(),
     for more detail, see .nocpuid in function setCPUInfo_via_asm() 
*/

    
/*m_szOEM[0] = 0;
    m_szSpecification[0] = 0;
*/

    
    setCPUInfo_via_asm(
this);
}


int cpu::getCUPID() const
{
    
return m_iCPUID;
}


int cpu::getFPU() const
{
    
return m_iFPU;
}


int cpu::getMMX() const
{
    
return m_iMMX;
}


int cpu::get3DNow() const
{
    
return m_i3DNow;
}


const char* cpu::getOEM() const
{
    
return m_szOEM;
}


const char* cpu::getSpec() const
{
    
return m_szSpecification;
}


std::ostream
& operator<<(std::ostream& out, const cpu& cpu)
{
    out 
<< "Support CPUID : " << cpu.getCUPID()  << std::endl;
    out 
<< "Support FPU   : " << cpu.getFPU()    << std::endl;
    out 
<< "Support MMX   : " << cpu.getMMX()    << std::endl;
    out 
<< "Support 3DNow : " << cpu.get3DNow()  << std::endl;
    out 
<< "O E M         : " << cpu.getOEM()    << std::endl;
    out 
<< "Specification : " << cpu.getSpec()   << std::endl;

    
return out;
}


int main()
{
    cpu currentcpu;
    std::cout 
<< currentcpu;
    
return 0;
}
             

(2)cpuAsm.asm:

[bits 32]
[section .text 
class=code use32]

void _stdcall setCPUInfo_via_asm(BMCPU* bmcpu);
global _setCPUInfo_via_asm@
4
_setCPUInfo_via_asm@
4:
;
-------------------------------------------------
    push ebp                  ; save ebp
    mov ebp, esp              ; esp
->ebp
    
    push ebx                  ; save ebx, esi, edi
    push esi
    push edi
;
-------------------------------------------------
    
    mov ebx, [ebp
+8]          ; R[ebx] = bmcpu, then
    ; M[ebx] 
= int m_iCPUID
    ; M[ebx
+4= int m_iFPU
    ; M[ebx
+8= int m_iMMX
    ; M[ebx
+12= int m_i3DNow
    ; M[ebx
+16= char m_szOEM[16]
    ; M[ebx
+32= char m_szSpecification[52];
    
    ; set 
int m_iFPU
.setfpu_start:
    fninit
    mov eax, 
0x5a5a
    fnstsw ax
    cmp eax, 
0
    jne .nofpu
    mov [ebx
+4], dword 1      ; int m_iFPU = 1;
    jmp .setfpu_end
.nofpu:
    mov [ebx
+4], dword 0      ; int m_iFPU = 0;
.setfpu_end:
    
    ; set 
int m_iCPUID
.setcpuid_start:
    pushfd                    ; get extended flags 
    pop eax;
    mov ecx, eax              ; save current flags
    xor eax, 
0x200000         ; toggle bit 21
    push eax                  ; put 
new flags on stack
    popfd                     ; flags updated now in flags
    pushfd                    ; get extended flags
    pop eax
    xor eax, ecx              ; 
if bit 21 r/w then supports cpuid
    jz .nocpuid
    mov [ebx], dword 
1        ; int m_iCPUID = 1;
    jmp .setcpuid_end
.nocpuid:
    mov [ebx], dword 
0        ; int m_iCPUID = 0;
    
    mov [ebx
+8], dword 0      ; int m_iMMX = 0;
    mov [ebx
+12], dword 0     ; int m_i3DNow = 0;
    mov [ebx
+16], byte 0      ; set char m_szOEM[16null string
    mov [ebx
+32], byte 0      ; set char m_szSpecification[52null string
    
    jmp .returnAsm            ; cupid not supported, then 
return
.setcpuid_end:

    ; set 
int m_iMMX
.setmmx_start:
    mov esi, ebx              ; save ebx to esi
    
    mov eax, 
1
    cpuid
    and edx, 
0x800000
    jz .nommx
    mov [esi
+8], dword 1      ; int m_iMMX = 1;
    jmp .setmmx_end
.nommx:
    mov [esi
+8], dword 0      ; int m_iMMX = 0;
.setmmx_end:
    mov ebx, esi              ; restore ebx from esi
    
    ; set 
int m_i3DNow
.set3dnow_start:
    mov esi, ebx              ; save ebx to esi
    
    mov eax, 
0x80000001
    cpuid
    and edx, 
0x80000000
    jz .no3dnow
    mov [esi
+12], dword 1     ; int m_i3DNow = 1;
    jmp .set3dnow_end
.no3dnow:
    mov [esi
+12], dword 0     ; int m_i3DNow = 0;
.set3dnow_end:
    mov ebx, esi              ; restore ebx from esi
    
    ; set 
char m_szOEM[16]
.setoem_start:
    mov esi, ebx              ; save ebx to esi
     
    mov eax, 
0
    cpuid
    mov [esi
+16], ebx         ; char m_szOEM[0-3= ebx;
    mov [esi
+20], edx         ; char m_szOEM[4-7= edx;
    mov [esi
+24], ecx         ; char m_szOEM[8-11= edx;
    mov [esi
+28], byte 0      ; char m_szOEM[12= 0;
    
    mov ebx, esi              ; restore ebx from esi
.setoem_end:

    ; set 
char char m_szSpecification[52]
.setspec_start:
    mov esi, ebx              ; save ebx to esi
    
    mov eax, 
0x80000002
    cpuid
    mov [esi
+32], eax         ; char m_szSpecification[0-3= eax;
    mov [esi
+36], ebx         ; char m_szSpecification[4-7= ebx;
    mov [esi
+40], ecx         ; char m_szSpecification[8-11= ecx;
    mov [esi
+44], edx         ; char m_szSpecification[12-15= edx;
    
    mov eax, 
0x80000003
    cpuid
    mov [esi
+48], eax
    mov [esi
+52], ebx
    mov [esi
+56], ecx
    mov [esi
+60], edx
    
    mov eax, 
0x80000004
    cpuid
    mov [esi
+64], eax
    mov [esi
+68], ebx
    mov [esi
+72], ecx
    mov [esi
+76], edx
    
    mov [esi
+77], byte 0      ; char m_szSpecification[48= 0;
    
    mov ebx, esi              ; restore ebx from esi
.setspec_end:

;
-------------------------------------------------
.returnAsm:    
    pop edi                   ; restore ebx, esi, edi
    pop esi
    pop ebx
    
    mov esp, ebp              ; restore ebp
    pop ebp
    ret 
4

运行结果:

在自己机器上:

Support CPUID : 1
Support FPU   : 1
Support MMX   : 1
Support 3DNow : 0
O E M         : GenuineIntel
Specification :               Intel(R) Pentium(R) 4 CPU 2.80G

在一台CPU为AMD的机器上:

Support CPUID : 1
Support FPU   : 1
Support MMX   : 1
Support 3DNow : 1
O E M         : AuthenticAMD
Specification : AMD Athlon(tm) XP 1700+

 

几点小结:

(1)环境:把nasmw拷贝到VC的bin下,建好工程文件后,右键单击cpuAsm.asm,Settings->Custom Build中Commands填入nasmw $(InputName).asm  -f win32 -o $(IntDir)\$(InputName).obj,Outputs一栏填入$(IntDir)\$(InputName).obj。如果工程的文件分布复杂一点,Commands是要根据需要作一点变动的。^_^。

(2)C++与汇编,一是函数的命名(C++和C的函数命名是不同的,考虑到可移植性,这里仍然用C函数命名)和函数的调用规则是要注意的。例如stdcall是要自己来进行参数退栈的,用ret XXX 来进行,这也是_setCPUInfo_via_asm@4为什么@符号带上一个数字的原因。二是变量访问的问题,牵扯到c++的内存模型以及内存对齐等一些问题,因而不太确定的情况下需要试验,而且一般尽量保证4字节对齐会使问题简化很多。这也是在cpu.cpp把本应该是bool类型的变量设置成int类型,字符数组的大小设置成4×的原因。

^_^,就这么多。

 
世界500强著名芯片公司上海招聘system tools:【上一篇】
该死的81.4:【下一篇】
【相关文章】
  • 从JAVA到C++ 语法结构的区别 [转]
  • 对刚刚涉足开发领域的朋友谈谈C++比C#高级的想法
  • 高质量C/C++编程九(每日一帖)
  • 返回内部静态成员 熟练C/C++(一)
  • C++主题——Template Method(模板方法)模式
  • Effective C++读书笔记之在资源管理类中小心coping行为
  • C++主题——转换函数
  • DevC++下工程手段:运用栈对迷宫问题的详细求解(经典方法)
  • 高质量C/C++编程八(每日一帖)
  • 【随机文章】
  • static辨析
  • MSN Search加入中文显示
  • 子类继承抽象类,必须重写其所有方法,抽象类中的抽象方法可以重载
  • 克罗拉多大学物理系一些有趣的Applet
  • JNI处理中文的编码转换问题
  • 关系数据库
  • VBScript 语法错误
  • 个人推广联盟 : 个人推广联盟-无需有网站,1000积分=60元! √
  • AS-2000访问服务器
  • 11.1.7 The bool type
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.