3.4 ARM汇编&C语言混合编程
3.4.1 C内联ARM汇编
先看一个例子:
# cat add.c
1 // add.c for s3c2410c board
2 // arm-linux-gcc -static -o add add.c
3 // qemu-arm add
4 #include
5
6 int main(void)
7 {
8 int foo = 10, bar = 15;
9 __asm__ __volatile__("add %0,%1"
10 :"+r"(foo)
11 :"r"(bar)
12 );
13 printf("foo+bar=%d\n", foo);
14 asm ("add %0,%0,#3" :"=r"(bar):"0"(bar)); //等价asm ("add %0,%0,#3"
:"+r"(bar));
15 printf("bar=%d\n", bar);
16 asm("mov r0, $6; mov r7, $1; swi
$0"); //syscall exit(int status)
17 return
0; //该语句不会执行
18 }
# arm-linux-gcc -static -o add add.c
# qemu-arm add
foo+bar=25 //第13行的结果
bar=18 //第15行的结果
# echo $?
6 //第15行的结果
3.4.3 ARM汇编&C语言混合编程
2.在汇编语言程序中调用C函数
例子:
用GNU ARM汇编语言调用C语言函数,实现5!的阶乘,并将结果保存到寄存器R0中。
# pwd
/root/桌面/嵌入式教程/qemu/armasm-call-c
# ls
factorial.c start.s
# cat start.s
.extern
Factorial @声明Factorial是一个外部函数
.equ Ni,
5 @要计算的阶乘数
.text
.global _start
_start:
MOV
R0,#Ni @将参数装入R0
BL Factorial @调用Factorial,并通过R0传递参数
mov r7,
$1
swi
$0
.end
# cat factorial.c
// arm-linux-gcc -c -o factorial.o factorial.c
long Factorial(char N)
{
char i;
long Nx=1;
for(i=1;i<=N;i++)Nx=Nx*i;
return
Nx; //通过R0,R1返回结果
}
# arm-linux-as -o start.o start.s
# arm-linux-ld -o factorial factorial.o start.o
# qemu-arm factorial
# echo $?
120
进行函数调用时,使用R0实现参数的传递,返回结果由R0带回。函数调用结束后,R0的值为120。
3.C语言程序调用汇编子程序(函数)
例子:
在一个汇编语言源文件中定义了求和函数add,并将结果通过寄存器R0返回。
# pwd
/root/桌面/嵌入式教程/qemu/c-call-armasm
# ls
add.s main.c
# cat main.c
// arm-linux-gcc -c -static -o main.o main.c
// arm-linux-gcc -c -o main.o main.c
//#include
extern int add (int x,int y);
//声明add为外部函数
int main ()
{
int a=1,b=2,c;
c=add(a,b);
//调用add子程序
//printf("a+b=%d\n", c);
//while(1);
return 0;
}
# cat add.s
.extern main
.global
add @声明add为一个全局函数
.text
.global _start
_start:
BL main
mov r7,
$1
swi $0
add:
ADD R0, R0, R1
MOV PC,LR
.end
当main()函数调用add汇编子程序时,变量a、b的值分别赋给R0和R1,返回结果由R0带回,并赋值给变量c。函数调用结束后,变量c的值为3。
生成带调试信息的add的过程如下:
# pwd
/root/桌面/嵌入式教程/qemu/c-call-armasm
# arm-linux-gcc -c -o main.o main.c -g
# arm-linux-as -o add.o add.s -g
# arm-linux-ld main.o add.o -o add
调试信息过程请参考2.5.4节(调试ARM汇编程序)。
3.5 x86汇编&C语言混合编程
# cat add-x86.c
// add-x86.c for x86
// gcc -o add-x86 add-x86.c
// ./add-x86
#include
int main()
{
int a = 10, b, c;
__asm__("movl %1, %�x\n\t"
"movl %�x, %0\n\t"
:"=r"(b)
:"r"(a)
:"�x"
);
printf("Result: %d, %d\n", a, b);
asm ("add %1, %2; movl %2, %0" :"=r"(c):"r"(a),"r"(b));
printf("a: %d\tb: %d\tc: %d\t\n", a,b,c);
return 0;
}
# gcc -o add-x86 add-x86.c
# ./add-x86
Result: 10, 10
a:
10 b:
10 c: 20