Имеется компилятор GNU 3.4.2 из MinGW. Например, компилируем и дизассемблируем такую простую функцию: int f(int a, int b, int c) { int array[3]; array[1] = a; array[2] = b; array[3] = c; return array[1]; } Дизассемблированный код: 004012B2 /$ 55 PUSH EBP 004012B3 |. 89E5 MOV EBP,ESP 004012B5 |. 83EC 18 SUB ESP,18 004012B8 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 004012BB |. 8945 EC MOV DWORD PTR SS:[EBP-14],EAX 004012BE |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 004012C1 |. 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX 004012C4 |. 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10] 004012C7 |. 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX 004012CA |. 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] 004012CD |. C9 LEAVE 004012CE \. C3 RETN Вот теперь вопрос, а почему собственно SUB ESP,18? И почему такие смещения у элементов массива: [EBP-14], [EBP-10], [EBP-C]? Стек перед возвратом из функции выглядит так: 0022FF30 77C24E42 -----------? 0022FF34 0000A0A0 \ 0022FF38 0000B0B0 | - Элементы массива 0022FF3C 0000C0C0 / 0022FF40 00401390 -----------? 0022FF44 00004000 -----------? 0022FF48 /0022FF78 - EBP 0022FF4C |00401316 RETURN to 4.00401316 from 4.004012B2 0022FF50 |0000A0A0\ 0022FF54 |0000B0B0 | - параметры функции 0022FF58 |0000C0C0 / Что-то я не догоняю зачем распределилась лишняя память?
MYX поробуйте для начала записать вашу прогу правильно. при 3х элементах в массиве они в С индексируются 0..2, те: уже ошибка. Кроме того укажите опции оптимизации (после переписывания).
MYX выделяется место в стеке под локальные переменные, сохраняется esp в ebp и потом через ebp обращаются к локальным переменным и переданным в функцию аргументам (обращаться через esp не очень хорошая идея, т.к. в функции он может часто менятся). Если включишь оптимизацию, то компилятор может сгенерировать лучший код.
Нет мне прощения... 0022FF30 0000A0A0 0022FF34 0000B0B0 0022FF38 0000C0C0 0022FF3C 00401466 ----------? 0022FF40 00401380 ----------? 0022FF44 00004000 ----------? 0022FF48 /0022FF78 - EBP 0022FF4C |0040130E RETURN to 4.0040130E from 4.004012AA 0022FF50 |0000A0A0 0022FF54 |0000B0B0 0022FF58 |0000C0C0 Оптимизация повлияла только на сам код, но не на распределение памяти в стеке. Также осталось SUB ESP,18.
не исключено, что пустые локалки - алиасы на случай записи во входные параметры как в переменные, ведь они у вас не консты. Сделайте эксперимент - добавьте еще параметров, запишите в какойнить из них. еще очень возможен вариант, что это выравнивание блока локалок на 16. Попробуйте отключить выравнивание. не помню точно как в гну вызывается.. ключевое слово align
_basmp_, спасибо! Это и на самом деле оказалось выравнивание. Я это подозревал, но не мог найти соответствующих опций компилятора. Опция называется -preferred-stack-boundary=X. Удалось добиться такого: 0022FF40 0000A0A0 -> array[0] 0022FF44 0000B0B0 -> array[1] 0022FF48 0000C0C0 -> array[2] 0022FF4C 00004000 --- для выравнивания 0022FF50 /0022FF78 --- сохраненный EBP 0022FF54 |00401324 RETURN to a.00401324 from a.004012AA