summary: gcc,Visual C++C,Turbo混合编程

C语言和汇编混合编程

一、背景

系统控制软件采用混合编程的方式,即在C语言中嵌入汇编语句,充分发挥汇编语言和C语言各自的优势,实现整个系统的功能要求,达到系统指标要求

本段话,参考博客
TIPS:在编译过程汇中,汇编代码块是原封不动地送到汇编语言编译阶段的。
一、为什么会用到汇编?
1.为了提高速度和效率。不过这种情况很少了,现在C/C++编译器的优化很厉害了。
2.为了实现某些C语言中不具备、但为不同的机器所特有的功能。这是主要原因。
3.为了利用通用的汇编语言例程。也常会遇到。
二、何时使用汇编?
第一种情况是,绝对没有其他方法可以使用。
第二种情况出现在某个C语言程序的执行时间必须减少的时候。
三、如何嵌入汇编?

二、各种编译器中汇编嵌入方式

1)GNU GCC(个人常用)

  • 用到的关键字
    asm” 表示后面的代码为内嵌汇编,“asm”是“asm”的别名。
    volatile” 表示编译器不要优化代码,后面的指令保留原样,“volatile”是它的别名。
    括号里面是汇编指令。
  • 内嵌汇编语法如下:
__asm__(
 汇编语句模板:
 输出部分:
 输入部分:
 破坏描述部分);

//Tips:其实,下面的代码中asm前后各两条下划线(_)都省略都是可以的

//测试环境Dev-C++ 5.11(TDM-GCC 4.9.2)

#include<stdio.h>

int main()
{

    int a=10,b=3;

    printf("汇编处理前b=%d\n",b); 

    __asm__(
    "movl %1, %%eax;"
    "movl %%eax, %0;"
    :"=r"(b)          /*输出部*/
    :"r"(a)           /*输入部*/
    :"%eax"           /*修正部*/
       );

       printf("汇编处理后b=%d\n",b); 

    return 0;
 } 

代码解释:
1)这些汇编代码表示C语言里的“b=a;”。
2)里边r表示使用任意寄存器,%0、%1表示使用两个寄存器,一般只能%0~%9共十个操作数,按输入输出部变
量出现顺序进行映射。
3)寄存器用两个百分号,是因为使用了%0%1这些数字使百分号有了特殊意义,所以在操作数出现的寄存器必须用双百分表示。
4)修正部里边的%eax表示eax寄存器在汇编代码块执行过程中会被改写,在执行前要保护好,这是提交给编
译器决定的。

2)Visual C++(比如VS212)

  • 格式:
  • asm前面是两条下划线,后面的方括号内容表示分号可有可无。
格式1:
一组汇编语句
__asm { 汇编指令 } [ ; ]
格式2:
一条汇编语句
__asm 汇编指令 [ ; ]

格式一、一组汇编语句(个人常用)

//测试环境VS2012,文件名test.c
#include<stdio.h>

int main()
{

    int a=10,b=3;

    printf("汇编处理前b=%d\n",b); 

    __asm{
    mov  eax,a
    mov  b,eax
    mov  ebx,b
    mov  a,ebx
    }   

       printf("汇编处理后b=%d\n",b); 

    return 0;
 } 
#include <stdio.h>

 int power2( int num, int power )
 {
     __asm{
         mov eax, num ; Get first argument
         mov ecx, power ; Get second argument
         shl eax, cl ; EAX = EAX * ( 2 to the power of CL )
        }

 /* Return with result in EAX */
 }


 void main( void )
 {
    printf( "3 times 2 to the power of 5 is %d\n", power2( 3, 5) );
 }

格式二、单行汇编语句

#include<stdio.h>

int main()
{

    int a=10,b=3;

    printf("汇编处理前b=%d\n",b); 


    __asm mov  eax,a
    __asm mov  b,eax
    __asm mov  ebx,b
    __asm mov  a,ebx


       printf("汇编处理后b=%d\n",b); 

    return 0;
 } 

3)Turbo C(不学这个,但作为备案)

吐槽:
这个实在太古老了,但是有时为了遗留代码啥的。。。还是老老实实看吧

  • 使用预处理程序的伪指令#asm#endasm,#asm用来开始一个汇编程序块,而#endasm指令用于该块的结束。

格式1、一组汇编语句

mul(a,b)
int a,b;
{

 #asm
 mov ax,word ptr 8[bp]
 imul ax word ptr 10[bp]
 #endasm

}

格式2、单行汇编语句

mul(a,b)
int a,b;
{
 asm mov ax,word ptr 8[bp]
 asm imul ax word ptr 10[bp]
}

三、用途

gcc的汇编,可以用来进行汇编开栈
(比如在leetcode中)
PS:提升算法能力才是真正的提升,不要太依靠这些技巧。