6410之汇编和c之间参数的传递

来源:互联网 发布:淘宝运费是怎么算的 编辑:程序博客网 时间:2024/06/05 07:46

一、汇编向c中传递参数并调用

1.传递低于4个参数:

如果汇编向c传递的参数个数小于或等于4个的话,这几个参数可以存放在r0-r3寄存器中,如果多余4的话就需要将多余的参数存放到栈中了。

汇编代码:

#define CONFIG_PERIPORT_BASE 0x70000000#define CONFIG_PERIPORT_SIZE 0x13#define WTCON                0x7E004000 .global _start_start:    /*告诉CPU 外设的地址*/    ldr r0, =CONFIG_PERIPORT_BASE    orr r0, r0, #CONFIG_PERIPORT_SIZE    mcr p15,0,r0,c15,c2,4    /*关闭看门狗*/    ldr r0, =WTCON    mov r1, #1    str r1,[r0]    /*设置GPM0到GPM3的电平输出为低,点亮,使用c编写*/    mov sp,#(1024*8)    ldr r0,=0x8000                            //将0x8000传递给r0,这个r0就是跳转到c函数的第一个参数    bl xxxxhalt:    b halt
c函数:

#define GPMDAT (volatile unsigned long *)0x7F008824#define GPMCON (volatile unsigned long *)0x7F008820void delay(int count)//延时{    volatile unsigned long i = count; //需要加入volatile,否则编译器会将该变量优化掉    while(i){        i--;    }}int xxxx(int n)   //第一个参数n就是汇编中传进来的r0{    volatile unsigned long *gpmcon = GPMCON;    volatile unsigned long *gpmdat = GPMDAT;    *gpmcon = 0x1111;        int i = 0;    while(1){        *gpmdat = i;        i++;        if(i == 16)            i = 0;        delay(n);    }       return 0;}   

2.传递多于4个参数

汇编:

#define CONFIG_PERIPORT_BASE 0x70000000#define CONFIG_PERIPORT_SIZE 0x13#define WTCON                0x7E004000 .global _start_start:    /*告诉CPU 外设的地址*/    ldr r0, =CONFIG_PERIPORT_BASE    orr r0, r0, #CONFIG_PERIPORT_SIZE    mcr p15,0,r0,c15,c2,4    /*关闭看门狗*/    ldr r0, =WTCON    mov r1, #1    str r1,[r0]    /*设置GPM0到GPM3的电平输出为低,点亮,使用c编写*/    mov sp,#(1024*8)    mov r0,#0    mov r1,#16    ldr r2,=0x1000    ldr r3,=0x1000           //r0,r1,r2,r3将传递给c函数的前四个参数中#   ldr r4,=0x1000           //这个指令是我尝试实验r4是否可以传递进c函数,结果是可以编译通过,但是led灯是不能闪烁的    ldr sp,=(1024*8-4)        //设置第5个参数存放的位置    ldr r4,=0x4000    str r4,[sp]    bl xxxxhalt:     b halt

二、c函数调用汇编代码:

汇编:

#define CONFIG_PERIPORT_BASE 0x70000000#define CONFIG_PERIPORT_SIZE 0x13#define WTCON                0x7E004000 .global _start.global delay              //必须定义这个标志为global,不然c函数无法调用到汇编代码_start:    /*告诉CPU 外设的地址*/    ldr r0, =CONFIG_PERIPORT_BASE    orr r0, r0, #CONFIG_PERIPORT_SIZE    mcr p15,0,r0,c15,c2,4    /*关闭看门狗*/    ldr r0, =WTCON    mov r1, #1    str r1,[r0]    /*设置GPM0到GPM3的电平输出为低,点亮,使用c编写*/    mov sp,#(1024*8)    bl xxxxhalt:    b haltdelay:    ldr r0,=0x8000delay_loop:    sub r0,r0,#1    cmp r0,#0    bne delay_loop    mov pc,lr              //调用mov pc,lr来返回,否则,将一直c中的函数delay下去

c函数:

#define GPMDAT (volatile unsigned long *)0x7F008824#define GPMCON (volatile unsigned long *)0x7F008820void delay();//声明delay函数,实现在汇编中int xxxx(){    volatile unsigned long *gpmcon = GPMCON;    volatile unsigned long *gpmdat = GPMDAT;        *gpmcon = 0x1111;        int i = 0;    while(1){        *gpmdat = i;        i++;        if(i == 16 )            i = 0;        delay();    }       return 0;}   

三、对于位的操作,应该使用下面的形式:

将 *gpmcon = 0x1111;
 改为:*gpmcon = (*gpmcon & ~0xffff) | 0x1111;

上面的坏处是可以会导致其他位被影响,下面的就只操作我们需要的位,不需要的是不会收到影响的。

原创粉丝点击