2012-05-17 76 views
2

我目前正在編寫一個簡單的C編譯器,它將一個.c文件作爲輸入並生成彙編代碼(X86,AT & T語法)。我很難傳遞數組類型參數併爲其生成正確的彙編代碼。這裏是我的輸入:X86 assembly - 處理數組類型參數

int getIndexOne(int tab[]){ 
    return tab[1]; 
} 

int main_test(void){ 
    int t[3]; 
    t[0] = 0; 
    t[1] = 1; 
    t[2] = 2; 
    return getIndexOne(t); 
} 

一個相當簡單的測試。這是我的輸出:

getIndexOne: 
.LFB0: 
    .cfi_startproc 
    pushl %ebp 
    .cfi_def_cfa_offset 16 
    movl %esp, %ebp 
    .cfi_offset 6, -16 
    .cfi_def_cfa_register 6 
    movl %edi, -24(%ebp) 
    movl $1, %eax 
    movl -24(%ebp, %eax, 8), %eax #trouble over here 
    leave 
    .cfi_def_cfa 7, 8 
    ret 
    .cfi_endproc 
.LFE0: 
    .size getIndexOne, .-getIndexOne 


falsemain: 
.LFB1: 
    .cfi_startproc 
    pushl %ebp 
    .cfi_def_cfa_offset 16 
    movl %esp, %ebp 
    .cfi_offset 6, -16 
    .cfi_def_cfa_register 6 
    pushl %ebx 
    subl $120, %esp 
    movl $2, -32(%ebp) 
    movl $0, %eax 
    movl $0, -24(%ebp, %eax, 8) 
    movl $1, %eax 
    movl $1, -24(%ebp, %eax, 8) 
    movl $2, %eax 
    movl $2, -24(%ebp, %eax, 8) 
    leal -24(%ebp, %eax, 8), %eax 
    movl %eax, %edi 
    call getIndexOne 
    addl $120, %esp 
    popl %ebx 
    leave 
    .cfi_def_cfa 7, 8 
    ret 
    .cfi_endproc 
.LFE1: 
    .size main_test, .-main_test 

我無法訪問傳遞的地址(leal指令)的內容。任何幫助將非常感激。 PS:不要擔心我的整數大小,由於其他原因,它們被設置爲8而不是4字節。

回答

2

有兩個問題,第一個是,當你設置的堆棧調用getIndexOne

movl $2, %eax 
movl $2, -24(%ebp, %eax, 8) 
leal -24(%ebp, %eax, 8), %eax ##<== EAX still holds value of 2! 
movl %eax, %edi     ##<== wrong address for start of array 

MOV命令後你不清除EAX寄存器的內容,因此地址您將放入EDI寄存器中,因爲函數調用不是指向數組的開始,而是數組的最後一個元素(即元素值爲2的第二個索引)。

第二個問題說到這裏你getIndexOne功能:

movl %edi, -24(%ebp) 
movl $1, %eax 
movl -24(%ebp, %eax, 8), %eax 

你已經保存在棧上的地址。這很好,但它也意味着當您從堆棧中檢索值時,您會收到一個指針,它必須在第二次處取消。你現在正在做的是,你只是從棧指針讀回一個值偏移量......這不是數組中的值,因爲你不是取消存儲在堆棧上的指針。換句話說,你應該改變它,如果你必須將指針存儲在堆棧以下(我認爲因爲該值已經在EDI這不是最有效的方式,但不管):

movl %edi, -24(%ebp)   ##<== store pointer to the array on the stack 
movl $1, %eax 
movl -24(%ebp), %ecx   ##<== get the pointer back from the stack 
movl (%ecx, %eax, 8), %eax  ##<== dereference the pointer 

由於一個側面說明,雖然我不知道你的編譯器是如何工作的,但我確實認爲你使用加載到數組元素中的值來索引數組...如果這些值被加載不匹配數組索引,這將創建相當大的havok ...我猜這是你試圖做的一些類型的優化,當兩個值匹配時?

+0

我試過兩種不同的方法: 1)在leal指令之前加載EAX中的EAX。 2)將leal指令替換爲:leal -24(%ebp)。 在這兩種情況下,我得到一個錯誤的結果。 在這種情況下你會提出什麼其他方法? –

+0

對不起,我錯過了一個問題...我已經更新了我的答案。 – Jason

+0

這似乎解決了這個問題。我會做一些進一步的測試,然後我會回到你身邊。謝謝。 –