简述arm汇编和c语言混合编程,ARM汇编&C语言混合编程

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

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值