Assembly 通过阅读.hex和.map,如何确保BL链接到正确的函数偏移?

Assembly 通过阅读.hex和.map,如何确保BL链接到正确的函数偏移?,assembly,arm,stm32,machine-code,instruction-set,Assembly,Arm,Stm32,Machine Code,Instruction Set,我目前正在做一个“十六进制比较”,以了解发生了什么 我知道比较十六进制有时会带来太多的变化,无法进行比较 通过改变一个函数调用,我可以在十六进制中做一个小的改变。 我的嵌入式代码包含Foo(5),我将其替换为条(5)(签名相同),然后通过Bla(5) 当我比较十六进制文件时,我有以下内容: 绿色部分是CRC 在hex文件和map文件的帮助下,我如何确保Foo确实被Bar或Bla取代,而不是被另一个函数取代 这是我在ARMv7-M arch doc中发现的。但即使知道了偏移量,我仍然不知道我是

我目前正在做一个“十六进制比较”,以了解发生了什么

我知道比较十六进制有时会带来太多的变化,无法进行比较

通过改变一个函数调用,我可以在十六进制中做一个小的改变。 我的嵌入式代码包含
Foo(5),我将其替换为
条(5)(签名相同),然后通过
Bla(5)

当我比较十六进制文件时,我有以下内容:

绿色部分是CRC

在hex文件和map文件的帮助下,我如何确保Foo确实被Bar或Bla取代,而不是被另一个函数取代

这是我在ARMv7-M arch doc中发现的。但即使知道了偏移量,我仍然不知道我是否能从中找出一些东西…如何在机器代码中转录.map地址

在.map中,相应的地址为:


我正在使用IAR编译器开发STM32L4xx(cortex M4)。

正如往常一样,您需要该核心的arm体系结构参考手册(以及技术参考手册)。cortex-m4 trm将告诉您这是一个armv7-m架构,您可以为此获得arm

BL是两个独立的指令,尽管它通常显示为32,但它们不必背靠背执行,而是必须以正确的顺序执行(并且不能在两者之间混用lr)

所以

或者编写一个程序(不处理H=10上的符号扩展,因为您没有设置这些位)

有关bl指令的地址是什么?作为intel十六进制文件,无法根据您提供的内容确定。(我更喜欢32位地址的srec)

旧的/最旧的ARM,armv5版本更适合查看这两条指令,但该文档中有一个打字错误/错误-thumb版本-您没有去掉两个较低的位,这将是该指令的ARM版本

.thumb
bl here
nop
bl here
nop
nop
nop
here:



00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)


PC(inst)+0x00000010
PC(inst)+0x0000000A
.thumb
这里是bl
不
这里是bl
不
不
不
在这里:
00000000 :
0:f000 f806 bl 10
4:46c0 nop;(mov r8,r8)
6:f000 f803 bl 10
a:46c0 nop;(mov r8,r8)
c:46c0 nop;(mov r8,r8)
e:46c0 nop;(mov r8,r8)
PC(仪表)+0x00000010
PC(仪表)+0x0000000A
啊,好吧,使用gnu汇编程序,你不能只使用.word或.hword技巧,必须使用.inst.n

.thumb
bl here
nop
bl here
nop
nop
nop
here:
.inst.n 0xf000
.inst.n 0xf806

00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)

00000010 <here>:
  10:   f000 f806   bl  20 <here+0x10>
.thumb
这里是bl
不
这里是bl
不
不
不
在这里:
.inst.n 0xf000
.安装编号0xf806
00000000 :
0:f000 f806 bl 10
4:46c0 nop;(mov r8,r8)
6:f000 f803 bl 10
a:46c0 nop;(mov r8,r8)
c:46c0 nop;(mov r8,r8)
e:46c0 nop;(mov r8,r8)
00000010 :
10:f000 f806 bl 20
和你的一个

.thumb
.inst.n 0xF0E6
.inst.n 0xFC03

00000000 <.text>:
   0:   f0e6 fc03   bl  e680a <.text+0xe680a>
.thumb
.inst.n 0xF0E6
.仪器编号0xFC03
00000000 :
0:f0e6 fc03 bl e680a

为什么不呢?您应该能够通过查看映射文件中这些函数的地址进行检查,并检查偏移量的差异是否匹配。这不是代码,至少不是链接代码。例如,第一个有,
和pc,r3,r6,ror#25
,这是一条无意义指令。也应该称之为“英特尔十六进制”,而不是十六进制转储。你应该输入地址。从图片中进行翻译需要很长时间才能获得二进制文件,以便在值上运行
objdump
。另外,提供源文件和映射文件的相关部分也会有所帮助,请提供这些地址的映射文件中的地址,Foo,Bar,Bla…为什么你认为链接器没有完成它的工作?我肯定链接器完成了它的工作,我只是对此感到好奇。
PC(inst)+0x000E680A
PC(inst)+0x00008A0A
PC(inst)+0x000C780A
.thumb
bl here
nop
bl here
nop
nop
nop
here:



00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)


PC(inst)+0x00000010
PC(inst)+0x0000000A
.thumb
bl here
nop
bl here
nop
nop
nop
here:
.inst.n 0xf000
.inst.n 0xf806

00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)

00000010 <here>:
  10:   f000 f806   bl  20 <here+0x10>
.thumb
.inst.n 0xF0E6
.inst.n 0xFC03

00000000 <.text>:
   0:   f0e6 fc03   bl  e680a <.text+0xe680a>