我试图弄清楚TBB在手臂装配中如何工作的细节。我只是想找出一个简单的例子,但无论我的代码去无限循环或不编译。
.syntax unified
.thumb
BranchTable_Byte:
.byte 0 @; Case1 offset calculation
.byte ((Case2-Case1)/2) @; Case2 offset calculation
.byte ((Case3-Case1)/2) @; Case3 offset calculation
.text
.global example_TBB
.thumb_func
example_TBB:
mov r1, #1
ADR.W r0, BranchTable_Byte
TBB [r0, r1] @; R1 is the index, R0 is the base address of the branch table
Case1:
@; an instruction sequence follows
mov r2, #1
b endTBB
Case2:
@; an instruction sequence follows
mov r3, #2
b endTBB
Case3:
@; an instruction sequence follows
mov r4, #3
b endTBB
endTBB:
bx lr
字符串
我相信应该发生的是,由于r1=1,tbb操作代码应该分支到情况2,但我得到无限循环和/或编译错误,无论我玩了多久。
1条答案
按热度按时间5n0oy7gb1#
所以
字符串
待定
型
为文本和数据地址创建一个位置并不重要,这是为了看看工具在做什么:
型
你看,这是个大问题如何将表中的3个字节的数据放入两个字节中?
你的代码暗示你可能想这样做:
型
哇,这更糟糕(好吧,这是一个ADR,而不是加载地址):
型
表的深度为3个字节,为了对齐,可以使用4个字节
型
给予
型
好多了:现在4个字节能装下4个字节。那很好。但更好的是,如果你把数据与代码内联,你应该对齐,或者把数据放在后面:
型
这也解决了问题
型
你可能希望你的表在.text中,这是你指定的地方。如果你把它放进.data,那么你必须把它从flash到ram假设这是一个微控制器。但你需要做的事情略有不同。
型
你不讨厌他们这样做吗?
型
这是一种更好的方法:
型
但是现在你有了.data,你不需要它是. data。
请注意,如果你将其与编译后的代码链接,你的编译器可能符合arm调用约定,即你不能在函数中修改r4,你必须保留它。这就是为什么我修改了您的代码(我想您是从我那里得到的,当我为您将它移植到gas时?))
我忘了,拇指在so. s。这很好,不是感兴趣的代码,不打算修复上面,但将在下面你可能想添加一些更多的偏执狂的代码,为什么不洒它与. aligns...
所以
型
待定
型
给予
型
这是一个完整的程序,你可以在你的stm32上运行,并使用openocd停止并检查寄存器,当完成时,看看r0被设置为什么。你也可以这样做
型
0x20000000处的ram链接
型
然后您可以加载它,运行它,停止并检查来自openocd的r0与您的STM32对话。