C语言转换成ARM汇编代码

3

我已经用C语言编写了一个程序,并将其转换为ARM汇编代码,现在我在理解汇编代码中生成的一些指令时遇到了问题。C程序的一部分如下:

#define MAX_DIGIT 1024
int main()
{
    int fd[MAX_DIGIT];
    int xLen = 0;
    int sd[MAX_DIGIT];
    int yLen = 0;

    int result[6*MAX_DIGIT];

    // Take input for two numbers
    takeInput(fd, &xLen);
    takeInput(sd, &yLen);   
        ...
        ...
        ...
}
...
...
...

void takeInput(int digit[], int *length)
{
    char c;
    if((c=getchar()) != '\n' && *length <= MAX_DIGIT){
        takeInput(digit, length);
        digit[*length] = c - '0';
        (*length)++;
    }else return;
}

我使用GNU ARM工具链将这段C代码转换为ARM汇编代码。其中生成的汇编代码的一部分如下:

main:
    @ args = 0, pretend = 0, frame = 32788
    @ frame_needed = 1, uses_anonymous_args = 0
    mov ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub fp, ip, #4
    sub sp, sp, #32768
    sub sp, sp, #20       @Why subtracted 20? 

    mvn r3, #4096
    sub r3, r3, #3
          @What r3 storing and Why took NOT of r3 and again subtract 3 from it?
    mov r2, #0
    sub r0, fp, #12
    str r2, [r0, r3]
    mvn r3, #8192
    sub r3, r3, #7
    mov r2, #0
    sub r1, fp, #12
    str r2, [r1, r3]
    sub r2, fp, #4096
    sub r2, r2, #12
    sub r3, fp, #4096
    sub r3, r3, #12
    sub r3, r3, #4
    mov r0, r2
    mov r1, r3
    bl  takeInput
    sub r2, fp, #8192
    sub r2, r2, #12
    sub r2, r2, #4
    sub r3, fp, #8192
    sub r3, r3, #12
    sub r3, r3, #8
    mov r0, r2
    mov r1, r3
    bl  takeInput
    mvn r3, #32768
    sub r3, r3, #11
    mov r2, #1
    sub ip, fp, #12
    str r2, [ip, r3]

我在汇编代码的注释中标记了我的疑虑。谢谢。

1个回答

6

立即数(仅在指令的某些部分中编码的常量)只能具有特定值,因为编码它们的字段只有几个比特。当编译器想要将寄存器加载为无法使用立即值编码的值时,它会加载部分值,然后使用算术完成操作。

在不同的ARM指令中,立即值有不同的编码方式,但以下是一种示例,来自ARM架构参考手册,ARMv7-A和ARMv7-R版。在ARM指令中,“修改后的立即常量”编码为12位。四位指定旋转,八位是值的文字位。这四位形成一个二进制数,旋转量是该数的两倍,向右移动。例如,如果四位是0011,即三,则旋转量为六位。

因此,如果四个旋转位是0011,并且八个文字位是10011101,则通过在32位字段内将10011101向右旋转六位来形成该值。因此,0000 0000 0000 0000 0000 0000 1001 1101向右旋转六位,产生0110 0100 0000 0000 0000 0000 0000 0010,或0x64000002。

显然,12位无法编码所有可能的32位值。在您的示例中,编译器想要的一个值是32748,即0x7fec。我们无法仅从任何位置的八位中(更具体地说,是偶数索引位置)形成0x7fec。


这里也有一个很好的解释:http://www.davespace.co.uk/arm/introduction-to-arm/immediates.html - Michael Burr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接