Привіт і ласкаво просимо назад.
У цьому уроці ми розглянемо фрейми стеків,
ознайомимося з ними.
Отже, що таке стековий каркас?
Стековий кадр у контексті комп'ютерного програмування - це структура даних, яка містить інформацію
про виклик функції, як, наприклад, у цьому прикладі.
Місце, куди повертається функція після завершення роботи, відоме як адреса повернення,
параметри, передані у функцію, локальні
змінні функції та збережені регістри, якщо такі є.
Тож давайте подивимось на стек тут.
У лівому стовпчику вказано адресу пам'яті, а у правому - вміст за цією адресою.
Таким чином, нижня пам'ять знаходиться зверху.
Більша пам'ять знаходиться внизу, тому стек зростає знизу вгору.
Отже, фрейм стека зазвичай має такий вигляд, де - використовується як метод посилання на параметри,
що передаються у функцію, а також на локальні змінні.
Тож - зазвичай використовується саме так.
- плюс чотири - зворотна адреса.
- плюс вісім буде аргументом номер один.
- плюс 12 буде аргументом два.
- плюс 16 було б третім аргументом.
А потім для локальних змінних, - мінус чотири отримає доступ до локальної змінної
один, - мінус вісім отримає доступ до локальної змінної два і так далі.
Тож давайте розглянемо практичний приклад.
Тоді ви зрозумієте, що це означає.
Припустимо, ми хочемо написати програму, яка буде додавати два числа, п'ять і три.
Гаразд, давайте подивимося, як ця штука працює.
Припустимо, що п'ять - ваш другий аргумент, а три - перший аргумент,
і що ми робимо - штовхаємо другий аргумент до стеку.
Тож тепер стек - підніметься сюди, другий
аргумент.
Потім ми натискаємо три, і вона знову піднімається вгору.
Отже, перший аргумент на столі.
Потім ви зателефонуєте за додатковими номерами.
Отже, коли ви викликаєте команду add numbers, вона виштовхує зворотну адресу цієї команди до стеку.
Отже, ця штука буде тут.
Потім він перейде в саму функцію, а сама функція, тепер ми спробуємо
зробити арифметику, але для того, щоб зробити арифметичне обчислення, потрібно зробити зсув - перейти до першого
аргументу і до другого аргументу.
У попередніх уроках ми робили це, використовуючи - мінус чотири для позначення першого аргументу і - мінус вісім
для позначення другого аргументу.
Але в цьому прикладі ми не можемо цього зробити, тому що нам потрібно створити локальні змінні, а для того,
щоб створити локальні змінні, нам потрібно взяти - і мінус чотири або мінус вісім, залежно від того, скільки змінних ви хочете.
Але якщо ви це зробили, то не зможете використовувати - для доступу до аргументів функції.
Ось чому нам потрібен ще один реєстр, щоб допомогти з посиланнями на різні аргументи.
Тому тут ми використовуємо -.
Тож ми просто штовхаємо - до штабеля.
Отже, - тепер йде до стопки, а - піднімається вгору, а потім ми переходимо - до -.
Отже, - і - тепер обидва вказують на одне і те ж місце, але одночасно, тому що ми штовхаємо - до
стеку,
тому стара адреса - зберігається в цьому місці тут.
Далі ми створимо локальні змінні, віднімаючи чотири від -, тобто віднімаючи чотири від -.
Ви створюєте місце у стеку для локальних змінних.
Ось чому вам потрібно використовувати -.
Тому що - дозволяє, - не змінюється.
Він дозволяє посилатися на аргументи функції.
У той же час, ви також можете посилатися на локальні змінні.
Отже, для того, щоб посилатися на аргументи функції, ви натиснете, візьмете - плюс вісім, - плюс
вісім буде посилатися на перший аргумент, - плюс 12 буде посилатися на другий аргумент, а - мінус
чотири буде посилатися на першу локальну змінну.
А якщо у вас є друга локальна змінна, то це буде - мінус вісім.
У цьому і полягає краса - тому що - не змінюється.
Отже, ви можете використовувати - для посилання на локальні
змінні, локальні змінні тут, або ви можете використовувати його для посилання на аргументи функції тут.
Отже, тепер ви можете створювати стільки локальних змінних, скільки захочете.
Наступне, що ви робите після створення локального
простору для локальних змінних, ви робите це, щоб створити простір для локальних змінних.
Тепер ви можете отримати доступ до параметрів функції або аргументу функції.
Для цього ви візьмете - плюс вісім.
Отже, ви отримуєте доступ до три тут і переміщуєте його до -, потім - плюс 12.
Ви берете п'ять тут і додаєте до -, а потім зберігаєте суму
в локальній змінній просто
для демонстрації.
Отже, ви візьмете - і перемістите на - мінус чотири ось сюди, щоб зберегти його тут,
ваш результат вашої суми.
Після цього ви повинні розблокувати сам стек. Щоб скасувати стек, ви повинні
відновити всі змінні - або дані -, а також - до початкового стану до виклику цієї функції.
Для цього ви зробите те, що ми зробили тут, навпаки.
Ось ти робиш, ти рухаєшся... Тут ви зробите все навпаки.
Ти рухаєшся - -.
І ось ви рухаєтесь - -.
Таким чином, перемістивши - до -, ви перемістите - вниз ось так.
Отже, на даний момент і - і - вказують на одну й ту саму адресу.
Чому?
Тому що ти будеш наступним.
Ось чому вам потрібно перемістити - до - так,
щоб - вказував на вершину стопки, щоб зробити її готовою до того, як ви натиснете -.
Отже, коли ви натискаєте -, відбувається
те, що - займає своє початкове положення, вказуючи на правильне місце в стеку.
Тож коли ти вискочиш -, - зараз підеш сюди.
Чому?
Тому
що старе значення - зберігалося у стеку, тож коли ви його витягнете, - повернеться на своє початкове місце десь тут,
унизу.
Гаразд, після того, як ти вискочиш, повертайся сюди.
Потім ви будете готові до повернення.
Пам'ятайте, що коли ви повернетеся, він висвітить
все, що тут є, зворотну адресу, щоб ви могли повернутися на цю адресу після дзвінка.
Тож коли він повернеться, - тепер повернеться сюди.
Ця штука вискочить на -, а - повернеться до основного коду ось тут і виконає решту.
Ось тут ви чистите стопку. Ви повинні додати вісім до -.
Чому?
Тому що тут у вас є два аргументи функції.
Спочатку ти натиснув п'ять і три.
Тож тепер вам потрібно почистити стопку.
Отже, ви додаєте вісім до -.
Отже - підуть вниз чотири і вісім.
Тож він повертається на початкове місце.
Отже, ми почистили штабель.
А далі це вже за бажанням.
Якщо ви хочете, ви можете перейти до результату, або залишити його як є, якщо хочете.
Отже, це теорія того, як це працює.
У наступному уроці ми розглянемо, як це реалізувати у x64dbg.
Дякуємо за перегляд.