`

C调用汇编

 
阅读更多
一、汇编语言的两种语法格式
 
Intel格式: 大多数DOS、Windows环境采用
AT&T格式:Unix和Linux系统采用(GCC编译器也采用AT&T)
 
详见附件《Linux 汇编器:对比 GAS 和 NASM》http://www.ibm.com/developerworks/cn/linux/l-gas-nasm.html#sidebar
 
二、C语言调用汇编程序
 
2.1 扩展内联汇编——C语言中嵌入汇编程序
 
基本内联汇编 不能 让汇编程序与C程序交互,形如:  __asm__("pushl %eax");
 
扩展内联汇编 可将C语言表达式的值作为参数输入,并可将汇编处理的结果返回,语法格式为:    
                            __asm__    __volatile__( "汇编指令" : 输出 : 输入 : 修改)
    注:扩展内联汇编的4个部分都不是必须的,如果省略后面3个部分则变成基本内联汇编。下面均介绍扩展内联汇编。
 
 
例1——基本语法
#include <stdio.h>
int main(){
 int i, j;
 scanf("%d%d", &i, &j);
 printf("i=%d, j=%d\n", i, j);
 
 //set j to i
 // __asm__ __volatile__(
 // "movl 8(%%esp), %0\n"
 // :"=a"(i)
 // );
 
 __asm__ __volatile__(
 "movl %1, %%eax; incl %%eax; movl %%eax, %0"
 :"=a"(i)
 :"r"(j)
 );
 printf("i=%d, j=%d\n", i, j);
 getch();
 return 0;
}
 
注释:
A. __asm__ 关键字定义一个内联汇编表达式,括号内是一条/多条汇编指令序列,多条则用"\n", "\n\t"或";"隔开
B. __volatile__关键字是一个可选项,如果包含了该关键字,则告诉编译器,对后面的内联汇编代码不能优化。通常,为了不让GCC的优化影响了内联汇编代码,最好使用该关键字
C. 本例中在"输入"和"输出"部分,占位符%0,%1按顺序分别表示C语言中的变量i和变量j
D. 在使用内联汇编机制时,%数字 表示 操作数占位符, %%eax 表示 寄存器(此时需要使用2个%)
E. 实际上,"汇编指令"、"输入"、"输出"都生成了汇编代码
 
例2——利用(扩展)内联汇编,得到寄存器内容
#include <stdio.h>
 
unsigned int getesp(){
 unsigned int i;
 __asm__ __volatile__(
 "movl %%esp, %0;"
 : "=r"(i)
 );
 return i;
}
 
unsigned int getebp(){
 unsigned int i;
 __asm__ __volatile__(
 "movl %%ebp, %0;"
 : "=r"(i)
 );
 return i;
}
 
int main(){
 printf("esp=0x%x\n", getesp());
 printf("ebp=0x%x\n", getebp());
 //getch();
 return 0;
}
 
(1) "汇编指令" :    指令中的占位符表示的操作数,总被作为long型(4字节,32bit),根据指令决定使用操作数的哪一部分。
                     %b1    使用低字节    %h1    使用高字节
                     %w1    使用低字
 
(2) 输出 :   格式为  "=限制字符"(C表达式), "=限制字符"(C表达式), ... ...
                限制字符可以用一个字母对寄存器进行约束,各字符的含义如下:
                    r : 使用一个通用寄存器,由GCC在通用寄存器中选取一个使用;
                    q : 同r
                    a : 使用寄存器%eax, %ax, %al
                    b : 使用寄存器%ebx, %bx, %bl
                    c : 使用寄存器%ecx, %cx, %cl
                    d : 使用寄存器%edx, %dx, %dl
                    D : 使用寄存器%edi, %di
                    S : 使用寄存器%esi, %si
                    f : 使用浮点寄存器
                    t : 使用第一个浮点寄存器
                    u : 使用第二个浮点寄存器
                    m : 使用系统支持的任何一种内存方式,不借助寄存器
                    g : 可以使用通用寄存器、内存、立即数等任何一种方式           
 
(3) 输入 
 
(4) 修改 : 有空再看
 
 
 
 
2.2 单独编写汇编程序,编译为目标文件,供C语言调用
 
A. 理解原理:熟悉C编译器的调用约定
 
C程序:从右向左压参数,压入放回地址;执行时,从栈顶取参数;结束时,函数返回值放入寄存器中返回(通常为%eax)
     注:esp是栈顶指针,为了方便在函数中均采用"栈顶+offset"来访问,但是却不直接使用esp,而是把esp赋予ebp来使用。
 
 
 
对应汇编程序:从中可以提炼出汇编函数的大致框架
 
 
B. 理解原理后自己都知道C语言是怎么调用汇编的.o程序的了
    按照上面框架,造一个汇编写的加法程序add.s,用gcc -c add.s就可以生成add.o
.globl add
 .type add, @function
add:
 pushl %ebp
 movl %esp, %ebp
 movl 12(%ebp), %eax
 addl 8(%ebp), %eax
 popl %ebp
 ret
 .size add, .-add
 .section .rodata
 
    在C程序中只需要生命函数原型即可,保证和汇编声明的函数名称一致
#include <stdio.h>
 
int add(int x, int y);
 
int main(){
 int i=1, j=2,n;
 n = add(i, j);
 printf("n=%d\n", n);
 
 return 0;
}
 
    好,这样就可以生成最终的可执行main.o了: gcc -o main.o add.o main.c
 
 
 
参考文档:
《C语言开发技术详解》(戴建华 等编著,电子工业出版社)
 


 

分享到:
评论

相关推荐

    c调用汇编实例 学习单片机c语言调用汇编

    c调用汇编实例 学习单片机c语言调用汇编 c调用汇编实例 学习单片机c语言调用汇编 c调用汇编实例 学习单片机c语言调用汇编 c调用汇编实例 学习单片机c语言调用汇编 ..................

    8051C语言调用汇编详细注释源代码

    这就涉及到C语言调用汇编的过程。 在8051C语言调用汇编的过程中,主要涉及以下几个关键知识点: 1. **函数调用约定**:C语言与汇编语言的交互主要通过函数调用来完成。在8051上,函数的参数传递和返回值的处理需要...

    利用C语言调用汇编子程序

    "利用C语言调用汇编子程序"是一个典型的混合编程案例,它结合了C语言的高效性和汇编语言的底层控制能力。C语言是一种高级编程语言,具有丰富的库支持和可移植性,而汇编语言则更接近机器代码,能直接对硬件进行操作...

    ARM中C语言调用汇编语言方法浅析[1].doc.doc

    本文将探讨如何在ARM中进行C语言调用汇编语言的方法。 首先,C语言中内嵌汇编语言是一种常见的方式,允许开发者利用汇编的灵活性和效率。在内嵌汇编中,需要注意以下几点: 1. 不能直接修改PC(程序计数器)寄存器...

    汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip

    汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯....

    C调用汇编实现20!

    "C调用汇编实现20!"这个标题暗示了一个具体的示例,其中C语言代码调用了一个汇编语言函数来计算20的阶乘。下面我们将深入探讨这个主题。 首先,C语言是一种高级编程语言,具有可移植性好、语法简洁等优点,但某些...

    51单片机C语言调用汇编子程序的简便方法_单片机_51单片机C语言调用汇编子程序的简便方法_

    在51单片机编程中,常常需要在C语言代码中调用汇编子程序,以便利用汇编语言的高效性和灵活性。本文将详细介绍一种简便方法来实现这种调用,帮助开发者更好地理解和应用混合编程技术。 首先,了解C语言与汇编语言...

    51单片机C语言调用汇编子程序的简便方法_单片机_51单片机C语言调用汇编子程序的简便方法_.zip

    本篇将详细探讨如何在51单片机上使用C语言调用汇编子程序,以实现高效且灵活的程序设计。 首先,理解C语言和汇编语言的区别至关重要。C语言是一种高级编程语言,具有易读性好、可移植性强的特点,但执行效率相比...

    CCS 中C语言程序调用线性汇编

    在CCS中,C语言调用汇编代码时,参数的传递遵循一定的规则: - 第1、3、5、7、9个参数通过A4、A6、A8、A10、A12寄存器传递。 - 第2、4、6、8、10个参数通过B4、B6、B8、B10、B12寄存器传递。 - 第10个及之后的参数...

    如何在C语言程序中调用汇编语言1

    总的来说,C语言调用汇编语言是为了结合两者的优点:C语言的高级抽象和易读性,以及汇编语言的效率和对硬件的直接控制。混合编程使得开发者能够在需要的时候深入底层,从而优化性能关键的部分,同时保持大部分代码的...

    C语言调用汇编的矩阵相乘

    本主题主要关注如何在DSP++5.0环境下,通过C语言调用汇编子程序来实现6x6矩阵相乘。 首先,我们需要理解矩阵相乘的基本概念。矩阵相乘是线性代数中的基础运算,两个矩阵A和B可以相乘,前提是A的列数等于B的行数。...

    调用汇编代码_me.rar_C 调用 汇编_VC 中嵌入汇编_VC 汇编_汇编语言

    1. **C语言调用汇编函数** 在C程序中调用汇编函数通常是通过定义一个外部汇编函数来实现的。首先,我们需要编写一个汇编源文件(例如:asm_func.asm),其中包含汇编函数的定义。然后,使用汇编器(如Microsoft的...

    利用C语言调用汇编子程序(blackfin BF535)

    利用C语言调用汇编子程序 其中5个输入参数和3个返回结果的汇编子程序调用 a) 输入整数a,b,c,d,e, b) 请计算a+b+c,a+c+d+e,a-b的值 c) 讨论a-b后算术状态标志寄存器的状态 (ASTAT) d) 请讨论输入整数数组e[3],f[3]...

    ARM中C语言调用汇编语言方法浅析.[文].pdf

    第三,C语言调用汇编语言函数时,需要在C文件中声明函数原型,并在汇编文件中使用`EXPORT`关键字标识函数。例如,`asm_strcpy`函数在C文件中声明为`extern`,在汇编文件中通过`EXPORT`导出,最后通过`mov pc, lr`...

    C语言中调用汇编程序

    总结起来,C语言调用汇编程序的过程涉及以下步骤: 1. 在C代码中声明汇编实现的函数。 2. 编写汇编代码实现该函数,遵循适当的函数调用约定。 3. 使用汇编器将汇编代码编译为对象文件。 4. 使用C编译器编译C源代码,...

    c语言调用汇编子程序

    本实验旨在探讨如何在C语言中调用汇编子程序,并处理输入参数和返回结果。C语言与汇编的混合编程使得我们可以利用C语言的易读性和汇编的高效性,以解决复杂的问题。 实验的目的是编写一个C语言程序,它调用一个汇编...

    单片机汇编语言和C语言混合调用资料及实例

    而在C代码中,可以设置中断向量,使得中断发生时调用汇编写的中断服务程序。 6. **性能优化**:对于性能敏感的部分,如循环或关键算法,可以使用内联汇编在C代码中插入,以提高效率。同时,通过分析汇编代码,找出...

    c语言调用汇编的方法

    总的来说,C语言调用汇编涉及到以下几个关键步骤: 1. 在C文件中声明汇编函数。 2. 编写汇编代码,处理参数和返回值。 3. 使用适当的编译器和链接器选项将C和汇编文件编译和链接在一起。 4. 在运行时,C程序可以通过...

    在C语言函数中调用汇编语言程序实现字符串的拷贝

    然而,在某些特定情况下,如优化性能或理解底层操作,我们可能需要直接调用汇编语言程序来实现这一功能。在这个主题中,我们将探讨如何在C语言函数中嵌入ARM汇编代码,以实现字符串的拷贝。 首先,我们要了解ARM...

    C语言函数调用汇编语言函数[归纳].pdf

    C语言函数调用汇编语言函数知识点总结 C语言函数调用汇编语言函数是软件开发中的一种常见技术。本文将对C语言函数调用汇编语言函数进行总结,详细介绍相关知识点。 一、C语言函数调用汇编语言函数的定义 C语言...

Global site tag (gtag.js) - Google Analytics