假设整数数组的大小存储在eax中。我想你可以可以为数组分配存储像这样:如何在堆栈中创建大小为x的数组,并将scanf值创建到该数组中
subl (%eax), %esp
然而,在EAX大小是由用户提供的,并且将具有不同的尺寸与每个程序的执行。鉴于此,如何初始化用户使用scanf提供的整数每个4字节的内存地址?我们如何确保如果提供的整数大于数组的大小,我们不会覆盖任何内存?
假设整数数组的大小存储在eax中。我想你可以可以为数组分配存储像这样:如何在堆栈中创建大小为x的数组,并将scanf值创建到该数组中
subl (%eax), %esp
然而,在EAX大小是由用户提供的,并且将具有不同的尺寸与每个程序的执行。鉴于此,如何初始化用户使用scanf提供的整数每个4字节的内存地址?我们如何确保如果提供的整数大于数组的大小,我们不会覆盖任何内存?
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中不是强制性的,并且不是一对一地映射到汇编程序员扩展和缩小堆栈的能力。