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

时间:2017-01-30 03:54:27

标签: arrays assembly att

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

subl (%eax), %esp

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

1 个答案:

答案 0 :(得分:2)

subl (%eax), %esp读取由eax值表示的地址内容 这很可能是您在此上下文中不想做的事情。

如果eax是数组的字节大小,那么subl %eax, %esp将为其分配足够的内存。
如果eax是数组的32位整数,则leal (,%eax,4), %esp是正确的指令。

上述说明均未考虑堆栈的对齐情况 为了从您的程序中正确返回,您必须能够正确撤消上述步骤 - 跟踪执行此操作所需的数量。

您可以通过帧指针(如果有)访问数组的项目,也可以直接从esp作为正偏移量访问。

关于你的其他问题 - 这些都是普通的C问题,任何C语言教程都涵盖了这些主题。

如果从C切换到汇编时处于死路,你可以让编译器激励你 对于一个类似于你想要实现的函数,我的the code generated by GCC下面是VLAs

#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

为了这个答案的目的,我假设存在{{3}},这在C11中并不是强制性的,并没有真正地将一对一映射到汇编程序员增长和缩小的能力。叠加。