
arm-linux-gcc -wall -O2 -c -o $@ $<
-o 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
-Wall 指定产生全部的警告信息
-O2 编译器对程序提供的编译优化选项,在编译的时候使用该选项,可以使生成的执行文件的执行效率提高
-c 表示只要求编译器进行编译,而不要进行链接,生成以源文件的文件名命名但把其后缀由 .c 或 .cc 变成 .o 的目标文件
-S 只激活预处理和编译,就是指把文件编译成为汇编代码
arm-linux-ld 直接指定代码段,数据段,BSS段的起始地址
-Tbss ADDRESS Set address of .bss section
-Tdata ADDRESS Set address of .data section
-Ttext ADDRESS Set address of .text section
示例:
${CROSS}ld -Ttext=0x33000000 led.o -o led.elf
使用连接脚本设置地址:
arm-linux-ld -Tbeep.lds start.o beep.o -o beep.elf
其中beep.lds 为连接脚本如下:
arm-linux-objcopy被用来复制一个目标文件的内容到另一个文件中,可用于不同源文件的之间的格式转换
示例:
arm-linux-objcopy –o binary –S elf_file bin_file
常用的选项:
input-file , outflie
输入和输出文件,如果没有outfile,则输出文件名为输入文件名
2.-l bfdname或—input-target=bfdname
用来指明源文件的格式,bfdname是BFD库中描述的标准格式名,如果没指明,则arm-linux-objcopy自己分析
3.-O bfdname 输出的格式
4.-F bfdname 同时指明源文件,目的文件的格式
5.-R sectionname 从输出文件中删除掉所有名为sectionname的段
6.-S 不从源文件中复制重定位信息和符号信息到目标文件中
7.-g 不从源文件中复制调试符号到目标文件中
arm-linux-objdump
查看目标文件(.o文件)和库文件(.a文件)信息
arm-linux-objdump -D -m arm beep.elf >beep.dis
-D 显示文件中所有汇编信息
-m machine
指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构.
[guowenxue@localhost asm_c_buzzer]$ cat beep.lds
/***********************************************************************
*File: beep.lds
* Version: 1.0.0
* Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com>
* Description: Cross tool link text, refer to u-boot.lds
* ChangeLog: 1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"
*
**********************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS{
. = 0x33000000
.text : {
*(.text)
*(.rodata)
}
.data ALIGN(4): {
*(.data)
}
.bss ALIGN(4): {
*(.bss)
}
}
[guowenxue@localhost asm_c_buzzer]$ cat makefile
# ***********************************************************************
# *File: makefile
# * Version: 1.0.0
# * Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com>
# * Description: Makefile used to cross compile the ASM and C source code
# * ChangeLog: 1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"
# *
# ***********************************************************************
CROSS = /opt/buildroot-2011.02/arm920t/usr/bin/arm-linux-
CFLAGS =
beep.bin: start.S beep.c
arm-linux-gcc $(CFLAGS) -c -o start.o start.S
arm-linux-gcc $(CFLAGS) -c -o beep.o beep.c
arm-linux-ld -Tbeep.lds start.o beep.o -o beep.elf
arm-linux-objcopy -O binary -S beep.elf beep.bin
rm -f *.elf *.o
install:
cp beep.bin ~/winxp -f --reply=yes
clean:
rm -f *.elf *.o
rm -f beep.bin
在开始的时候设置起始代码段。1,首先,进入目录LINK,运行make生成arm-linux-ld选项为“-Ttext 0x00000000”的反汇编码ttt.s。
然后,修改Makefile:将第4、7行的“#”去掉,在第3、6行前加上“#”,运行make生成arm-linux-ld选项为“-Ttext 0x30000000”的反汇编码ttt2.s,link.s程序中用到两种跳转方法:b跳转指令、直接向pc寄存器赋值。
然后,先把在不同“-Ttext”选项下,生成的可执行文件的反汇编码列出来,再详细分析这两种不同指令带来的差异。
然后,让第一张图片从最左面开始,滚动方向是从左向右,而且让第一张图片和最后一张图片要连接在一起,现在是一个滚动完成之后,图片又从最右边开始向左滚动。
然后,在应用程序中,栈和堆的起始地址是有约定的。但是内核本身没有另外一个更高层的程序来管理内核的地址空间,所以内核空间的栈的组织,和应用程序有所不同。内核的栈如果溢出时,不能像应用程序那样产生一个page fault,然后分配新的地址空间,继续使用。内核的栈如果溢出,没有人知道,除非溢出的地方影响了运行,让程序crash。
后,堆的空间的扩大靠brk()系统调用,而内核的内存使用,get_free_pages来实现的(虽然上层封装了kmalloc和vmalloc),这个基本上是自己管理自己,由于Linux内核还不支持自己的swapping,所以内核如果找不到可用的页框了,也就没办法了。
连接器脚本xxx.lds文件中指定的地址,就是链接地址,程序运行时必须位于它的链接地址处,汇编文件中的各个标号或者c文件中的各个函数名(函数的入口地址)对应的链接地址就是由链接脚本中的起始链接地址和各个目标文件(.s或.c文件编译但还为链接的文件)的排放顺序有关。这些链接地址可以通过查看可执行文件的反汇编文件即xxx.dis文件来获得.如果你不使用全局变量或者静态变量,访问这些变量时要使用到链接地址,重定位完成之前不能使用这些类型的变量,adr、b和bl指令都是属于相对跳转指令,即在当前pc值的基础上加减一个偏移值,跳转去执行。如果只使用adr、b或者bl指令,并且不访问全局变量或者静态变量,这类代码被称为“位置无关码”,即代码的存储位置可以不在其链接地址处。如果当使用全局跳转指令ldr时就只能使用链接地址了,如ldr pc,_reset。程序运行时,pc指针的内容是不区分原本地址(存储地址)或链接地址的,只要是”位置无关码“,存储地址可以与链接地址不同,不是位置无关码就要使用到链接地址,即存储地址与链接地址必须相同。即使用之前必须完成代码的重定位。
ps:望采纳!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)