我在Cortex-M3中读到,它只是拇指,当我们写到PC时,我们必须确保目标地址LSB是'1‘,以确保处理器保持拇指模式。
此外,当我们使用'BX reg‘时,reg值必须有LSB =1来启用拇指模式。
当我们在大脑皮层中使用'B标签‘时,情况如何?由于16位/32位指令对齐到偶数地址,这个'label‘将有一个LSB =0的值。'B标签‘不等于'PC :=标签’吗?
“B标签”和“BL标签”的特殊情况是PC的写入不会影响处理器模式吗?
谢谢。
发布于 2014-03-06 03:23:50
目标地址需要bx (和blx)指令的lsbit a 1,当它进入pc时,该1被剥离。B指令是pc相对的,arm文档中显示的数学表明它是均匀的。
一般来说,如果你让工具完成他们的工作,在任何时候你都不用担心这个问题。
thumb.s
.thumb
.globl _start
_start:
b reset
nop
nop
.thumb_func
reset:
nop
nop
nop
nop
ldr r0,=reset
bx r0然后
arm-none-eabi-as thumb.s -o thumb.o
arm-none-eabi-ld -Ttext=0x1000 thumb.o -o thumb.elf
arm-none-eabi-objdump -D thumb.elf 这给
thumb.elf: file format elf32-littlearm
Disassembly of section .text:
00001000 <_start>:
1000: e001 b.n 1006 <reset>
1002: 46c0 nop ; (mov r8, r8)
1004: 46c0 nop ; (mov r8, r8)
00001006 <reset>:
1006: 46c0 nop ; (mov r8, r8)
1008: 46c0 nop ; (mov r8, r8)
100a: 46c0 nop ; (mov r8, r8)
100c: 46c0 nop ; (mov r8, r8)
100e: 4801 ldr r0, [pc, #4] ; (1014 <reset+0xe>)
1010: 4700 bx r0
1012: 10070000 andne r0, r7, r0
...枝条自己照顾自己
1000: e001 b.n 1006 <reset>
...
00001006 <reset>:分支中的编码是以16位数量为单位,而不是字节单位,然后将其乘以2 (shift it),得到始终是偶数的字节地址。pc从来不是奇数,而是你输入的bx或blx的值是奇怪的。
现在,因为我在重置之前使用了.thumb_func,它告诉汇编程序这是一个拇指标签,而不是手臂标签。因此,当我说请将重置地址加载到r0中时,汇编程序为值0x00001007分配了一些数据,这在反汇编过程中显示出很奇怪,但它就在那里。他们已经为我们设定了目标
00001006 <reset>:
...
100e: 4801 ldr r0, [pc, #4] ; (1014 <reset+0xe>)
1010: 4700 bx r0
1012: 10070000 andne r0, r7, r0现在,如果要删除.thumb_func
100c: 46c0 nop ; (mov r8, r8)
100e: 4801 ldr r0, [pc, #4] ; (1014 <reset+0xe>)
1010: 4700 bx r0
1012: 10060000 andne r0, r6, r0汇编程序认为这是一个arm地址,不设置lsbit,这段代码就会崩溃。现在,如果您关心它,您总是可以添加额外的orr r0,#1,但这实际上是一个黑客。学习如何将标签声明为拇指标签,而不是手臂。是的,很愚蠢的是,gnu汇编程序知道这个代码段是大拇指,因为我们告诉它,但是它不知道拇指代码中的标签是.拇指标签。非常愚蠢的工具。
我假设还有其他更详细的gnu汇编程序指令,它们也允许您声明这是一个函数或一个大拇指标签或其他任何东西。当然,每个汇编程序都是不同的,所以不要假设gnu汇编程序指令可以在其他汇编程序指令上工作。
如果将C和asm混合在一起,C编译器并不愚蠢,它知道-mthumb使所有函数和全局(标签)大拇指,并且取决于在代码中使用它们的方式和位置,链接器会放置正确的值。它甚至可以为您正确切换模式,在拇指代码中使用bl main,其中main是arm代码,并在切换模式的代码中放置蹦床。或者反之亦然,至少我已经看到该工具这样做了(并多次在堆栈溢出答案中演示)。我不记得它是否是棘手的让它工作,你应该总是定期拆卸,并确保链接器是为你这样做,否则它做它,或者你可以随时回到做它自己。
所以
请记住,只有bx和blx需要为拇指设置lsbit,需要为分支臂重置两个lsbit。blx和bx指令将删除这个lsbit,并在pc中留下一个偶数的pc (非常简单地做一个mov r0,pc,然后用拇指代码查看它)。
理想情况下,无条件的和有条件的分支(而不是bx)永远不应该切换模式--臂对臂,拇指到拇指。对于bl,我也看到了gnu工具在这方面的帮助,如果您希望您的代码是纯的,那么将地址加载到寄存器中,否则工具必须正确运行,否则整个工具链就会失败,blx而不是bl到该标签,而不是依赖于工具链为您做蹦床。
发布于 2014-02-23 21:17:49
'B标签‘不等于'PC :=标签’吗?
它实际上是在指令中编码偏移量的PC := PC + offset * 2。汇编程序/链接器必须计算此偏移量。
有关指令编码的详细信息,请参阅Armv7-M的ARM体系结构参考手册。
“B标签”和“BL标签”的特殊情况是PC的写入不会影响处理器模式吗?
是。最后一位是,而不是,在B(L) label指令中编码,因此拇指模式位不能更改。
https://stackoverflow.com/questions/21965365
复制相似问题