ENTRY(helloworld) SECTIONS { . = 0x00000000; .text :{ *(.text) } . = ALIGN(32); .data :{ *(.data) } . = ALIGN(32); .bss: { *(.bss) }
.haha: {
*(.haha)
} }
.arch armv7 # 选择目标体系结构,这里指定编译后生成armv7体系结构的代码 .global helloworld # 若想在外部文件里引用函数或变量,就要用.global声明,相当于C语言extern .equ REG_FIFI, 0x50000020 # 相当于C语言宏定义,这里是指串口地址 .text # 从当前位置开始的内容被归并到代码段中 .align 2 # 在ARM下,.align后面的数是以幂出现的,这里指按4字节对齐 helloworld: ldr r1, =REG_FIFO # 将常量写入寄存器中,即将串口地址存储到r1中 adr r0, .L0 # 将相对地址写入寄存器中,这里使r0指向helloworld字符串的首地址 .L2: ldrb r2, [r0], #0x1 # b的意思是ldr一个字节的数据,这里意思是把r0的内容的一个字节写到r2,然后r0值加1。即使r2指向‘h‘,r0指向‘e‘ str r2, [r1] # 将寄存器值存储到另一个寄存器所指向的内存地址中。这里把r2的值存到r1中,即把‘h‘通过串口打印到屏幕上 cmp r2, #0x0 # 将两个数相减,影响CPSR的零标志位,从而影响判断条件的执行 bne .L2 # 如果r2 != 0,跳到.L2,即执行循环。 不等于0说明还没有到达字符串结尾,因为字符串最后是‘\0‘ .L1: b .L1 .align 2 .L0: .ascii "helloworld\n\0" # 用于在内存中定义字符串,这里定义“helloworld\n”字符串
文件start.s:
.arch armv7 .global _start .equ REG_FIFO, 0x50000020 .text .align 2 _start: ldr r0, =REG_FIFO # r0, r1这两个值就是传给helloworld的参数 adr r1, .L0 bl helloworld # bl的作用和b医院,只是多了保存程序返回地址的功能 .L1: b .L1 .align 2 .L0: .ascii "helloworld\n\0"
文件helloworld.c:
int helloworld(unsigned int *addr, const char *p) { while(*p) { *addr = *p++; }; return 0; }
arm-elf-ld -e _start -Ttext 0x0 start.o hello world.o -o helloworld
运行成功,这里-e命令是说以_start函数为程序入口函数,也可以在链接脚本里用ENTRY(_start)指定。
嵌入式Linux入门基础知识 ---- 链接脚本、汇编语言、混合编程,布布扣,bubuko.com
嵌入式Linux入门基础知识 ---- 链接脚本、汇编语言、混合编程
原文:http://www.cnblogs.com/comeonjiji/p/3624005.html