zoukankan      html  css  js  c++  java
  • ARM中C和汇编的相互调用(5个数求和、字符串拷贝)

    开发环境:Keil5

    工程目录:

     

    一、汇编调用C——多数相加

      使用汇编调用C,需要注意的是参数的传递。不同于X86的传参规则,在ARM体系中,如果形参的个数不超过4个,使用特殊寄存去R0~R3传递;而如果参数大于4个,就要将多出来的那部分参数使用堆栈传递。

      压栈的之后移动位置指针,压栈顺序别忘了是最后一个参数先入栈->倒数第二个参数->,,,,

      下面的代码实现了五个参数求和,首先使R0=0,R1=1,R2=2,R3=3,第五个参数使用栈传递,并移动堆栈指针。

    (1)startup.s

    Stack_Size EQU 0x100         ;初始化栈的大小为256B
        AREA STACK, NOINIT, READWRITE, ALIGN = 3
    Stack_Mem SPACE Stack_Size
    __initial_sp
    
        PRESERVE8
        THUMB
            
        AREA RESET, DATA, READONLY;中断向量表 
            DCD __initial_sp
            DCD Reset_Handler
        AREA RESET, DATA, READWRITE
        
    
    
    
        AREA Sum, CODE, READONLY ;声明一个叫Sum的代码段,可读
    Reset_Handler PROC;          ;复位函数,从这里开始执行
        IMPORT  main             ;main函数不在此文件中,所以需要引入
        IMPORT  sum5             ;sum5函数不在此文件中,所以需要引入
        
    
    CALLSUM5
        MOV R0,#0
        MOV R1,#1
        MOV R2,#2
        MOV R3,#3
        MOV R4,#4                ;前4个参数使用R0~R3传递,
        STR R4,[SP, #-4]!        ;第5个使用栈传递
        BL  sum5                 ;调用c程序
        LDR  R0, = main   
        BX      R0               ;回到C的main函数
        ENDP
        END

    (2)main.c

    int sum5(int a, int b, int c, int d, int e) {
        return (a+b+c+d+e);
    }    
    int main(void) {
    
        return 0;
    }

    二、C调用汇编——strcopy

      逻辑上比较好理解,首先在汇编文件中定义C要调用的函数,然后在.c文件extern这个函数,调用即可。

    (1)startup.s

        AREA |.text|, CODE, READONLY ;声明一个叫|.text|的代码段,可读    
    Reset_Handler PROC
        IMPORT  main                 ;main函数不在此文件中,所以需要引入
        EXPORT  Reset_Handler        ;声明外部函数
    
        LDR     R0, =main
        BX      R0
        ALIGN
        ENDP    
        
        
        
        AREA SCopy, CODE, READONLY          
        EXPORT strcopy               ;想要被外部调用,必须声明函数
    strcopy
        LDRB R2,[R1],#1              ;B 代表一个字节,#1 代表 R1 的地址 1
        STRB R2,[R0],#1
        CMP  R2,#0                   ;0 是字符串额结束标志,比较R2和0就可以看到字符串是否结束
        BNE  strcopy                 ;跳转指令,不相等的时候跳转到上面,形成了循环
        BX   LR                      ;返回现场
    
        END    

    (2)main.c

    extern void strcopy(char *d, const char *s);
    
    int main(void) {
        const char  srcstr[] = "ABCDEFGH";//0x41-0x48
              char  dststr[] = "abcdefgh";//0x61-0x68
        strcopy(dststr, srcstr);
    
        return 0;
    }

  • 相关阅读:
    springboot的jar为何能独立运行
    掌握SpringBoot-2.3的容器探针:实战篇
    掌握SpringBoot-2.3的容器探针:深入篇
    掌握SpringBoot-2.3的容器探针:基础篇
    详解SpringBoot(2.3)应用制作Docker镜像(官方方案)
    体验SpringBoot(2.3)应用制作Docker镜像(官方方案)
    kubespray2.11安装kubernetes1.15
    Jenkins集群下的pipeline实战
    快速搭建Jenkins集群
    前端开发神器Charles从入门到卸载
  • 原文地址:https://www.cnblogs.com/Irvingcode/p/12111301.html
Copyright © 2011-2022 走看看