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>