伪指令ldr补充

本文补充了上一篇文章中ldr与adr区别的实验结果,展示了汇编源码及反汇编文件,指出ldr指令写常数到寄存器,adr根据pc值计算跳转。还记录了实验流程,包括编译、链接等步骤,同时解析了ELF与BIN文件的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章说到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文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值