首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Cortex-M3 (拇指)中使用B指令

在Cortex-M3 (拇指)中使用B指令
EN

Stack Overflow用户
提问于 2014-02-23 07:20:07
回答 2查看 2.2K关注 0票数 1

我在Cortex-M3中读到,它只是拇指,当我们写到PC时,我们必须确保目标地址LSB是'1‘,以确保处理器保持拇指模式。

此外,当我们使用'BX reg‘时,reg值必须有LSB =1来启用拇指模式。

当我们在大脑皮层中使用'B标签‘时,情况如何?由于16位/32位指令对齐到偶数地址,这个'label‘将有一个LSB =0的值。'B标签‘不等于'PC :=标签’吗?

“B标签”和“BL标签”的特殊情况是PC的写入不会影响处理器模式吗?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-06 03:23:50

目标地址需要bx (和blx)指令的lsbit a 1,当它进入pc时,该1被剥离。B指令是pc相对的,arm文档中显示的数学表明它是均匀的。

一般来说,如果你让工具完成他们的工作,在任何时候你都不用担心这个问题。

thumb.s

代码语言:javascript
复制
.thumb

.globl _start
_start:
    b reset
    nop
    nop
.thumb_func
reset:
    nop
    nop
    nop
    nop
    ldr r0,=reset
    bx r0

然后

代码语言:javascript
复制
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 

这给

代码语言:javascript
复制
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
    ...

枝条自己照顾自己

代码语言:javascript
复制
    1000:   e001        b.n 1006 <reset>
...    
00001006 <reset>:

分支中的编码是以16位数量为单位,而不是字节单位,然后将其乘以2 (shift it),得到始终是偶数的字节地址。pc从来不是奇数,而是你输入的bx或blx的值是奇怪的。

现在,因为我在重置之前使用了.thumb_func,它告诉汇编程序这是一个拇指标签,而不是手臂标签。因此,当我说请将重置地址加载到r0中时,汇编程序为值0x00001007分配了一些数据,这在反汇编过程中显示出很奇怪,但它就在那里。他们已经为我们设定了目标

代码语言:javascript
复制
00001006 <reset>:
 ...
    100e:   4801        ldr r0, [pc, #4]    ; (1014 <reset+0xe>)
    1010:   4700        bx  r0
    1012:   10070000    andne   r0, r7, r0

现在,如果要删除.thumb_func

代码语言:javascript
复制
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到该标签,而不是依赖于工具链为您做蹦床。

票数 1
EN

Stack Overflow用户

发布于 2014-02-23 21:17:49

'B标签‘不等于'PC :=标签’吗?

它实际上是在指令中编码偏移量的PC := PC + offset * 2。汇编程序/链接器必须计算此偏移量。

有关指令编码的详细信息,请参阅Armv7-M的ARM体系结构参考手册。

“B标签”和“BL标签”的特殊情况是PC的写入不会影响处理器模式吗?

是。最后一位是,而不是,在B(L) label指令中编码,因此拇指模式位不能更改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21965365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档