- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试学习对固件修改有用的技能(我没有源代码)
这些问题涉及使用 BX 从拇指代码跳转或调用其他现有拇指代码。
1
为了保持cpu状态为“拇指状态”。
LDR R6, =0x24000
ADD R6, #1 @ (set lsb to 1)
BX R6
ldr r2, =0x24000
mov lr, pc
bx r2
bx r2
切换模式到ARM模式?? BX LR
, ... 嗯.. 怎么能返回到我的 THUMB 代码呢?我肯定错过了什么...
BL
THUMB 指令,将 LR 设置为
return addr + 1
自动地?
最佳答案
哇,谢谢你叫我出来这个。我知道我在 http://github.com/dwelch67/yagbat 中尝试了 qemu 代码并认为 XPUT32 以您描述的方式调用 PUT32,并且它起作用了。但它似乎不起作用。我创建了许多实验并且很惊讶,这不是我所期望的。现在我明白了为什么 gnu 链接器会做它所做的。抱歉,这是一个很长的回复,但我认为它非常有值(value)。这是一个令人困惑的话题,我知道多年来我一直认为电脑会拖拽模式位,但事实并非如此。
在我开始下面的实验之前,如果你要这样做:
LDR R6, =0x24000
ADD R6, #1 @ (set lsb to 1)
BX R6
LDR R6, =0x24001
BX R6
bx
带有一个包含地址加一的寄存器。
ldr r6,=something
bx r6
.thumb
ping:
ldr r0,=pong
bx r0
.code 32
pong:
ldr r0,=ping
bx r0
d6008148 <ping>:
d6008148: 4803 ldr r0, [pc, #12] ; (d6008158 <pong+0xc>)
d600814a: 4700 bx r0
d600814c <pong>:
d600814c: e59f0008 ldr r0, [pc, #8] ; d600815c <pong+0x10>
d6008150: e12fff10 bx r0
d6008158: d600814c strle r8, [r0], -ip, asr #2
d600815c: d6008148 strle r8, [r0], -r8, asr #2
pong
想从 0xD600815C 中提取拇指地址,但得到了一个 ARM 地址。
.thumb_func
在要声明为拇指标签的标签之前(术语 func 暗示函数具有误导性,不要担心
.thumb_func
意味着它只是一个汇编器/链接器游戏)。
.thumb
.thumb_func
ping:
ldr r0,=pong
bx r0
.code 32
pong:
ldr r0,=ping
bx r0
d6008148 <ping>:
d6008148: 4803 ldr r0, [pc, #12] ; (d6008158 <pong+0xc>)
d600814a: 4700 bx r0
d600814c <pong>:
d600814c: e59f0008 ldr r0, [pc, #8] ; d600815c <pong+0x10>
d6008150: e12fff10 bx r0
d6008158: d600814c strle r8, [r0], -ip, asr #2
d600815c: d6008149 strle r8, [r0], -r9, asr #2
lsbit
设置,以便您不必做任何工作。例如,当您调用 C 函数时,编译器会处理所有这些。对于汇编程序,尽管您必须使用该
.thumb_func
(或其他一些指令,如果有的话)让气体知道这是一个拇指标签并设置
lsbit
为你。
testthumb
ARM7TDMI 和 qemu 上的函数 1 到 4 具有相同的结果。
.globl testarm
testarm:
mov r0,pc
bx lr
armbounce:
mov r0,lr
bx lr
.thumb
.thumb_func
.globl testthumb1
testthumb1:
mov r0,pc
bx lr
nop
nop
nop
bounce:
bx lr
.thumb_func
.globl testthumb2
testthumb2:
mov r2,lr
mov r0,pc
bl bounce
bx r2
nop
nop
nop
.thumb_func
.globl testthumb3
testthumb3:
mov r2,lr
mov lr,pc
mov r0,lr
bx r2
nop
nop
nop
.thumb_func
.globl testthumb4
testthumb4:
push {lr}
ldr r2,=armbounce
mov r1,pc ;@ -4
add r1,#5 ;@ -2
mov lr,r1 ;@ +0
bx r2 ;@ +2
pop {r2} ;@ +4
bx r2
.thumb_func
.globl testthumb5
testthumb5:
push {lr}
ldr r2,=armbounce
mov lr,pc
bx r2
pop {r2}
bx r2
.thumb_func
.globl testthumb6
testthumb6:
push {lr}
bl testthumb6a
.thumb_func
testthumb6a:
mov r0,lr
pop {r2}
bx r2
.thumb_func
.globl testthumb7
testthumb7:
push {lr}
bl armbounce_thumb
pop {r2}
bx r2
.thumb_func
.globl testthumb8
testthumb8:
push {lr}
bl armbounce_thumb_two
pop {r2}
bx r2
.align 4
armbounce_thumb:
ldr r1,[pc]
bx r1
.word armbounce
nop
.align 4
armbounce_thumb_two:
bx pc
nop
.code 32
b armbounce
d60080b4 <testarm>:
d60080b4: e1a0000f mov r0, pc
d60080b8: e12fff1e bx lr
d60080bc <armbounce>:
d60080bc: e1a0000e mov r0, lr
d60080c0: e12fff1e bx lr
d60080c4 <testthumb1>:
d60080c4: 4678 mov r0, pc
d60080c6: 4770 bx lr
d60080c8: 46c0 nop ; (mov r8, r8)
d60080ca: 46c0 nop ; (mov r8, r8)
d60080cc: 46c0 nop ; (mov r8, r8)
d60080ce <bounce>:
d60080ce: 4770 bx lr
d60080d0 <testthumb2>:
d60080d0: 4672 mov r2, lr
d60080d2: 4678 mov r0, pc
d60080d4: f7ff fffb bl d60080ce <bounce>
d60080d8: 4710 bx r2
d60080da: 46c0 nop ; (mov r8, r8)
d60080dc: 46c0 nop ; (mov r8, r8)
d60080de: 46c0 nop ; (mov r8, r8)
d60080e0 <testthumb3>:
d60080e0: 4672 mov r2, lr
d60080e2: 46fe mov lr, pc
d60080e4: 4670 mov r0, lr
d60080e6: 4710 bx r2
d60080e8: 46c0 nop ; (mov r8, r8)
d60080ea: 46c0 nop ; (mov r8, r8)
d60080ec: 46c0 nop ; (mov r8, r8)
d60080ee <testthumb4>:
d60080ee: b500 push {lr}
d60080f0: 4a15 ldr r2, [pc, #84] ; (d6008148 <armbounce_thumb_two+0x8>)
d60080f2: 4679 mov r1, pc
d60080f4: 3105 adds r1, #5
d60080f6: 468e mov lr, r1
d60080f8: 4710 bx r2
d60080fa: bc04 pop {r2}
d60080fc: 4710 bx r2
d60080fe <testthumb5>:
d60080fe: b500 push {lr}
d6008100: 4a11 ldr r2, [pc, #68] ; (d6008148 <armbounce_thumb_two+0x8>)
d6008102: 46fe mov lr, pc
d6008104: 4710 bx r2
d6008106: bc04 pop {r2}
d6008108: 4710 bx r2
d600810a <testthumb6>:
d600810a: b500 push {lr}
d600810c: f000 f800 bl d6008110 <testthumb6a>
d6008110 <testthumb6a>:
d6008110: 4670 mov r0, lr
d6008112: bc04 pop {r2}
d6008114: 4710 bx r2
d6008116 <testthumb7>:
d6008116: b500 push {lr}
d6008118: f000 f80a bl d6008130 <armbounce_thumb>
d600811c: bc04 pop {r2}
d600811e: 4710 bx r2
d6008120 <testthumb8>:
d6008120: b500 push {lr}
d6008122: f000 f80d bl d6008140 <armbounce_thumb_two>
d6008126: bc04 pop {r2}
d6008128: 4710 bx r2
d600812a: 46c0 nop ; (mov r8, r8)
d600812c: 46c0 nop ; (mov r8, r8)
d600812e: 46c0 nop ; (mov r8, r8)
d6008130 <armbounce_thumb>:
d6008130: 4900 ldr r1, [pc, #0] ; (d6008134 <armbounce_thumb+0x4>)
d6008132: 4708 bx r1
d6008134: d60080bc ; <UNDEFINED> instruction: 0xd60080bc
d6008138: 46c0 nop ; (mov r8, r8)
d600813a: 46c0 nop ; (mov r8, r8)
d600813c: 46c0 nop ; (mov r8, r8)
d600813e: 46c0 nop ; (mov r8, r8)
d6008140 <armbounce_thumb_two>:
d6008140: 4778 bx pc
d6008142: 46c0 nop ; (mov r8, r8)
d6008144: eaffffdc b d60080bc <armbounce>
d6008148: d60080bc ; <UNDEFINED> instruction: 0xd60080bc
d600814c: e1a00000 nop ; (mov r0, r0)
D60080BC testarm
D60080C8 testthumb1
D60080D6 testthumb2
D60080E6 testthumb3
D60080FB testthumb4
testthumb5 crashes
D6008111 testthumb6
D600811D testthumb7
D6008127 testthumb8
lsbit
,我知道您知道在执行 bx 指令时要设置或不设置它。
Program counter Register 15 is the Program Counter (PC). It can be used in most
instructions as a pointer to the instruction which is two instructions after
the instruction being executed...
testarm
验证程序计数器是否超前 8 个字节。这也是两个指令。
testthumb1
验证程序提前 4 个字节,在这种情况下也是两条指令。
testthumb2
:
d60080d2: 4678 mov r0, pc
d60080d4: f7ff fffb bl d60080ce <bounce>
d60080d8: 4710 bx r2
testthumb3
是希望
mov lr,pc
很特别,其实不是。
lsbit
程序计数器的未设置,我想这对于例如分支表是有意义的。所以
mov lr,pc
在拇指模式下不会为返回设置链接寄存器。
testthumb4
如果您在
mov r1,pc
之间更改该指令序列,则会以一种非常痛苦的方式获取程序计数器,无论该代码发生在何处结束,并根据精心放置的指令计算返回地址。和
bx r2
你必须返回添加。现在为什么我们不能做这样的事情:
add r1,pc,#1
bx r2
testthumb5
直接来自我向您展示的导致此问题的一部分的代码,并且它崩溃了。这不是它的工作原理,对不起,我误导了人们,我会尝试回去修补我使用过的 SO 问题。
testthumb6
是一个实验,以确保我们都没有疯。一切都很好,链接寄存器确实得到了
lsbit
设置以便当您
bx lr
后来它知道了那个位的模式。
testthumb7
,这是从 ARM 侧蹦床派生而来的,当您从 ARM 模式转到拇指模式时,您会看到链接器所做的 Action ,在这种情况下,尽管我将从拇指模式转到 ARM 模式。为什么链接器不能这样做?因为在拇指模式下,至少你必须使用一个低寄存器,而在游戏的这一点上,在编译代码之后,链接器无法知道它可以丢弃哪个寄存器。在 arm 模式下,虽然 ip 寄存器(不确定可能是 r12 是什么)可能会被丢弃,但我猜它是保留供编译器使用的。在这种情况下,我知道
r1
可以被丢弃并使用它,这可以按需要工作。 armbounce 代码被调用,它在返回到哪里时获取链接寄存器,这是在
lsbit set
之后的拇指指令(
bl armbounce_thumb
)。在
testthumb7
功能,正是我们想要的地方。
testthumb8
这就是 gnu 链接器在需要从拇指模式到 ARM 模式时的工作方式。
bl
指令设置为去蹦床。然后他们做了一些非常非常棘手的事情,看起来很疯狂:
d6008140 <armbounce_thumb_two>:
d6008140: 4778 bx pc
d6008142: 46c0 nop ; (mov r8, r8)
d6008144: eaffffdc b d60080bc <armbounce>
bx pc
.我们从上面的实验中知道
pc
前面四个字节,我们也知道
lsbit
未设置。因此,这意味着跳转到 ARM CODE 之后的四个字节。
nop
是一个两字节的间隔,那么我们必须在四个字节之前生成一条 ARM 指令并在四字节边界上对齐,然后我们将其无条件分支到我们要去的任何地方,这可能是 b 某物或
ldr pc
,= 取决于你需要走多远。非常棘手。
bl arm_bounce_thumb_two
设置链接寄存器返回之后的指令
bl
.蹦床不会修改链接寄存器,它只是执行分支。
...
bl myfun_from_arm
...
myfun_from_arm:
ldr ip,[pc]
bx ip
.word myfun
101f8: eb00003a bl 102e8 <__testthumb1_from_arm>
000102e8 <__testthumb1_from_arm>:
102e8: e59fc000 ldr ip, [pc] ; 102f0 <__testthumb1_from_arm+0x8>
102ec: e12fff1c bx ip
102f0: 00010147 andeq r0, r1, r7, asr #2
r12
?),他们都不介意把它扔掉,我想你可以自己扔掉它。
关于gcc - 在 Thumb 代码中使用 BX 调用 Thumb 函数,或跳转到另一个函数中的 Thumb 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9368360/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!