Привіт і ласкаво просимо назад.
У цьому новому уроці ми дізнаємося, як отримати дані від користувача.
Ми зробимо це за допомогою функції scanf.
Отже, функція scanf - це функція для отримання вхідних даних від користувача, і ви можете отримати вхідні дані від користувача у вигляді
чисел, а також ви можете отримати вхідні дані у вигляді рядків у програмі на C.
Перш ніж використовувати scanf, ви повинні оголосити змінну для зберігання числа, яке ви збираєтеся ввести.
Отже, це оператор, який оголошує цілочисельну змінну з іменем number. Після оголошення змінної ви можете використовувати її у
вашій функції scanf, викликавши функцію scanf з двома параметрами.
Перший параметр - це специфікатор формату.
%d означає, що це число.
І тоді другим параметром буде адреса змінної "number. Цей символ тут особливий.
Це означає "адреса. Отже, коли ви викликаєте функцію
scanf, програма призупиняється, щоб дочекатися, поки користувач щось введе.
Після того, як користувач введе число і натисне клавішу Enter, число буде збережено в цій змінній під назвою
"number". У нас також
є версія для введення рядків.
Отже, для введення рядків, ви повинні спочатку оголосити рядок у програмі C.
Оголошення рядків здійснюється шляхом створення символьного масиву за допомогою ключового слова char (символ),
після чого задається ім'я змінної для рядка, а потім вказується довжина байт, яка буде використовуватися
для створення рядків.
Отже, це фактично масив з 32 елементів.
Ось як ви створюєте рядки у програмі на C.
Потім, коли ви захочете використати це у функції scanf, ви використовуєте %s як специфікатор
формату, а потім "s" вказує на рядок.
А в другому параметрі ви просто вказуєте назву рядка.
Не обов'язково ставити оператор адреси, оператор "address of".
Вам не обов'язково його ставити, тому що в масивах ім'я масиву саме є вказівником на рядок.
Отже, це виняток, особливий випадок у програмі на C.
Отже, рядок сам по собі вже є адресою рядка у пам'яті.
Тож це просто повторення для тих, хто забув свою програму на C.
І навіть якщо ви не вивчали програму C, вам не обов'язково це знати.
Все, що вам потрібно знати - це версія збірки.
Тож тепер спробуємо реалізувати це у збірці.
Тож давайте відкладемо це в сторону і відкриємо ваш x64dbg. Відкрийте шаблонний.
І поставте курсор сюди.
Отже, щоб реалізувати цю функцію в асемблері, вам потрібно мати адресу в пам'яті, де ви збираєтесь
зберігати номер.
А також вам потрібна адреса в пам'яті для зберігання специфікатора формату.
Дві речі тобі потрібні.
Перший - це сам номер.
Отже, для самого номера потрібно виділити пам'ять. Іди сюди.
Зазвичай ми використовуємо його для зберігання даних.
Є ще одне місце, де ви також можете зберігати дані.
BSS. Тож BSS також можна використовувати, сегмент BSS.
Різниця між ними полягає в тому, що всі дані, які ви зберігаєте в сегменті даних, залишаться в живих після
перезапуску програми.
Це означає, що після перезапуску програми ваші дані, ваші значення залишаються в сегменті
даних.
Саме тому вони називаються ініціалізованими даними.
Але якщо ви зберегли свої дані в BSS, то при перезапуску програми все буде видалено.
Ось чому цей сегмент BSS називається неініціалізованими даними.
Отже, в цьому уроці я покажу вам, як використовувати BSS, а також сегмент даних.
Отже, для сегмента даних ми збережемо ваш специфікатор формату, тому що коли програма перезапуститься,
ви все одно захочете мати ці дані у вашій програмі.
А потім для BSS ми будемо використовувати його для зберігання змінної, числа, тому що це число не потрібно,
його не потрібно зберігати після перезапуску програми.
Ця цифра тут постійно змінюється.
Кожного разу, коли ви запускаєте програму, число буде різним, тому що це число вводиться користувачем.
Ось чому ми додали це в BSS.
Втім, ви також можете використовувати дані для зберігання номера, але я просто хочу показати вам, що є альтернатива.
Саме тому я представляю вам сегмент BSS.
Отже, давайте почнемо з виділення адреси для зберігання вашого номера.
Отже, це змінна.
Тому ми просто збережемо його в неініціалізованому сегменті даних.
Отже, ми двічі клацаємо на BSS, і тут ми можемо використовувати будь-яку локацію.
Всі вони безкоштовні.
Скажімо, візьмемо 405010, ось цей. Отже, ми можемо клацнути правою кнопкою миші тут і скопіювати цю адресу.
Тоді тут ми можемо використати поштовх.
Натискаємо пробіл, а потім набираємо "push", а потім адресу, вставляємо її туди.
Гаразд.
Отже, саме тут ви зберігатимете свій номер, який користувач вводить ось тут.
405010.
Далі потрібно проштовхнути струну до стека.
Для цього ми повинні використовувати сегмент даних.
Переходьте сюди і шукайте вільну локацію.
Може, цей. Використовуйте одне d-слово, і цього має бути достатньо для нашого специфікатора формату %d. Відредагуйте та введіть
%d.
Ось.
Гаразд. Тож тепер ми маємо %d там.
Ви можете скопіювати цю адресу.
Скопіюйте адресу, а потім перейдіть сюди і введіть "push. Hex префікс і натисніть
Гаразд.
І, нарешті, ми збираємось посканфувати. Отже, ми дивимося вниз, прокручуємо вниз і шукаємо місце,
де є виклик, і просто двічі клацаємо на ньому і переходимо до таблиць переходів для всіх функцій.
Отже, нам потрібна функція scanf.
Тож просто прокрутіть трохи, і ви побачите ось тут, scanf.
Клацніть правою кнопкою миші та скопіюйте цю адресу, поверніться до покажчика інструкцій і клацніть на ньому.
А тепер ми повернулися сюди.
Натискаємо пробіл і поміщаємо туди виклик, вводимо префікс "hex" і вставляємо адресу функції scanf.
Ось так.
Тепер ми можемо запустити програму на виконання і досягнемо точки зупинки.
Пам'ятайте, що перед виконанням слід поставити точку зупинки.
Тож подивимося, що з цього вийде.
Відійдіть, поки ми не прийдемо сюди.
Таким чином, це пересуне адресу другого параметра.
Другий параметр - ось ця змінна, ось ця адреса цього номера.
А адреса
- 405010, 405010.
Тож поїхали туди зараз.
Давайте подивимося на карту пам'яті для BSS.
А це 405010, ось ця адреса.
Тож давайте переступимо через це.
І тепер ви бачите адресу на стеку: 405010, яка знаходиться тут.
Тож будь-які дані, введені користувачем, будуть збережені тут.
Далі ми натиснемо специфікатор формату, яким є цей сегмент даних 403050.
Отже, для цього ми обираємо дамп два, тому що дамп один ми хочемо відстежувати. Отже, обираємо
дамп 2. Тепер ми перейдемо до карти пам'яті і подивимося на дані.
Тож натисніть на сегмент даних, і він буде показаний у другому дампі.
Отже, у другому дампі ви бачите у цьому місці,
403050, специфікатор формату %d. Отже, зараз ми переступимо через це, і ви побачите, що специфікатор
формату, перший параметр знаходиться у стеку, а потім адреса, де ви збираєтеся
зберігати вхідні дані, також знаходиться
у стеку: 405010.
Так, щоб один показував адресу другого параметра.
Другий дамп показує адресу специфікатора формату.
Отже, ми будемо стежити за дампом один, тому що після того, як ми введемо номер, ми хочемо побачити, як він з'явиться
тут.
Тож давайте повернемося до цього зараз.
Тож як тільки ми переступимо через нього, він чекатиме, поки ми щось наберемо.
Зараз він перебуває в стані паузи.
Тож коли ми переступимо через це, ви побачите, що зупинений стан перетвориться на стан, що працює.
Переступи через це.
І зараз він знаходиться в запущеному стані.
Коли вона в запущеному стані, це означає, що програма чекає від нас якихось дій.
Отже, тут нам потрібно ввести число, яке ми хочемо ввести.
Тож ми можемо ввести три, три. Скажімо, три, три і натисніть Enter.
Отже, як тільки ви натиснете Enter, ви помітите, що стан виконання зміниться на стан паузи.
Тож давайте натиснемо Enter.
І тепер ми бачимо, що стан виконання змінився на стан призупинення, що означає, що ми повернулися до відладчика.
А тепер, якщо ви перейдете до цього місця, ви побачите, що ця адреса пам'яті, 405010,
тепер має гекс 21. Гекс 21 дорівнює 33.
Щоб перевірити, ви можете зайти на калькулятор і ввести 21 у шістнадцятковій системі числення, а 21
- це 33.
Це номер, який ми ввели.
Отже, коли ви введете 33, натисніть Enter.
Він зберігається у вашій адресі пам'яті у вигляді 21 у шістнадцятковому форматі.
Ось як працює сканф.
Гаразд, тепер ви можете зберегти свій проект: Patch, Patch file, а потім ми дамо йому назву.
19. 19, scanf-dec,
scanf десятковий.
Д-Е-С,..
exe.
Ось як ми можемо вводити дані від користувача.
Отже, у наступному уроці я
покажу вам, як виводити на друк значення, яке користувач ввів ось тут.
Тому я б хотів, щоб ви спробували спочатку самостійно, щоб зрозуміти, чи вмієте ви це робити.
Ви повинні вміти це робити, оскільки ви вже вивчили функцію printf.
Тож спробуйте це спочатку, перш ніж дивитися рішення в наступному відео.
Дякуємо за перегляд.