2012-08-24 293 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 –