如何在堆栈上创建大小为 x 的数组并将 scanf 值放入其中

Posted

技术标签:

【中文标题】如何在堆栈上创建大小为 x 的数组并将 scanf 值放入其中【英文标题】:How can you create an array of size x on stack and scanf values into it 【发布时间】:2017-01-30 03:54:27 【问题描述】:

假设一个整数数组的大小存储在 eax 中。我想你可以像这样为数组分配内存:

subl (%eax), %esp

但是,eax 中的大小由用户提供,并且每个程序执行的大小都不同。鉴于此,如何使用用户使用 scanf 提供的整数初始化每个 4 字节内存地址?我们如何确保如果提供的整数多于数组的大小,我们不会覆盖任何内存?

【问题讨论】:

【参考方案1】:

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 中不是强制性的,并且并没有真正一对一地映射到汇编程序员增长和缩小堆栈的能力。

【讨论】:

以上是关于如何在堆栈上创建大小为 x 的数组并将 scanf 值放入其中的主要内容,如果未能解决你的问题,请参考以下文章

C中堆栈上的动态数组分配

关于如何输入一个数来任意确定数组大小

在堆栈上分配数组时出现运行时错误[重复]

如何访问数组并将其存储在python中的单个数组中(类似于matlab中的单元格)

哨兵与传递计数

用C编程,如何声明未知大小的数组以供以后使用?