c程序调用汇编函数
程序实例:按键控制led灯
/************************* main.c**************************/
static int (*printf)(const char *format,...) = (int (*)(const char *format,...))0xc3e11ad0
void _start()
{
printf("%s , %s \n", __FUNCTION__, __LINE__);
led_init();
key_init();
while(1)
{
led_on(key_stat());
}
}
/************************* led_key.S**************************/
//转载请注明原文地址:http://blog.csdn.net/oyhb_1992/article/details/77822816
#define GPM4CON 0X110002E0
#define GPM4DAT 0X110002E4
#define GPX3CON 0X11000C60
#define GPX3DAT 0X11000c64
.global led_init
led_init:
//GPM4_0~3设为输出
//GPM4CON = (GPM4CON & ~0XFFFF) | 0X1111led_init:
ldr r0 , =GPM4CON
ldr r1 , [r0]
bic r1 , #0xff
bic r1 , #0xff00 //0xffff 0x1111都是非法立即数,两种方法,拆开立即数或用伪指令
ldr r2 , #0x1111
orr r1 , r2
str r1 , [r0]
mov pc , lr
.global key_init
key_init:
//GPX3_2~5设为输入
//GPX3CON &= ~(0XFFFF<<8)
ldr r0 , =GPX3CON
ldr r1 , [r0]
bic r1 , #(0xff<<8)
bic r1 , #(0xff00<<8)
ldr r2 , #0x1111
str r1 , [r0]
mov pc , lr
.global key_stat
key_stat:
ldr r0 , =GPM3DAT
ldrb r1 , [r0]
mov r1 , r1 , lsr #2
and r1 , #0xf
mov r0 , r1 //将按键状态stat通过r0传给led_on函数,汇编中函数的返回值是通过r0来传递
mov pc , lr
.global led_on
led_on:
//点亮led
//GPM4DAT = (GPM4DAT & ~0Xf) | (stat & 0xf)
ldr r2 , r0 //将函数唯一的参数stat转移到r2里
ldr r0 , =GPM4DAT
ldrb r1 , [r0]
bic r1 , 0xf
orr r1 , r2 //点灯
strb r1 , [r0]
mov pc , lr
/************************* makefile**************************/
TGT := boot.o
OBJS := led_key.o
OBJC := main.o
CROSS_COMPILER := arm-linux-
CC := $(CROSS_COMPILER)gcc
OBJCOPY := $(CROSS_COMPILER)objcopy
CFLAGS := -ffreestanding
LDFLAGS : -static -nostartfiles -Ttext=0x40000000
all:
$(CC) $(CFLAGS) -c $(OBJC:.o=.S) $(OBJC:.o=.c)#替换后缀,编译生成a.out
$(CC) $(LDFLAGS) $(OBJC) $(OBJS) #链接,_start在哪个文件里哪个文件链接就放前面
$(OBJCOPY) -O binary a.out $(TGT:.o=.bin)
clean:
$(RM) a.out $(OBJC) $(TGT:.o=.bin)