混合编程-C语言和GNU ARM汇编互相调用

2 篇文章 0 订阅
1 篇文章 0 订阅
本文介绍了如何在C/C++中使用__asm关键字嵌入汇编代码,包括__asm的语法、示例以及C语言和汇编之间的参数传递规则,特别关注了ARM汇编的限制和调用C语言的步骤。
摘要由CSDN通过智能技术生成

混合编程-C语言和GNU ARM汇编互相调用

C语言嵌入汇编

__asm 是C/C++中的一个关键字,用于嵌入汇编代码到C/C++程序中。它通常用于需要直接操作底层硬件或者需要特定的汇编指令来实现的场景。

在使用 __asm 关键字时,可以直接在C/C++代码中编写汇编指令。这样的话,编译器会将这部分汇编代码嵌入到生成的可执行文件中。

格式

 __asm [volatitle]{[instruction]} 

示例

int main() {
    int a = 5;
    int b = 10;
    int result;

  	// 要避免直接使用这些物理寄存器,这里只是示例
    __asm {
        MOV R0, a   ; 将变量a的值加载到R0寄存器中
        ADD R0, R0, b   ; 将变量b的值加到R0寄存器中
        MOV result, R0  ; 将R0寄存器的值保存到result变量中
    }

    return 0;
}

void my_strcpy(char *srt,char *dest){
	char ch;
  __asm {
    	loop:
        LDRB ch,[src],#1
        STRB ch,[dest],#1
        CMP ch,#0
        BNE loop
  }
}

限制条件

  • 不能直接向PC寄存器赋值,程序跳转要使用B或BL指令;
  • 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;
  • R12和R13可能被编译器用来存放中间编译结果,计算表达式值可能 R0~R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器。

C语言调用汇编

步骤

  1. 汇编 .global
  2. C语言定义 extern function
  3. C语言使用
.global add

add:
    ADD r0, r0, r1    @ 将第一个参数(r0)和第二个参数(r1)相加,并将结果存储在r0中
    B lr              @ 返回
#include <stdio.h>

extern int add(int a, int b);  // 声明外部的add函数

int main() {
    int result = add(10, 20);
    printf("Result: %d\n", result);
    return 0;
}
as -o add.o add.s
gcc -o main main.c add.o

注意

C语言和汇编语言之间的参数传递是通过 R0~R3来进行传递的,即R0传递第一个参数,R1传递第二个参数,R2传递第三个参数,多于4个时借助栈来实现,函数的返回值通过R0来传递,这个规定叫 ATPCS(ARM Thumb Procedure Call Standard),具体见ATPCS规范

汇编调用C语言

步骤

  1. C语言实现函数
  2. 汇编声明C语言函数
  3. BL 函数名
// add.c
int add(int a, int b) {
    return a + b;
}
.section .text
.global main

; 声明外部的C语言函数
.extern add

main:
    MOV R0, #5         @ 将参数 a 加载到寄存器 R0 中
    MOV R1, #10        @ 将参数 b 加载到寄存器 R1 中
    BL add             @ 调用C语言函数 add
    MOV R2, R0         @ 将返回值存储到寄存器 R2 中

    ; 在这里可以使用返回值 R2,比如打印输出
    ; ...

    ; 函数返回
    MOV R7, #1         @ 将退出系统调用号加载到 R7 中
    SWI 0              @ 执行退出系统调用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值