在不同环境下的C程序中嵌入汇编

作者在 2009-03-31 16:03:01 发布以下内容

       相信大家学C学汇编的时候老师都提到过,可以在C中嵌入汇编代码,然而,由于课时有限,很少有老师会深入讲述。当我们要在C中嵌入汇编的时候,上网搜索,很可能会发现按照网上说的方法去做却行不通。为啥呢?原来,对于不同的汇编器,汇编语言的格式不同,而在C中嵌入汇编的形式也不同。现在你可以体会到为什么在VC写的程序linux编译不了,linux下写的C程序windows下也经常编译不了,而老师却说C的可移植性好了吧。

       为了尽量简单,我只对一个加法做转换。先看C程序:

 

#include <stdio.h>

 

int main()

{

       int a=4 , b = 5, c=0;

      

       c = a + b;

      

       printf("%d + %d = %d\n", a, b, c); 

       return 0;

}

 

       首先,我们来看看tc/wintc是怎么嵌入的。

 

/****************************************/

/* tasm3.0(tc/wintc)                                         */

/* 格式:asm asm_code                                  */

/*                                                                   */

/* 其他:                                                       */

/* 1.仅支持16位汇编                                      */

/* 2.变量名优先访问局部变量                         */

/* 如下面的程序输出:4 + 5 = 9                     */

/****************************************/

 

#include <stdio.h>

 

int a=3, b=5;

 

int main()

{

       int a=4, c=0;

 

       asm push        ax

       asm mov        ax,a

       asm add         ax,b

       asm mov        c,ax

       asm pop         ax

 

       printf("%d + %d = %d\n", a, b, c);

       getch();

       return 0;

}

 

       相信大多数人初学C,老师推荐的都是TC,而自己却不屑于TC那简陋的编辑界面,找来notepadUEwintc甚至是VC来编写源程序。TC2.0/wintc使用的是Borland公司的tasm3.0,可以看到每个语句都要加个asm,极其不方便。我们再来看linux中是怎么实现的。

 

/****************************************/

/* g++                                                             */

/* 格式:__asm__("asm_code");                      */

/*                                                                   */

/* 其他:                                                       */

/* 1.直接用变量名来访问全局变量                  */

/* 2.%加寄存器来访问寄存器                      */

/* 3.指令中ops在前,opd在后                         */

/* 4.汇编语句用\n分开,可用多个引号           */   

/****************************************/

 

#include <stdio.h>

 

int a=4, b=5, c=0;

int main()

{

       __asm__

       (

"push      %eax      \n"

"mov       a,%eax    \n"

"add       b,%eax    \n"

"mov      %eax,c    \n"

"pop        %eax      \n"

       );

 

       printf("%d + %d = %d\n", a, b, c); 

       return 0;

}

 

       linux中好像更麻烦,语法跟我们学的X86汇编都有些不同哦。在windows下,有模拟linux的有cygwin/mingw,嵌入汇编的格式也和linux差不多,但还是有一点小差别:

 

/****************************************/

/* cygwin/mingw(cfree默认编译器)                 */

/* 格式:__asm__(asm_code);                         */

/*                                                                   */

/* 其他:                                                        */

/* 1.用下划线加变量名来访问全局变量           */

/* 2.%加寄存器来访问寄存器                      */

/* 3.指令中ops在前,opd在后                         */

/* 4.汇编语句用\n分开,可用多个引号           */   

/****************************************/

 

#include <stdio.h>

 

int a=4, b=5, c=0;

int main()

{

       __asm__

       (

"push      %eax      \n"

"mov       _a,%eax  \n"

"add       _b,%eax  \n"

"mov      %eax,_c  \n"

"pop        %eax      \n"

       );

 

       printf("%d + %d = %d\n", a, b, c); 

       return 0;

}

 

       windows还是最受欢迎的操作系统,财大气粗的M$给我们提供了很好的VS开发环境,M$的汇编器MASM也是很非常的好。我们来看看在VC/VS2005/VS2008中编写C时是怎么嵌入汇编的。

 

/****************************************/

/* vc6/vs2005/vs2008(masm)                           */

/* 格式:__asm{asm_code};                           */

/*                                                                   */   

/* 其他:                                                       */

/* 1.变量名优先访问局部变量                         */

/* 如下面的程序输出:4 + 5 = 9                     */

/****************************************/

 

#include <stdio.h>

 

int a=3, b=5;

int main()

{

       int a=4, c=0;

       __asm

       {

              push        eax

              mov        eax,a

              add         eax,b

              mov        c,eax

              pop         eax

       };

 

       printf("%d + %d = %d\n", a, b, c);

       system("pause");

       return 0;

}

 

       是不是感觉简洁多了呢?

 

       对于局部变量和全局变量的访问。不同的环境下嵌入的汇编代码有所不同。tasmmasm的访问规则和C程序相同,都是局域变量优先。而linuxcygwin/mingw中,只可以访问全局变量。现在有两个问题,tasmmasm中,如果有局域变量和全局变量相同,那怎样才可以访问全局变量?在linux中,是否真的无法访问局域变量,还是要用其他格式?在这里请教一下大家^_^

win32汇编 | 阅读 3065 次
文章评论,共0条
游客请输入验证码

Eru
浏览3065次
文章归档
最新评论