Привіт і ласкаво просимо на цей практичний семінар.
У цьому практикумі я створив програму під назвою "75 Traversing Call Stack exe. Я взяв перший шаблон і ввів весь
код зі слайда PowerPoint.
І це код, який я ввів.
Дозвольте мені показати вам. Якщо ви перейдете за цим посиланням і подивитеся на останню частину слайду PowerPoint,
ви отримаєте весь код безпосередньо в ньому.
Отже, функцію X я розмістив у головному, а функції Y, S і T - у підземеллі коду.
Дозвольте мені показати вам.
Отже, це функція Y.
Як бачите, штовхач - тут.
А потім це оригінальний поштовх - з попереднього кадру.
Тепер ми додамо сюди власний фрейм, додавши цей натиск -.
Отже, цей поштовх
- це фактично початок прологу функції для функції X.
Отже, я набрав push -, move -, -, sub -, C, і все це фактично
походить з цього коду тут.
А потім сюди, дзвони Y.
Отже, виклик Y - це адреса ось тут, у кодовій печері.
Отже, вам потрібно ввести код для цієї частини коду, функції Y, у печері коду.
Ось що я зробив.
Отже, коли я двічі клацну на цьому, я перейду
в печеру коду, і це буде функція Y. Я ставлю коментар, і це функція
Y, а це функція S.
А ось функція T.
Отже, функція Y проходить від цього місця до цього.
Функція S - звідси сюди, а функція T - звідси сюди.
Я вірю, що ви знаєте, як створити всі ці функції.
Вам потрібно отримати адресу для кожного дзвінка.
Наприклад, коли ви знаходитесь на головній сторінці, давайте повернемося на головну.
Коли ви знаходитесь на головній сторінці, як ви знаєте, за якою адресою дзвонити?
Треба планувати заздалегідь.
Перейдіть до своєї кодової печери і скопіюйте цю адресу сюди, а потім поверніться на головну сторінку
і вставте сюди адресу 402005.
На вашому комп'ютері
він може відрізнятися від мого, тому дотримуйтесь того, що ви бачите на своєму ПК.
А потім, коли ви будете тут, зробіть те ж саме.
Тепер ви знаходитесь всередині функції Y.
Викличемо функцію S.
Отже, знову ж таки, ось ця адреса, вам потрібно отримати її звідси.
Просто скопіюйте цю адресу та вставте її сюди.
Те ж саме для функції T.
Тож зараз я запущу його і продемонструю вам, як він працює.
І ще одна річ, яку я збираюся розглянути, - це вкладка, яка називається стек викликів.
Отже, на початку стеку викликів ваша функція X ще не знаходиться у стеку викликів.
Ви все ще перебуваєте в системі.
Отже, на початку у стеку викликів немає функції X.
Отже, це стек викликів, який показує вам історію всіх викликів функції, які були зроблені.
Гаразд.
Отже, зараз ми поставимо точку зупинки.
Я збираюся перейти на основну сторінку і поставити точку зупинки.
Я це вже зробив, і вам варто
зробити те ж саме у вашому випадку.
І я побіжу і заб'ю свій брейк-пойнт.
Отже, зараз моя точка зупинки тут.
Він створить фрейм, виконавши пролог функції.
Отже, ми закінчили писати пролог функції.
Тепер він створить локальні змінні.
Потім він виштовхне значення 20 і 10 у стек для функції Y.
Отже, це аргументи для функції Y. Він штовхається до штабеля, і він штовхається.
Ви можете побачити тут, 20 - там.
Це в гексах, пам'ятайте.
А потім воно перевалить за 10.
Тепер у стопці 10.
Потім він викличе функцію Y.
Щоб викликати функцію Y, ми зробимо крок у неї.
Отже, в цей момент часу, якщо ви перейдете до стеку викликів, ви побачите, що ваша функція X
вже там.
Ви можете підтвердити це, клацнувши правою кнопкою миші на цій адресі.
Випливає з. Коли ви натискаєте "слідувати від", ви переходите до місця розташування функції X ось тут.
Так ви дізнаєтесь, де знаходиться... Так ви відстежуєте
функцію зі стеку викликів.
Отже, зі стеку викликів, якщо ви хочете перейти до функції, просто клацніть правою кнопкою миші і виберіть "слідувати від", і
ви перейдете
до тієї функції, яка зараз знаходиться на вершині стеку викликів.
Отже, тепер він знаходиться на вершині стека викликів.
Саме тому він тут, нагорі.
Гаразд.
Отже, тепер він збирається викликати функцію Y.
Ми робимо крок у нього.
Це "крок у...". Тому, коли ви входите,
стежте за тим, що відбувається зі стеком викликів.
Коли ви входите, поверх функції X з'являється функція Y.
Тож давайте подивимося. Тепер я перейду до функції Y.
Отже, я переходжу до функції Y,
і тепер ми у функції Y, як ви можете бачити тут.
Тепер подивіться на стек викликів.
Функція Y тепер зверху,
а функція X знизу.
Таким чином, щоразу, коли ви викликаєте іншу функцію з попередньої, остання буде витіснена на вершину
стека.
Ось як це працює.
Отже, найактуальніша функція знаходиться зверху, попередня - під нею, і так далі.
Отже, тепер це функція Y, і ви можете підтвердити це, клацнувши правою кнопкою миші, перейдіть до "слідувати від". І тоді ви потрапите в область функції
Y ось тут.
А якщо ви хочете дізнатися, яка функція викликала функцію Y, ви можете відстежити її за стеком викликів.
Отже, батьком функції Y є фрейм безпосередньо під нею.
Отже, це функція, яка викликає функцію Y.
І ви можете поїхати туди.
Ви можете клацнути правою кнопкою миші і вибрати "слідувати з", а можете повернутися до основної функції.
Отже, це функція X.
Отже, ось як можна трасувати функції за допомогою стеку викликів.
Ви можете дізнатися, яка функція викликала іншу функцію, просто подивившись на стек викликів,
тому що стек викликів - це історія всіх викликів функцій.
Гаразд.
Повернімося до нашої поточної функції.
Давай повернемося сюди.
Звідси випливає, що тепер ми знаходимося у функції Y.
Тепер функція Y повторить все, що зробила функція X. Він створить кадр за допомогою
функції prologue.
Отже, він натисне -, перемістить -, -, створить локальні
змінні, а потім викличе функцію S.
Але перед тим, як викликати функцію S, він виштовхне параметри функції S.
Тож давайте зробимо це зараз. До речі, саме так ви отримуєте доступ до аргументів вашої функції.
Ми вже вивчали це раніше.
Щоб отримати доступ до аргументів функції,
потрібно - передати покажчик на -, праворуч.
Якщо ви забули про це, просто поверніться і згадайте.
Отже, вона передасть все, що ви отримали від функції X, як параметр для функції S.
Так ось чому ти штовхаєшся тут.
Отже, він виштовхує два параметри до стеку, і
ви можете побачити їх тут.
А тепер він викличе функцію S і стежитиме за стеком.
Отже, тепер у стеку є функція X, функція Y.
Отже, далі вона виштовхне функцію S поверх цього.
Тож давайте подивимось.
Тож зараз я збираюся відповісти на цей заклик.
Зробіть крок у цьому напрямку,
і ви опинитеся у функції S. І ви повертаєтеся до стеку викликів.
Тепер ви бачите, що там є три функції.
Зверху знаходиться функція S, а батьківською для функції S є функція Y, а потім функція
X, праворуч. X, Y, S.
Отже, функція S тепер у стеку.
Отже, це функція S.
Тепер ми переступимо через це,
і функція S використає свій пролог для створення фрейму.
Тож давайте переступимо через це. Крокуй, крокуй, створюй локальні змінні, а тепер
він збирається викликати функцію T.
Але перед цим вона виштовхне параметри функції T у стек.
Тож штовхаємо його до стопки, і він опиняється на стопці.
Тепер він викличе функцію T.
Тепер слідкуйте за стеком викликів.
Тепер у вас є три функції: X, Y, S.
Тепер ми зробимо крок у цю функцію T.
Тож давайте почнемо.
Отже, ми переходимо до функції T.
Зараз ми знаходимося у функції T, а потім переходимо до стеку викликів і дивимося.
Отже, функція T існує.
Отже, тепер у стеку
є чотири функції: функції T, S, Y та X.
Гаразд.
Отже, зараз ми знаходимося у функції T.
Функція T використає свій пролог функції для створення ще одного кадру стеку.
Тож давайте переступимо через це.
А тепер він створить локальні змінні,
а потім виконає обчислення. Функція T не викликає ніяких інших функцій, тому на цьому
вона завершується.
Він не викликає ніяких інших функцій.
Тож він просто виконуватиме те, що має робити, а саме - виконувати арифметичні дії.
Тож нехай вона це зробить. Переступайте, переступайте,
і ось він закінчив виконувати свою роботу,
а тепер ми розмотуємо стос.
Це означає, що звідси вона буде розкручуватися до самого батька.
Це означає, що T розкручується до S, а потім до Y.
Y розкручується до X.
Тож, коли він розкручується, все, що знаходиться зверху, буде збито.
Це означає, що з чотирьох
функцій залишилося три, а з трьох - дві, а потім одна функція.
Подивимось, що з цього вийде.
Тож тепер у нас є чотири функції.
Подивимось. Зараз вона розслабиться.
Тож коли вона розкрутиться, куди вона піде?
Ми можемо легко передбачити. Він піде до батьків.
Коли він потрапляє на ret
тут, відбувається те, що він повертається на зворотну адресу.
Адреса повернення для функції T знаходиться одразу після виклику.
Тут ви викликаєте функцію T, так.
Отже, ця адреса повернення повинна повернутися до адреси після виклику, тому що цей виклик викликав функцію
T.
Тож перш ніж я подзвоню, пам'ятайте, що він виштовхнув зворотну адресу, якою є ця адреса, до стеку.
Отже, коли ви повернетеся сюди, він повернеться за цією адресою, і ми можемо переконатися
в цьому, подивившись стек викликів.
Отже, ця дочірня функція, куди вона повертається? Вона повернеться до батьків.
Тож давайте підемо за батьком. Клацніть правою кнопкою миші, "слідувати
від", і ви побачите, що це місце, куди повернеться ваша функція T.
Це зворотна адреса, так.
Отже, звідси рет піде вгору.
Тож не зводьте з мене очей, коли я переступатиму через нього. Гаразд, я переступаю. Повертайся. Бам.
Він повертається на зворотну адресу.
Це правда.
А тепер поверніться до стеку викликів.
Ви побачите, що стек викликів, який раніше складався з чотирьох функцій, тепер скоротився до трьох.
Отже, тепер на вершині стеку ми маємо функцію S.
S тепер на вершині стеку.
Тож ми можемо піти туди.
Тепер "випливаємо з", і ми вже тут.
А потім те саме повторюється знову.
Отже, він очистить стопку,
а потім розмотає її.
Подивимось, як це буде.
І куди, на вашу думку, він повернеться?
І тепер, коли я виконаю це повернення, він переступить, і ми повернемося сюди.
Тож він повернувся до функції Y ось тут.
Батьком функції S є функція Y. Він повернеться сюди.
Тепер ми переходимо до стеку викликів.
Ви бачите, що ми знаходимося на вершині, і тепер
ми знаходимося у функції Y. "Follow from", і ви бачите,
що це функція Y.
А потім функція Y повернеться до функції X.
Отже, ви можете перейти сюди і відстежити батька для функції Y. "Випливає з", і ви можете побачити
тут у функції X тут.
Тож давайте повернемося до цього.
"Вийди з" і переступи через.
Коли ви переступите межу, вона повернеться до функції X.
Тож зробіть крок, і тепер ви у функції X.
Ось так ви розкручуєте функцію.
Отже, процес трасування стеку викликів називається обходом стеку викликів.
На цьому відео все.
Дякуємо за перегляд.