subl (%eax), %esp
은 eax
의 값으로 표시된 주소의 내용을 읽습니다.
이것은이 컨텍스트에서 원하지 않는 무언가입니다.
eax
이 배열의 크기 (바이트)이면 subl %eax, %esp
은 충분한 메모리를 할당합니다.
eax
이 배열의 32 비트 정수의 수이면 leal (,%eax,4), %esp
이 올바른 명령어입니다.
위 지침 중 스택 정렬에 대한 설명이 없습니다.
절차에서 올바르게 반환하려면 위의 단계를 올바르게 실행 취소 할 수 있어야합니다. 수행해야 할 수량을 추적하십시오.
프레임 포인터가있는 경우 배열의 항목에 액세스하거나 직접 esp
의 양수 오프셋으로 배열의 항목에 액세스 할 수 있습니다.
기타 질문 - 해당 질문은 정말 일반적인 C 질문입니다. C 자습서에서는 이러한 주제를 다룹니다.
C에서 어셈블리로 전환 할 때 막 다른 길을 가고 있다면 컴파일러에서 영감을 얻도록 할 수 있습니다. 내가 가정 한이 답변의 목적
#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
:
아래는 (내가 이해 한대로) 구현하려는 하나의 유사 기능에 대한 the code generated by GCC입니다 VLAs의 존재는 C11에서는 필수 사항이 아니며 스택을 확장하고 축소하는 데 어셈블리 프로그래머가 실제로 일대 일로 매핑하지 않습니다.