上一篇文章说到ldr,adr区别,在这补充一下实验结果
汇编源码如下
_start:
.word 1
.word 2
.word 3
.word 4
ldr pc, main
ldr pc, =main
adr pc, main
led_blink:
ldr r1, =0xE0200244
mov r0, #0
str r0, [r1]
bl delay
ldr r1, =0xE0200244
mov r0, #0x38
str r0, [r1]
bl delay
sub r2, r2, #1
cmp r2,#0
bne led_blink
main:
bl delay
delay:
mov r0, #0x900000
delay_loop:
cmp r0, #0
sub r0, r0, #1
bne delay_loop
mov pc, lr
经过编译、链接、反编译后得到对应反汇编文件如下
start.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
0: 00000001 andeq r0, r0, r1
4: 00000002 andeq r0, r0, r2
8: 00000003 andeq r0, r0, r3
c: 00000004 andeq r0, r0, r4
10: e59ff030 ldr pc, [pc, #48] ; 48 <main>
14: e59ff044 ldr pc, [pc, #68] ; 60 <delay_loop+0x10>
18: e28ff028 add pc, pc, #40 ; 0x28
0000001c <led_blink>:
1c: e59f1040 ldr r1, [pc, #64] ; 64 <delay_loop+0x14>
20: e3a00000 mov r0, #0
24: e5810000 str r0, [r1]
28: eb000007 bl 4c <delay>
2c: e59f1030 ldr r1, [pc, #48] ; 64 <delay_loop+0x14>
30: e3a00038 mov r0, #56 ; 0x38
34: e5810000 str r0, [r1]
38: eb000003 bl 4c <delay>
3c: e2422001 sub r2, r2, #1
40: e3520000 cmp r2, #0
44: 1afffff4 bne 1c <led_blink>
00000048 <main>:
48: ebffffff bl 4c <delay>
0000004c <delay>:
4c: e3a00609 mov r0, #9437184 ; 0x900000
00000050 <delay_loop>:
50: e3500000 cmp r0, #0
54: e2400001 sub r0, r0, #1
58: 1afffffc bne 50 <delay_loop>
5c: e1a0f00e mov pc, lr
60: 00000048 andeq r0, r0, r8, asr #32
64: e0200244 eor r0, r0, r4, asr #4
68: 00001a41 andeq r1, r0, r1, asr #20
6c: 61656100 cmnvs r5, r0, lsl #2
70: 01006962 tsteq r0, r2, ror #18
74: 00000010 andeq r0, r0, r0, lsl r0
78: 45543505 ldrbmi r3, [r4, #-1285] ; 0x505
7c: 08040600 stmdaeq r4, {r9, sl}
80: Address 0x00000080 is out of bounds.
可以看出_start标号的函数中三条指令被编译器转换,ldr指令就是直接写一个常数到寄存器。而adr则是根据当前pc寄存器值进行计算,再跳转。
后记:
实验过程中遇见不少问题记录一下。
arm-linux-objdump
-i 显示支持的目标文件格式和CPU架构
-f file 查看file文件的整体头部摘要信息
#arm-linux-objdump -f start.bin
start.bin: file format elf32-littlearm
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000
实验流程:
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Tlink.lds -o start.elf start.o
arm-linux-objcopy -O binary start.elf start.bin
arm-linux-objdump -D start.elf > start_elf.dis过程编译源文件得到.o文件--->链接得到.elf文件----->转换为二进制.bin文件
通过.elf文件反汇编得到反汇编文件。
ELF与BIN文件区别:
Gcc 编译出来的是ELF文件。通常gcc –o test test.c,生成的test文件就是ELF格式的,在linuxshell下输入./test就可以执行。
Bin 文件是经过压缩的可执行文件,去掉ELF格式的东西。是直接的内存映像的表示。在系统没有加载操作系统的时候可以执行。
elf(executable and link format)文件里面包含了符号表,汇编等。
BIN文件是将elf文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像。