Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 有人能解释一下ARM中的分支操作码吗?_Assembly_Arm_Armv7_Opcode - Fatal编程技术网

Assembly 有人能解释一下ARM中的分支操作码吗?

Assembly 有人能解释一下ARM中的分支操作码吗?,assembly,arm,armv7,opcode,Assembly,Arm,Armv7,Opcode,我正在尝试创建一个操作码以跳转到一个地址 我查看了手册,发现: B<c> <label> 31 30 29 28 | 27 26 25 24 | 23 ................. 0 cond 1 0 1 0 imm24 B 31 30 29 28 | 27 26 25 24 | 23 ................. 0 条件1 0 1 0 imm24 我不明白什么是cond和imm24。如何创建操作码以分支到某

我正在尝试创建一个操作码以跳转到一个地址

我查看了手册,发现:

B<c> <label>

31 30 29 28 | 27 26 25 24 | 23 ................. 0
    cond      1  0  1  0          imm24
B
31 30 29 28 | 27 26 25 24 | 23 ................. 0
条件1 0 1 0 imm24

我不明白什么是
cond
imm24
。如何创建操作码以分支到某个地址,例如分支到
0xbefffbc

查看ARM指令集,您正在搜索分支指令。您可以轻松地创建标签并跳转到它们(跳转到代码中的特定位置),尽管我认为这不是您想要做的

如果想跳转到内存地址,有很多方法(寻址模式)。直接寻址,间接寻址。。。 您可以在此处找到正在搜索的说明:

您应该真正了解寻址是如何工作的。在汇编中编程时,理解它的功能是至关重要的

在这里,您可以找到不同寻址模式的工作原理:

基本上你需要知道你在内存中(不多于或少于位)。因此,必须就如何组织记忆做出某些决定。某些部分或为特定事物保留的部分

使用此内存,只需记住最顶端位置(第一个空闲位置,即SP(堆栈指针))的地址,即可轻松构建堆栈。然后可以使用相对于堆栈指针的地址。这也是他们实施的方式

有关基础工作环境的信息:

在大多数体系结构上,
imm
是一个立即值(在实际指令中编码)。因此,我假设
imm24
是一个24位长的立即值。此
imm
值通常是有符号的

大多数
jmp
指令都是与当前指令相关的。这意味着编码到指令中的立即数被添加到程序计数器中,该计数器将指向下一条指令。如果
imm
值为负值,将从当前程序计数器中减去该值。否则,
imm
值将添加到程序计数器中

要创建指向地址的分支,您需要知道当前指令的地址并计算它们之间的差异。

B
是一个高达+/-32MB的相对分支。立即数对当前PC的目标地址的有符号偏移量进行编码(即,该指令+8)-注意,该偏移量以字而不是字节计算;因为指令总是字对齐的,所以任何偏移量的底部两位总是00,因此在编码中是隐式的

cond
与大多数其他ARM指令中的谓词字段相同。如果您已经了解了指令编码,您可能已经知道了——ARM的“条件执行”部分(v7A/R版本中的A8.3部分我手边有)有完整的细节


ARM的典型问题是,虽然指令描述中描述了编码字段及其表示的值,有时,您确实需要交叉引用伪代码以准确了解发生了什么。

如果分支指令位于0xb0,并且您希望跳转到0xbc,则编码指令的imm24部分的值将为3

指令imm24部分中的数字3告诉您[指令数量],您正在从当前位置移动到您想去的位置

imm24按预期编码3而不是12的原因(因为分支位于0xb0,而您希望位于0xbc,差值为12)是因为imm24中编码的偏移量值是使用PC寄存器的值计算的,相对于地址分支的值位于(0xb0)顺便说一句,它不是你想象中的0xb0,而是0xb8

PC寄存器的值为指令地址分支前2条指令(由于流水线),因此分支指令的实际位置为0xb8而不是0xb0

所以ARM指令的大小是4字节,你要移动3条指令,所以3x4会给你12个0xb0到0xbc的差值

所以如果你想完全按照上面的格式来编排你的指令


您将有一个操作码,它告诉处理器分支即将出现(一个特定值),然后是一个可选条件(cond部分),它告诉您在什么条件下应该进行此分支,例如,如果小于或大于,然后是上面解释的imm24部分,这将构成完整的指令。

如果我的分支指令位于地址0xBEFFFB0,并且我想跳到0xBEFFFBC,那么它应该是分支+3吗?他说偏移量是以字计算的。所以我认为这意味着在我的例子中:我有0xbefffb0,0xbefffb4,0xbefffb8,oxbefffffbc。我看到它有3个字了?@user2378481在0xbefffb0处,它将是0xbefffb8,所以你实际上在分支中编码+1。如果您检查一些拆卸,可能会变得更清楚-例如,看到a b。无限循环编码的偏移量为-2(有趣的是,与x86上的等效操作的偏移量相同,但原因完全不同)。