2017-01-30 74 views
0

假設整數數組的大小存儲在eax中。我想你可以可以爲數組分配存儲像這樣:如何在堆棧中創建大小爲x的數組,並將scanf值創建到該數組中

subl (%eax), %esp 

然而,在EAX大小是由用戶提供的,並且將具有不同的尺寸與每個程序的執行。鑑於此,如何初始化用戶使用scanf提供的整數每個4字節的內存地址?我們如何確保如果提供的整數大於數組的大小,我們不會覆蓋任何內存?

回答

2

subl (%eax), %esp讀取由值eax表示的地址的內容。
這很可能是你不想在這種情況下做的事情。

如果eax是數組的字節大小,則subl %eax, %esp將爲其分配足夠的內存。
如果eax是該數組的32位整數的數量,那麼leal (,%eax,4), %esp是正確的指令。

上述說明都沒有說明棧的對齊情況。
爲了正確地從您的過程中返回,您必須能夠正確地撤銷上述步驟 - 跟蹤您需要執行此操作的數量。

您可以通過幀指針訪問數組的項目(如果有的話),或直接從esp獲取正數偏移量。


關於你提到的其他問題 - 那些是非常普通的C的問題,任何C教程涉及的主題。

如果您在從C切換到彙編時處於死衚衕,您可以讓編譯器激勵您。
下面是the code generated by GCC對類似於您要實現(因爲我已經明白它)的一個函數:

#include <stdio.h> 

void foo(int n) 
{ 
    int arr[n]; 


    for (int i = 0; i < n; i++) 
     scanf("%d", &arr[i]); 

} 

 

.LC0: 
     .string "%d" 
foo(int): 
     pushl %ebp 
     movl %esp, %ebp     ;Prologue 

     pushl %edi 
     pushl %esi 

     movl 8(%ebp), %edi    ;EDI = n 

     pushl %ebx 

     leal 4(,%edi,4), %eax   ;EAX = n*4+4 (For alignment purpose) 

     subl %eax, %esp     ;Allocate space 

     ;Pre loop condition 
     testl %edi, %edi 
     jle  .L1 

     ;Loop init 

     movl %esp, %esi     ;ESI = ptr to first element 
     xorl %ebx, %ebx     ;EBX = Counter 
.L5: 
     ;scanf("%d", &arr[i]); 
     pushl %esi 
     pushl $.LC0 
     addl $1, %ebx     ;Inc counter 
     addl $4, %esi     ;Move pointer 
     call scanf 

     ;Loop condition 
     cmpl %ebx, %edi 
     popl %eax 
     popl %edx 
     jne  .L5 
.L1: 
     leal -12(%ebp), %esp    ;Deallocate 

     popl %ebx 
     popl %esi 
     popl %edi 
     popl %ebp 
     ret 

對於這個答案的目的,我認爲存在VLAs,這在C11中不是強制性的,並且不是一對一地映射到彙編程序員擴展和縮小堆棧的能力。

相關問題