一、汇编语言的两种语法格式
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语言调用汇编的过程。 在8051C语言调用汇编的过程中,主要涉及以下几个关键知识点: 1. **函数调用约定**:C语言与汇编语言的交互主要通过函数调用来完成。在8051上,函数的参数传递和返回值的处理需要...
"利用C语言调用汇编子程序"是一个典型的混合编程案例,它结合了C语言的高效性和汇编语言的底层控制能力。C语言是一种高级编程语言,具有丰富的库支持和可移植性,而汇编语言则更接近机器代码,能直接对硬件进行操作...
本文将探讨如何在ARM中进行C语言调用汇编语言的方法。 首先,C语言中内嵌汇编语言是一种常见的方式,允许开发者利用汇编的灵活性和效率。在内嵌汇编中,需要注意以下几点: 1. 不能直接修改PC(程序计数器)寄存器...
汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯....
"C调用汇编实现20!"这个标题暗示了一个具体的示例,其中C语言代码调用了一个汇编语言函数来计算20的阶乘。下面我们将深入探讨这个主题。 首先,C语言是一种高级编程语言,具有可移植性好、语法简洁等优点,但某些...
在51单片机编程中,常常需要在C语言代码中调用汇编子程序,以便利用汇编语言的高效性和灵活性。本文将详细介绍一种简便方法来实现这种调用,帮助开发者更好地理解和应用混合编程技术。 首先,了解C语言与汇编语言...
本篇将详细探讨如何在51单片机上使用C语言调用汇编子程序,以实现高效且灵活的程序设计。 首先,理解C语言和汇编语言的区别至关重要。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语言调用汇编语言是为了结合两者的优点:C语言的高级抽象和易读性,以及汇编语言的效率和对硬件的直接控制。混合编程使得开发者能够在需要的时候深入底层,从而优化性能关键的部分,同时保持大部分代码的...
本主题主要关注如何在DSP++5.0环境下,通过C语言调用汇编子程序来实现6x6矩阵相乘。 首先,我们需要理解矩阵相乘的基本概念。矩阵相乘是线性代数中的基础运算,两个矩阵A和B可以相乘,前提是A的列数等于B的行数。...
1. **C语言调用汇编函数** 在C程序中调用汇编函数通常是通过定义一个外部汇编函数来实现的。首先,我们需要编写一个汇编源文件(例如:asm_func.asm),其中包含汇编函数的定义。然后,使用汇编器(如Microsoft的...
利用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]...
第三,C语言调用汇编语言函数时,需要在C文件中声明函数原型,并在汇编文件中使用`EXPORT`关键字标识函数。例如,`asm_strcpy`函数在C文件中声明为`extern`,在汇编文件中通过`EXPORT`导出,最后通过`mov pc, lr`...
总结起来,C语言调用汇编程序的过程涉及以下步骤: 1. 在C代码中声明汇编实现的函数。 2. 编写汇编代码实现该函数,遵循适当的函数调用约定。 3. 使用汇编器将汇编代码编译为对象文件。 4. 使用C编译器编译C源代码,...
本实验旨在探讨如何在C语言中调用汇编子程序,并处理输入参数和返回结果。C语言与汇编的混合编程使得我们可以利用C语言的易读性和汇编的高效性,以解决复杂的问题。 实验的目的是编写一个C语言程序,它调用一个汇编...
而在C代码中,可以设置中断向量,使得中断发生时调用汇编写的中断服务程序。 6. **性能优化**:对于性能敏感的部分,如循环或关键算法,可以使用内联汇编在C代码中插入,以提高效率。同时,通过分析汇编代码,找出...
总的来说,C语言调用汇编涉及到以下几个关键步骤: 1. 在C文件中声明汇编函数。 2. 编写汇编代码,处理参数和返回值。 3. 使用适当的编译器和链接器选项将C和汇编文件编译和链接在一起。 4. 在运行时,C程序可以通过...
然而,在某些特定情况下,如优化性能或理解底层操作,我们可能需要直接调用汇编语言程序来实现这一功能。在这个主题中,我们将探讨如何在C语言函数中嵌入ARM汇编代码,以实现字符串的拷贝。 首先,我们要了解ARM...
C语言函数调用汇编语言函数知识点总结 C语言函数调用汇编语言函数是软件开发中的一种常见技术。本文将对C语言函数调用汇编语言函数进行总结,详细介绍相关知识点。 一、C语言函数调用汇编语言函数的定义 C语言...