risc-v中文社区

 找回密码
 立即注册
查看: 7097|回复: 3

arm的ldr和adr指令

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-10-16 17:37:29 | 显示全部楼层 |阅读模式
.section .text "x"
        ldr r0,_start
        adr r0,_start
        ldr r0,=_start
        nop
_start:
        nop
编译:
ldradr:ldradr.o
        arm-none-eabi-ld -Ttext=0x30000000 -Tdata=0x40000000 -Map ldrard.map -o ldradr.elf $^
        arm-none-eabi-objdump -D ldradr.elf > ldradr.dis
反汇编之后主要代码如下:
ldradr.elf:     file format elf32-littlearm

Disassembly of section .text:

30000000 <_start-0x10>:
30000000:        e59f0008         ldr        r0, [pc, #8]        ; 30000010 <_start> 指令基址0x30000000,在指令执行时pc值其实是0x30000008,所以指令的目的就是将0x30000008+8=0x30000010内存中的字数据传给r0。
                                                          //如果执行时的基地址与-Ttext指定的链接基址不同,最终也不影响ldr r0,_start对内存地址的寻址,也就是说是位置无关定位
30000004:        e28f0004         add        r0, pc, #4        //也就是指令adr r0,_start。pc值在指令执行时值为0x3000000C,所以pc+4=0x30000010,不管基址是多少,执行时都能正确定位目标地址,所以是位置无关定位
30000008:        e59f0004         ldr        r0, [pc, #4]        ; 30000014 <_start+0x4> 即寄存器基址加偏址寻址最终地址为0x30000014
3000000c:        e1a00000         nop                        ; (mov r0, r0)

30000010 <_start>:
30000010:        e1a00000         nop                        ; (mov r0, r0)
30000014:        30000010         andcc        r0, r0, r0, lsl r0

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-10-16 17:38:27 | 显示全部楼层
汇编语法错误:
.section .text,"x"
        ldr r0,_start
        adr r0,_start
        ldr r0,=_start
        ldrb r1,data2  //此句:Error: internal_relocation (type: OFFSET_IMM) not fixed up
        ldrb r2,data1   //此句:Error: internal_relocation (type: OFFSET_IMM) not fixed up
        nop
        mov pc,lr
_start:
        nop
       
.section .data
data1:
        .ascii        "hello world"
data2:
        .string "arm string"
.end

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-10-16 17:42:02 | 显示全部楼层
如果改为
ldrb r1,=data2
ldrb r2,=data1
则反汇编之后主要代码:
Disassembly of section .text:
30000000 <_start-0x1c>:
30000000:        e59f0014         ldr        r0, [pc, #20]        ; 3000001c <_start>
30000004:        e28f0010         add        r0, pc, #16 不管链接地址与执行地址相不相同,都是位置无关定位
30000008:        e59f0010         ldr        r0, [pc, #16]        ; 30000020 <_start+0x4>
3000000c:        e5df1010         ldrb        r1, [pc, #16]        ; 30000024 <_start+0x8> 对应指令ldrb r1,=data2其实是一个绝对地址定位,并不是相对地址定位
30000010:        e5df2010         ldrb        r2, [pc, #16]        ; 30000028 <_start+0xc>
30000014:        e1a00000         nop                        ; (mov r0, r0)
30000018:        e1a0f00e         mov        pc, lr

3000001c <_start>:
3000001c:        e1a00000         nop                        ; (mov r0, r0)
30000020:        3000001c         andcc        r0, r0, ip, lsl r0
30000024:        4000000b         andmi        r0, r0, fp
30000028:        40000000         andmi        r0, r0, r0

Disassembly of section .data:  注意:我们编译时用的是:arm-none-eabi-ld -Ttext=0x30000000 -Tdata=0x40000000 -Map ldrard.map -o ldradr.elf $^,所以数据段基址是0x40000000

40000000 <__data_start>:
40000000:        6c6c6568         cfstr64vs        mvdx6, [ip], #-416        ; 0xfffffe60  data1的数据,从右到左对应的ascii码为字母:“hell”
40000004:        6f77206f         svcvs        0x0077206f 从右到左对应的ascii码为字母:“o空格wo”
40000008:        61646c72         smcvs        18114        ; 0x46c2 从右到左对应的ascii码为字母:“rlda” 其实我们希望rld之后是C语言中对应的字符串结束符 \0

4000000b <data2>:
4000000b:        206d7261         rsbcs        r7, sp, r1, ror #4  data2的数据,从右到左对应的ascii码为字母:“arm空格”
4000000f:        69727473         ldmdbvs        r2!, {r0, r1, r4, r5, r6, sl, ip, sp, lr}^ 从右到左对应的ascii码为字母:“stri”
40000013:        Address 0x40000013 is out of bounds.  因为不是ARM指令,所了本行在反汇编中看不到,但用winhex查看可以看到有字母:“ng"

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2022-10-16 17:47:59 | 显示全部楼层
如果改为:
data1:
        .ascii        "hello world\000"
data2:
        .string "arm string\000"
反汇编之后:
Disassembly of section .data:

40000000 <__data_start>:
40000000:        6c6c6568         cfstr64vs        mvdx6, [ip], #-416        ; 0xfffffe60
40000004:        6f77206f         svcvs        0x0077206f
40000008:        00646c72         rsbeq        r6, r4, r2, ror ip 从右到左对应的ascii码为字母:“rld\0” 这才是我们希望的结果

4000000c <data2>:
4000000c:        206d7261         rsbcs        r7, sp, r1, ror #4
40000010:        69727473         ldmdbvs        r2!, {r0, r1, r4, r5, r6, sl, ip, sp, lr}^
40000014:        0000676e         andeq        r6, r0, lr, ror #14 同样地,从右到左是"ng\0\0",最后一个\0应该是汇编器自己加进去的,以补齐32位,以便地址4字节对齐而已

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-19 14:54 , Processed in 0.019757 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表