假设我们有一个汇编源文件led.s,需要经过如下步骤才能得到在ARM处理器上运行的binary文件:
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
:编译汇编源码,得到.o目标文件arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
:链接.o文件获得elf文件,并指定运行地址arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
:将elf文件转换成binary文件,后缀为.bin
另外不管是汇编还是C代码编译生成的elf文件,我们都可以通过下面命令得到反汇编的文件:arm-linux-gnueabihf-objdump -D led.elf > led.dis
下面是led.s的内容,通过设置寄存器bit GPIO1_IO03 = 0,使板子上的led灯点亮:
.global _start /* 全局标号 */
/*
* 描述: _start函数,程序从此函数开始执行此函数完成时钟使能
* GPIO初始化、最终控制GPIO输出低电平来点亮LED灯
*/
_start:
/* 例程代码 */
/* 1、使能所有时钟 */
ldr r0, =0X020C4068 /* 寄存器CCGR0 */
ldr r1, =0XFFFFFFFF
str r1, [r0]
ldr r0, =0X020C406C /* 寄存器CCGR1 */
str r1, [r0]
ldr r0, =0X020C4070 /* 寄存器CCGR2 */
str r1, [r0]
ldr r0, =0X020C4074 /* 寄存器CCGR3 */
str r1, [r0]
ldr r0, =0X020C4078 /* 寄存器CCGR4 */
str r1, [r0]
ldr r0, =0X020C407C /* 寄存器CCGR5 */
str r1, [r0]
ldr r0, =0X020C4080 /* 寄存器CCGR6 */
str r1, [r0]
/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */
ldr r0, =0X020E0068 /* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */
ldr r1, =0X5 /* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */
str r1,[r0]
/* 3、配置GPIO1_IO03的IO属性*/
ldr r0, =0X020E02F4 /*寄存器SW_PAD_GPIO1_IO03_BASE */
ldr r1, =0X10B0
str r1,[r0]
/* 4、设置GPIO1_IO03为输出 */
ldr r0, =0X0209C004 /*寄存器GPIO1_GDIR */
ldr r1, =0X0000008
str r1,[r0]
/* 5、打开LED0
* 设置GPIO1_IO03输出低电平
*/
ldr r0, =0X0209C000 /*寄存器GPIO1_DR,设置该寄存器为0 */
ldr r1, =0
str r1,[r0]
/* loop 死循环,程序不终止 */
loop:
b loop
实际上,我们可以用C语言完成上面的逻辑,而不是手撸汇编,毕竟直接使用汇编太繁琐了。