Как массив переменного размера в C работает внутри? - PullRequest
1 голос
/ 21 июня 2020

Я пытаюсь понять, как массив stati c переменного размера работает внутри:

Ниже приводится массив stati c фиксированного размера в C и его эквивалент в сборке;

int main()
{
int arr[2] = {3};
}
================
main:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], 0
        mov     DWORD PTR [rbp-8], 2
        mov     eax, 0
        pop     rbp
        ret

Однако ниже показан массив переменного размера

int main()
{
int varSize ;
int Arr[varSize];
}
=================
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     rax, rsp
        mov     rcx, rax
        mov     eax, DWORD PTR [rbp-4]
        movsx   rdx, eax
        sub     rdx, 1
        mov     QWORD PTR [rbp-16], rdx
        movsx   rdx, eax
        mov     r8, rdx
        mov     r9d, 0
        movsx   rdx, eax
        mov     rsi, rdx
        mov     edi, 0
        cdqe
        lea     rdx, [0+rax*4]
        mov     eax, 16
        sub     rax, 1
        add     rax, rdx
        mov     edi, 16
        mov     edx, 0
        div     rdi
        imul    rax, rax, 16
        sub     rsp, rax
        mov     rax, rsp
        add     rax, 3
        shr     rax, 2
        sal     rax, 2
        mov     QWORD PTR [rbp-24], rax
        mov     rsp, rcx
        mov     eax, 0
        leave
        ret

Я вижу множество инструкций по сборке, если я объявляю массив переменного размера. Может кто-нибудь объяснить, как достигается эта гибкость переменного размера?

1 Ответ

1 голос
/ 21 июня 2020

Тот же механизм, что и alloca() - выделение памяти путем уменьшения указателя стека с предположением, что стек достаточно велик и / или ОС будет увеличивать его по мере необходимости.

Может быть немного проблема, когда запрошенный размер превышает страницу памяти и стек близок к концу. Обычно ОС увеличивает стек, устанавливая страницу защиты на вершине стека и наблюдая за ошибками в этой области, но это предполагает, что стек растет более или менее последовательно (путем нажатия кнопок и вызовов функций). Если уменьшенный указатель стека выходит за пределы страницы защиты, он может в конечном итоге указывать на фиктивное место. Я не уверен, что компилятор делает с этой возможностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...