Почему при создании переменной в стеке и в куче получается один и тот же код сборки? - PullRequest
1 голос
/ 23 января 2020

Я создал пример кода, потому что я пытаюсь начать сборку. Я объявляю и инициализирую целое число в стеке, а также делаю то же самое для того, что находится в куче. При взгляде на ассемблерный код они оба выдают довольно похожий код:

mov dword ptr [ebp-8],0     ; this is on the stack
mov dword ptr [ebp-14h],0   ; this is on the stack

mov eax,dword ptr [ebp-20h] ; this is on the heap
mov dword ptr [eax],0       ; this is on the heap

Не могли бы вы пролить свет на то, что я пропускаю?

Можно найти соответствующую часть разборки. внизу:

    int x = 0;
00111848  mov         dword ptr [ebp-8],0  
    int y = 0;
0011184F  mov         dword ptr [ebp-14h],0  
    int* z = new int;
00111856  push        4  
00111858  call        00111325  
0011185D  add         esp,4  
00111860  mov         dword ptr [ebp+FFFFFF14h],eax  
00111866  mov         eax,dword ptr [ebp+FFFFFF14h]  
0011186C  mov         dword ptr [ebp-20h],eax  
    *z = 0;
0011186F  mov         eax,dword ptr [ebp-20h]  
00111872  mov         dword ptr [eax],0  

Ответы [ 2 ]

7 голосов
/ 23 января 2020

Оба

int y = ....;

и

int* z = ....;

создают автоматическую переменную c (т.е. в стеке). Один является целым числом, а другой - указателем.

Первый инициализируется с 0, а другой инициализируется с new int. Это создает динамический объект c и приводит к вызову функции выделения памяти call 00111325.

2 голосов
/ 23 января 2020

Оба стека и кучи расположены в оперативной памяти, следовательно, доступ к ним выглядит аналогично.

На 32-битном x86 указатель стека находится в * Регистр 1007 *, а ebp обычно используется как " указатель кадра ". Локальные переменные функции находятся в памяти чуть ниже ebp, поскольку на x86 стек увеличивается вниз.

mov dword ptr [ebp-8], 0 означает «запись 4 нулевых байтов в память в месте [ebp-8]».

call 00111325 выделяет блок в куче и возвращает адрес в eax.

mov dword ptr [ebp-20h], eax означает запись eax в [ebp-20h] (вот где int *z находится в стеке).

mov dword ptr [eax], 0 затем записывает 0 в любом месте адреса eax.

...