[英]ARM disassembler output: When there are two arguments instead of three
我正在尝试为考试练习注释反汇编块。 这是我到目前为止所做的:
00000190 <mystery>:
190: 2300 movs r3, #0 // move address 190 (offset 0) into r3 ?
192: e004 b.n 19e <mystery+0xe> // if 19e then branch to mystery
194: f010 0f01 tst.w r0, #1 ; 0x1 // update flags to 1 in status register
198: bf18 it ne // if 198 not equal to ??? then ???
19a: 3301 addne r3, #1 // add to r3 if not equal to 19a offset 1?
19c: 1040 asrs r0, r0, #1 // shift r0 right one spot (leave it in r0)
19e: 2800 cmp r0, #0 // compare contents of r0 against 0 ?
1a0: d1f8 bne.n 194 <mystery+0x4> // branch to 194 if not equal to something at line 194?
1a2: 4618 mov r0, r3 // move r3 wholecloth into r0
1a4: 4770 bx lr // branch(return from the mystery function)
1a6: bf00 nop // No operation
因此,我的评论非常基本,并且可能非常不正确,但最重要的是,我真的不明白诸如 190 或 19a 之类的指令是什么意思。 只有两个 arguments 而不是三个,那么这些是如何工作的呢?
举个例子
19a: 3301 addne r3, #1
到目前为止,我对此的解释是:如果不等于 X,则将 Y 添加到 r3? X 和 Y 是什么? 我应该使用上一行的结果吗? 如果是这样,它取代了(标准三中的)哪个论点?
呸!
我愿意接受我不知道自己在做什么,并且完全误解了一切。
请发送帮助!
190: 2300 movs r3, #0 // assign the value 0 to R3, affecting
// the status flags (the S suffix)
19a: 3301 addne r3, #1 // add 1 to r3 IF the previous comparison was
// Not Equal to 0
ne
后缀检查先前由movs
指令设置的状态标志。
1) TST指令与ANDS基本相同,只是它不改变第一个操作数。 因此, TST r0, #1
根据 (r0 & 1) 的结果设置标志。 具体来说,如果结果为零,即未设置 r0 的位 0,它将设置 Z(零)标志。
2) IT代表“如果-那么” 。 它检查指示的条件,并有条件地执行最多 4 条以下指令。 在您的示例中,您只有一条条件指令,反汇编程序提供了 IT 指令中的 NE 后缀(后缀未在 Thumb-2 的指令本身中编码)。 NE 的意思是“不相等”,但在这种情况下没有比较,那么给出了什么? 诀窍是相等检查检查 Z 标志,因此您可以将其视为“非零”。 因此,我们的 ADD 将在 Z 标志未设置的情况下执行,即 r0确实设置了位 0。
3)类似的情况发生在CMP/BNE周围。 CMP 基本上减去操作数并根据结果设置标志。 在我们的例子中,如果 r0 等于 0,它将设置 Z。接下来,BNE 将测试 Z 标志,如果没有设置则分支(即 r0不等于 0)。
将其全部转换为伪 C,我们得到:
r3 = 0
goto test_loop;
loop:
Z = (r0 & 1) == 0;
if (!Z)
r3 += 1;
r0 = r0 >> 1
test_loop:
Z = (r0 - 0) == 0;
if (!Z) goto loop;
r0 = r3;
return;
或者,在“正常”C 中:
r3 = 0;
while ( r0 != 0 )
{
if ( r0 & 1 )
r3++;
r0 >>= 1;
}
return r3;
看起来它正在计算 r0 中的位。
在这里查看条件代码表以及它们检查的标志。这描述了设置标志的方式和时间。
编辑:我刚刚重读了您的问题,并意识到您的困惑之一。 像这样排列:
b.n 19e <mystery+0xe>
有一个操作数,而不是两个。 反汇编程序试图提供帮助,不仅显示绝对目标地址 (19e),还显示其表示为与最近符号的偏移量(神秘在 190,所以 19e 是神秘+0xe)。
您需要意识到的另一件事是,在 ARM(和许多其他处理器)中,设置标志和使用标志通常在单独的指令中完成。 这就是为什么您首先执行 TST 或 CMP(或其他标志设置指令),然后使用条件指令、IT 或条件分支。
如果您查看 ARM ARM (ARM 架构参考手册),它的前面有一个关于标志的部分。 与许多其他指令集不同,如果您查看 ARM 指令,特别是 ARM 风格(不是拇指),每条指令的前四位都是条件位。 与大多数其他处理器不同,使用 arm 您可以有条件地执行任何指令,大多数其他处理器只允许条件分支。 条件代码 ne、nz、cs、nc 等在条件代码的早期部分中列出。 因此,如果清除零标志,则添加将是 addne。 与大多数其他处理器不同,ARM(在 arm 模式下)允许您选择何时要销毁/写入标志。 大多数其他人总是会在添加时更新标志,例如,arm 仅在您添加 s 时才会这样做,添加不会添加。 当您将条件执行和这些其他修饰符组合到指令中时,它会变得很棘手,例如它是 addne 还是 addnes? 这需要反复试验才能弄清楚。 我猜是addnes,但我很少使用这样的组合,以至于我没有记住它。
正如已经提到的,反汇编器创建了一些不可汇编的东西,output 上还有其他项目可以帮助您解码指令。
看起来您正在查看 thumb2 代码,它是 ARM 和 thumb 的科学怪人混合物。 因此,您将拥有一些 arm 功能和一些拇指功能,至少对于 binutils 有一些烦人的 binutils-isms(不再有 arm 工具链可比较)。 例如,即使我们知道许多 thumb 指令在没有选项的情况下修改标志,并且反汇编程序通过给出添加而不是添加来显示这一点,但您不能将添加 r1,r2 用于拇指模式,因为它会抱怨,它希望您使用即使您正在修改标志,也要添加 r1,r2。 ARM 正在努力推动统一的 arm/thumb 汇编语法,这可能已经适用于他们的工具链,但必须看看 gnu 工具会发生什么。
因此,出于这两个原因,我不希望能够进行反汇编 output 并重新组装该语法。 额外的东西可以帮助您理解编码的特定指令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.