s3c2440学习之路-003 汇编给C传参数 点亮不同led灯

  1. 原理分析
  2. 源码

硬件平台:jz2440
软件平台:Ubuntu16.04 arm-linux-gcc-3.4.5
源码位置: https://github.com/lian494362816/C/tree/master/2440/004_led_parma

1原理分析

当使用汇编调用C函数,碰到需要传参时,可以使用R0-R3来传递参数。
R0代表第1个参数,R1代表第2个参数.......当参数超过4个时,就需要靠SP来实现了。
更详细的说明可以去查“ATPCS规则“。
这里只讨论参数不超过4个时的情况。

2源码

led_on.c

void delay(int delay_time)
{
    while(delay_time --)
    {
        /* nothing */
    }
}

int led_on(int led_num)
{
    unsigned int *pGPF4CON = (unsigned int *)0x56000050;
    unsigned int *pGPFDAT = (unsigned int *)0x56000054;

    if (4 == led_num)
    {^M
        *pGPF4CON = 0x100;
    }
    else if (5 == led_num)
    {
        *pGPF4CON = 0x400;
    }

    *pGPFDAT = 0x0;

    return 0;
}

先看C文件,包含了2个函数,delay 和 led_on。
led_on:传入4或5来点亮2个不同的LED灯
delay:对传进来的参数做递减, 以此来实现简单的延时

start.s

.global _start
_start:

    ldr sp, =4096 /* for nand */
    /*ldr sp, =0x40000000 + 4096  /* for nor */

    mov r0, #4
    bl led_on
    ldr r0,=10000
    bl delay
    mov r0, #5
    bl led_on

loop:
    b loop

如之前所说的,R0代表第1个参数。 而led_on 和delay都只接收1个参数,所以需要把参数的值都赋值给R0。
(1)先将4赋值给R0然后调用led_on, 相当于调用led_on(4),
(2)然后把10000赋值给R0,再调用delay, 相当于调用delay(10000),
(3)再次把5赋值给R0, 然后调用led_on,相当于调用led_on(5)
这样就实现了汇编给C传参,点亮不同的led灯。 这样简单的led函数可以在调试u-boot时使用,尤其是当串口还未初始化时,可以通过点亮/熄灭 不同的led灯来判断代码执行到了什么位置。

你可能感兴趣的:(s3c2440学习)