浮点臂拆卸说明

时间:2011-08-12 14:43:05

标签: assembly floating-point arm disassembly

我正试图在c ++中重新创建以下的手臂反汇编:

00003188    ed910a06    flds    s0, [r1, #24]
0000318c    edd10a07    flds    s1, [r1, #28]
00003190    ec800a02    fstmias r0, {s0-s1}
00003194        4770    bx  lr
00003196        bf00    nop

首先,s0是一个单一的进动登记册吗? flsl和fstmias做了什么。我尝试了以下代码,但它不会产生相同的结果:

float s0 = r1[6];
float s1 = r1[7];

我试过的是什么问题?

1 个答案:

答案 0 :(得分:4)

因为它是一个非常简单的功能,让我们逐行采取。我假设您发布了完整的功能。

00003188    ed910a06    flds    s0, [r1, #24]

FLDS位于此表单上:“FLD< precision> {cond} Fd,[Rn {,#offset}]”,精度为s(=单精度)。正如文档所述,这会将位于r1 + 24的单个精度浮点值加载到s0

0000318c    edd10a07    flds    s1, [r1, #28]

另一次加载,这次来自r1 + 28(这对应于您使用r1[7]编写的内容)。

00003190    ec800a02    fstmias r0, {s0-s1}

FSTMIAS列出“FSTM< addressmode>< precision> {cond} Rn,{!} VFPregisters”。这里有addressmode = IA,表示“每次传输后递增地址”,精度=单次。该指令将指定的寄存器存储到r0中指定的地址,在每个存储之后递增地址。换句话说,它将s0存储在[r0],将s1存储在[r0+4]

00003194        4770    bx  lr

BX是分支(并可选择更改回ARM模式)以注册值 - 从函数返回的首选方式(请参阅第5.1节here)。在这种情况下,寄存器是保存返回地址的链接寄存器。

00003196        bf00    nop

没有操作。什么都不做,通常插入以对齐内存中的函数。

ARM-THUMB的calling convention(4.1节)声明前四个参数在r0-r3(== a1-a4)中传递,我们从反汇编中可以看出r0和r1是这样使用的,所以该函数需要2个参数。不清楚函数是返回值(与第一个输入相同)还是不返回值。您将不得不查看呼叫网站来解决这个问题。

在C语言中,我们有一个函数,它将两个指针值作为输入,从第二个参数中的偏移量24和28加载两个float,并将它们存储在第一个参数的偏移量0和4中。如果不了解程序,就无法判断参数是否应该是数组,结构或其他东西。

假设它们是数组,那么对C的翻译是微不足道的:

void mystery_function(float* dst, const float* src) {
    dst[0] = src[6];
    dst[1] = src[7];
}