我正在尝试创建一个操作码以跳转到某个地址。
我查看了手册,我看到了:
B<c> <label>
31 30 29 28 | 27 26 25 24 | 23 ................. 0
cond 1 0 1 0 imm24
我不明白cond
和imm24
是什么。我如何创建一个操作码来分支到某个地址,例如分支到0xbeffffbc
?
答案 0 :(得分:5)
B
是相对分支,最高可达+/- 32MB。立即对当前PC的目标地址的有符号偏移进行编码(即该指令+8) - 注意该偏移量以字计算,而不是字节;由于指令始终是字对齐的,因此任何偏移的底部两位始终为00,因此在编码中隐含。
cond
与大多数其他ARM指令中的谓词字段相同。如果你已经开始探讨指令编码了,你可能应该知道这一点 - ARM ARM的“条件执行”部分(我方便的v7A / R版本的A8.3部分)已经完成了的信息。
ARM ARM的典型烦恼是,虽然编码字段和它们代表的值在指令描述中描述,但有时您必须交叉引用伪代码以确切地知道什么是继续。
答案 1 :(得分:1)
在大多数体系结构中,imm
是一个立即值(在实际指令中编码)。因此,我认为imm24
是一个24位长的立即值。此imm
值通常已签名。
大多数jmp
条指令都与当前Program Counter相关。这意味着编码到指令中的立即值被添加到程序计数器,该计数器将指向下一条指令。如果imm
值为负,则将从当前程序计数器中减去该值。否则,imm
值将添加到程序计数器中。
要创建地址0xbeffffbc
的分支,您需要知道当前指令的地址并计算它们之间的差异。
答案 2 :(得分:0)
如果您的分支指令位于0xb0并且您想跳转到0xbc,则编码指令的imm24部分的值为3.
你手指的imm24部分中的这个数字3告诉你[指示的数量]你从当前位置移动到你想去的地方。
imm24编码3而不是12的原因正如您所期望的那样(因为分支位于0xb0而您希望位于0xbc,差异为12)是因为在imm24中编码的偏移值是使用PC的值计算的寄存器,一个相对于地址分支的值是(0xb0),顺便说一句,它不是像你想象的那样是0xb0而是0xb8。
PC寄存器的值是指令地址分支前面的2条指令(由于流水线操作),所以分支指令的实际位置是0xb8而不是0xb0。
所以ARM指令的大小为4个字节,你移动3个指令,所以3 x 4会给你12个0xb0到0xbc的差异。
因此,如果你想完全按照上面的说法格式化你的指令
你会有一个操作码告诉处理器分支出现(一个特定的值),然后是一个可选的条件(cond部分)告诉你它应该在什么条件下进行这个分支,例如它是否小于或等于比上面解释的imm24部分会形成你的完整指导。
答案 3 :(得分:-1)
查看ARM指令集,您正在搜索分支指令。您可以轻松创建标签并跳转到它们(跳转到代码中的特定位置),虽然我不认为这是您想要做的。
如果要跳转到内存地址,有很多方法可以执行此操作(寻址模式)。立即寻址,间接寻址,...... 在这里,您应找到您要搜索的说明:ARM branch instructions
您应该真正了解寻址的工作原理。在汇编时进行编程以了解它的作用至关重要。
在这里您可以找到不同的寻址模式如何工作: ARM addressing modes Summary of the different addressing modes
基本上你需要知道你在内存中(不多于或少于比特)。因此,必须做出关于如何组织记忆的某些决定。某些部分或保留用于特定事物。
使用此内存,您只需记住最顶层位置(第一个空闲位置,即SP(堆栈指针))即可轻松构建堆栈。然后,您可以使用相对于堆栈指针的地址。这也是他们实施procedure calls的方式。
有关基础工作的信息: Working of the stack