arm汇编调用C语言中的printf函数

        对很多人来说,学习C语言时的第一个程序是Hello World 。那么在学习ARM汇编语言的起始阶段,如何写出一个hello world程序呢?

       由于ARM汇编语言程序不像通常的C语言程序,没有操作系统环境,不能做为常见的可执行程序在操作系统上运行,也不能方便地通过标准输出设备来显示字符串。所以在ARM汇编语言中实现hello world比C语言中要麻烦不少。目前网上对这一个话题做较比完整分析的文章还很少见,因此通过一个具体的例子来说明一下。

       选择的工具是MDKl μVision4。首先新建一个project。项目名称随意,在选择目标设备时可以选择ARM/Cortex-M3

新建一个主文件main.s ,主要代码如下:

PRESERVE8

AREA example,CODE,READONLY ; 声明代码段example

IMPORT ||Lib$$Request$$armlib||

IMPORT printf

EXPORT main

 

;汇编代码调用printf的例子

main

STMFD sp!,{r4,lr}

ADR r0,arg0

BL printf

LDMFD sp!,{r4,pc}

 

; 为了arg0的地址4字节对齐,特地跳过两个字节

skip

DCB "\0\0"

arg0

DCB "hello world\n\0"

END

 

如果仅仅只有这个主文件,无法得到正确的结果,还需要重写一下fputc这个函数,将字符输出到MDK的调试窗口。

因此新建一个fputc.c文件,主要内容如下:

#include <string.h>

#include <stdio.h>

#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))

#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))

#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))

 

#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))

#define TRCENA 0x01000000

struct __FILE { int handle; /* Add whatever needed */ };

FILE __stdout;

FILE __stdin;

 

int fputc(int ch, FILE *f) {

    if (DEMCR & TRCENA) {

        while (ITM_Port32(0) == 0);

        ITM_Port8(0) = ch;

    }

    return(ch);

}

为了对芯片做一些初始化工作,还需要新建一个startup.s文件。是从MDK软件自带的例子中复制过来的。

此外,不能使用默认的内存段设置,所以做了一个小的scatter文件,内容如下:

LR_IROM1 0x00000000 0x00040000  {    ; load region size_region

  ER_IROM1 0x00000000 0x00040000  {  ; load address = execution address

   *.o (RESET, +First)

   .ANY (+RO)

  }

  RW_IRAM1 0x20000000 0x00020000  {  ; RW data

   .ANY (+RW +ZI)

  }

}

做好了这些准备工作,通过build操作,可以顺利生成结果文件。再点击调试按钮,调试界面如下图所示:

再点击run按钮,可以在右下方的调试窗口看到输出了hello world.

完整的例子项目可通过CSDN的资源下载获取。

转去下载页面

 

 

 

猜你喜欢

转载自blog.csdn.net/littlezhuhui/article/details/92243623