假设我们有一个汇编源文件led.s,需要经过如下步骤才能得到在ARM处理器上运行的binary文件:

    1. arm-linux-gnueabihf-gcc -g -c led.s -o led.o:编译汇编源码,得到.o目标文件
    2. arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf:链接.o文件获得elf文件,并指定运行地址
    3. 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灯点亮:

    1. .global _start /* 全局标号 */
    2. /*
    3. * 描述: _start函数,程序从此函数开始执行此函数完成时钟使能
    4. * GPIO初始化、最终控制GPIO输出低电平来点亮LED灯
    5. */
    6. _start:
    7. /* 例程代码 */
    8. /* 1、使能所有时钟 */
    9. ldr r0, =0X020C4068 /* 寄存器CCGR0 */
    10. ldr r1, =0XFFFFFFFF
    11. str r1, [r0]
    12. ldr r0, =0X020C406C /* 寄存器CCGR1 */
    13. str r1, [r0]
    14. ldr r0, =0X020C4070 /* 寄存器CCGR2 */
    15. str r1, [r0]
    16. ldr r0, =0X020C4074 /* 寄存器CCGR3 */
    17. str r1, [r0]
    18. ldr r0, =0X020C4078 /* 寄存器CCGR4 */
    19. str r1, [r0]
    20. ldr r0, =0X020C407C /* 寄存器CCGR5 */
    21. str r1, [r0]
    22. ldr r0, =0X020C4080 /* 寄存器CCGR6 */
    23. str r1, [r0]
    24. /* 2、设置GPIO1_IO03复用为GPIO1_IO03 */
    25. ldr r0, =0X020E0068 /* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */
    26. ldr r1, =0X5 /* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */
    27. str r1,[r0]
    28. /* 3、配置GPIO1_IO03的IO属性*/
    29. ldr r0, =0X020E02F4 /*寄存器SW_PAD_GPIO1_IO03_BASE */
    30. ldr r1, =0X10B0
    31. str r1,[r0]
    32. /* 4、设置GPIO1_IO03为输出 */
    33. ldr r0, =0X0209C004 /*寄存器GPIO1_GDIR */
    34. ldr r1, =0X0000008
    35. str r1,[r0]
    36. /* 5、打开LED0
    37. * 设置GPIO1_IO03输出低电平
    38. */
    39. ldr r0, =0X0209C000 /*寄存器GPIO1_DR,设置该寄存器为0 */
    40. ldr r1, =0
    41. str r1,[r0]
    42. /* loop 死循环,程序不终止 */
    43. loop:
    44. b loop

    实际上,我们可以用C语言完成上面的逻辑,而不是手撸汇编,毕竟直接使用汇编太繁琐了。