2012-08-24 329 views
3

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

#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; 
} 

我已经转换这种C代码使用GNU工具链臂到臂汇编代码。和生成的汇编代码的一部分是:

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] 

我也标志着我在汇编代码中的注释dought。谢谢。

回答

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。我们不能在任何位置(或更具体地说,偶数索引的位置)仅由8位构成0x7fec。

+0

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