C和汇编-混合编程
混合编程规则
- 混合编程要遵循ARM公司指定的ATPCS规范
- 汇编和C语言的传递参数
汇编:参数传递通过寄存器 r0 - r3。
C语言:形参的个数一般不要超过4个;如果超过4个,则使用栈传递参数。 - C:函数的返回值return_value,通过r0返回。汇编:r0不够通过使用寄存器 r0-r1,依次使用。
汇编调用C
(1) 切换到User模式:msr cpsr ,#0xD0
注:用户模式后8位 0x1101 0000 = 0xD0
(2)初始化User模式下的栈:ldr sp, = 0x40001020
(3)汇编调用C:
mov r0,#1 @参数赋值操作
mov r1,#2
bl add @注意跳转回来bl + c程序中函数名即函数的首地址
int add(int a,int b)
{
int sum = 0;
sum = a + b;
return sum; 将sum中的值先放到临时变量中,
再将临时变量中的值返回给主函数调用者。
} ---> 作用域终止运算符,释放sum
main()
{
int sum;
sum = add (3, 4);//sum是调用函数中返回的临时变量 赋值给此main中的sum
}
注:
(1)子函数只有在被调用的时候才分配临时使用的栈空间。
(2)传递参数用r0-r3寄存器,执行完返回值用r0返回。
C调用汇编
无论是C调用汇编还是汇编调用C,代码的执行都是先从汇编开始执行:切换user模式,分配栈内存空间,跳转执行函数。
- 汇编代码:start.s
.text
.globl _start
_start:
@ 1)切换到用户模式
msr cpsr, #0xD0
@ 2)初始化用户模式下的栈
ldr sp, =0x40001020
@ 3)汇编跳转C主函数main
bl main
globl add_func: @定义一个add_func函数,main主函数调用add_func(1,2)时,将1传给r0,2传给r1。
add r0, r0, r1 @将r0和r1的相加保存到r0中
mov pc, lr @ 再返回到调用执行下一条指令的位置,跳转到main()主函数
.end
- C代码:add.c
extern int add_func(int a,int b);//声明一个外部函数
int main()
{
int sum;
sum = add_func(1,2);
while(1);
return 0;
}
linux下交叉编译环境配置
在windows编写代码–》在开发板上运行代码
x86 ARM
安装交叉编译工具链:将PC平台下的代码编译成ARM架构的可执行程序
安装步骤:
1. 在ubuntu的家目录(~)下,创建toolchain
mkdir toolchain
2. 拷贝gcc-4.5.1.tar.bz2到toolchain目录下
cp 目录/gcc-4.5.1.tar.bz2 ~/toolchain
3. 解压缩交叉编译工具链
tar -vxf gcc-4.5.1.tar.bz2
4. 配置环境变量
打开 sudo vi /etc/bash.bashrc
在最后一行添加内容,修改为自己的gcc交叉编译工具的/bin路径:
export PATH=$PATH:/home/linux/toolchain/gcc-4.5.1/bin/
5. 使环境变量立即生效
source /etc/bash.bashrc
6. 测试交叉编译工具链是否安装成功
arm-none-linux-gnueabi-gcc -v
打印以下内容,表示成功
gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50)