Привіт і ласкаво просимо назад.
У цій вправі ми напишемо вправу на побітові операції.
Тож про що ця вправа?
Ось такий опис.
Напишіть інструкції для вилучення п'ятого біта з цього 32-розрядного двійкового числа.
Отже, це 32-бітне двійкове число, а нульовий біт є першим бітом праворуч.
І якщо порахувати, то він починається з нуля, потім одиниця, потім біт два, потім біт три, потім біт чотири, а потім
це біт п'ять.
Отже, п'ятий біт - це шостий біт праворуч.
Тож ви можете спробувати це самостійно, якщо хочете.
Просто поставте відео на паузу і спробуйте.
Або ви можете просто подивитися рішення на наступному слайді, де я детально поясню, як воно працює.
Гаразд, ось і рішення.
Для розв'язання ми будемо використовувати оператор AND.
Отже, перший крок - перемістити це двійкове число в регістр, а потім створити маску для п'ятого
біта, біта
номер п'ять.
Маска складається з усіх нулів і лише одного на позиції п'ятого біта.
Таким чином, коли ми виконуємо операцію AND з регістром -, вона витягне біт номер п'ять з початкового
значення в -.
Отже, тут ми переміщуємо число в -, а тут виконуємо операцію AND.
Отже, як тільки п'ятий біт буде витягнуто,
його буде збережено назад у регістр.
А потім ми можемо перевірити результат, чи дорівнює п'ятий біт нулю чи ні, за допомогою тесту переходу JZ.
Так.
Отже, якщо п'ятий біт дорівнює нулю, то JZ перескочить.
Отже, ми переходимо за довільною адресою, яку ви можете вказати.
Отже, це адреса. Якщо ми стрибнемо сюди,
то чи дійдемо ми сюди, коли біт п'ятий дорівнює нулю.
Однак, якщо він не нульовий, він спуститься сюди і виконає все, що ви захочете.
І що б не сталося в кінці, ви повинні вискочити назад з оператора if.
Ось чому тут є додатковий перехід, щоб вийти з усього оператора if.
Отже, це місце, куди ви стрибаєте.
Отже, це базовий оператор if, який ви вже вивчали раніше.
Давайте спробуємо це зробити у x64dbg. Відкриваємо наш шаблон і вводимо ці інструкції.
Отже, перша команда - MOV -, тому ми просто копіюємо все це і вставляємо.
Натисни "ОК".
Наступною інструкцією буде операція AND.
Отже, ми просто копіюємо маску і саму інструкцію, і вставляємо її в наш код тут.
Натисни
"ОК".
Далі нам потрібно виконати стрибок,
тому нам потрібна адреса.
Тож давайте пошукаємо правильну адресу, можливо, десь тут, унизу.
І ми розмістили коментар тут, щоб нагадати, про що йдеться.
Отже, якщо п'ятий біт дорівнює нулю, то він потрапить сюди.
Потім копіюємо адресу.
Клацніть правою кнопкою миші, скопіюйте адресу.
А потім ми піднімаємося на вершину і створюємо наш стрибок.
Отже, натискаємо пробіл і вводимо JZ, а потім вводимо нашу адресу.
Тепер, коли ми вводимо, ми бачимо JZ, але коли ми натискаємо клавішу Enter, він стає JE.
Це те саме.
JE і JZ - це одне й те саме, як я вже пояснював у попередніх уроках.
Тож далі ми хочемо стрибнути сюди.
Отже, якщо він перескакує сюди, це означає, що п'ятий біт дорівнює нулю.
Якщо ні, то п'ятий біт не дорівнює нулю, він прийде сюди.
Тож давайте залишимо там коментар.
Якщо біт п'ятий дорівнює одиниці.
Тож ви можете розмістити свій код там. Все, що ви хочете зробити, ви можете записати тут.
Якщо біт п'ятий дорівнює одиниці.
Отже, що б це не було, ви повинні перейти до виходу з інструкції if, щоб ми могли завершити інструкцію if.
Тож нам потрібен ще один стрибок.
Отже, це місце виходу з інструкції if.
Тож давайте залишимо там коментар.
Тож ми пишемо "кінець".
Кінець оператора if.
Отже, ми копіюємо адресу.
Тому нам потрібно вийти з інструкції if.
Тож ми копіюємо адресу, повертаємося на початок і робимо наш стрибок.
Одразу після цього, ось цей рядок.
У цьому рядку ви виконуєте все, що хочете, якщо біт п'ятий дорівнює одиниці.
І якщо ми хочемо продовжити, нам потрібно вийти з оператора if, щоб ми могли поставити його, наприклад, тут.
JMP 0x і вставте адресу.
Отже, тепер ми вистрибуємо з оператора if і замість того, щоб продовжувати, переходимо до наступного.
Інакше він піде туди і виконає все, що там внизу.
Ось чому нам потрібно вийти з інструкції if.
Отже, тепер ви бачите логіку, яку ми вивчали раніше, як працює оператор if.
Тож ми просто впроваджуємо його тут.
Тож ми поставили там коментар.
Якщо п'ятий біт дорівнює нулю, то так і повинно бути.
Тепер ми біжимо, і він потрапляє на наш брейк-пойнт, і ми переступаємо.
Отже, ми перемістимо наше число, двійкове число, на -.
Тож давайте переступимо через це.
І ми маємо там наш двійковий номер.
Ми можемо скопіювати його і вивчити в нашому калькуляторі.
І ми бачимо, що це наше двійкове число, яке вводиться.
Отже, ми маємо наше двійкове число -, це ціль.
І тепер нам потрібно виконати операцію "І" з цим числом.
Отже, це число, давайте переступимо через нього зараз.
А операція AND зберігає результат назад у -, тож ми можемо дослідити - зараз і побачити, як він виглядає у двійковій
формі.
Давайте скопіюємо його і вставимо в наш калькулятор.
І ми бачимо, що це наш результат.
Ми витягли біт номер п'ять. Як бачите, біт номер п'ять дійсно дорівнює одиниці.
Нульовий біт, перший, другий,
третій, четвертий і п'ятий біт.
Пам'ятайте, ми рахуємо праворуч. По-перше, перший біт дорівнює
нулю.
Гаразд, це вирішує нашу проблему.
Давай переступимо.
Отже, він повинен робити
все,
що ви хочете, тому що п'ятий біт дорівнює одиниці.
І після цього ми можемо вийти з інструкції if.
Отже, тут ми виходимо з інструкції if.
Тож давайте переступимо через це і подивимося.
Воно вистрибує.
Ми не хочемо, щоб він продовжував виконувати частину нижче, нижче цього
стрибка.
Ось чому ми повинні вистрибнути.
Тож давайте вистрибувати.
Це кінець інструкції if.
Тож давайте врятуємо його зараз.
Файл виправлення, виправлення.
Назвемо це 49_тире І_розв'язок_вправи.
x. Натисніть "Зберегти".
Тож ми виконали цю частину.
Зробимо другий розв'язок, другий
альтернативний розв'язок з використанням ROR, повернемо
праворуч.
Таким же чином, ми переносимо все в -, а потім називаємо ROR - шість. Чому шість? Тому що справа є шість бітів.
Це шостий біт, але насправді це п'ятий біт, тому що перший біт - це нульовий біт, але насправді це шостий біт.
Тому
ми ротуємо - шість.
Це означає, що кожен біт переміститься вправо.
Потім ми тестуємо і бачимо, чи дорівнює прапорець перенесення нулю.
Якщо прапорець перенесення дорівнює нулю, то він перескочить сюди.
Прапорець перенесення
буде, тоді він дійде до цього місця і виконає те, що має бути зроблено, якщо прапорець перенесення дорівнює нулю.
Однак, якщо це одиниця, то прапорець перенесення не буде дорівнювати нулю.
Він дотягнеться сюди і виконає все, що ви захочете.
Отже, в цьому випадку він прийде сюди, тому що біт п'ятий дійсно дорівнює одиниці.
Отже, тут він перестрибне і повернеться в кінець оператора if, де відновить початкове значення,
використовуючи ROL, який є протилежністю ROR.
Ось як ви відновлюєте початкове значення за допомогою ROL.
Тож давайте спробуємо зараз.
Отже, ми перезавантажуємо шаблон і видаляємо всі наші попередні команди.
Backspace, щоб видалити все.
Чисто.
Гаразд.
Крапка з комою, backspace
для видалення всього.
Гаразд.
Крапка з комою, backspace для видалення всього.
Гаразд.
Крапка з комою, щоб відкрити коментар.
Backspace, щоб видалити все.
Гаразд. Тепер ми готові додати це до нашого x64dbg, тому просто копіюємо і вставляємо, як і раніше.
Тож ми копіюємо це, а потім вставляємо його сюди і натискаємо "ОК".
Тоді ми зробимо, наступним
буде ROR - шість.
Отже, введіть ROR - шість.
Гаразд.
Тоді тепер
нам потрібна адреса JNC.
Тож давайте підемо і знайдемо правильну адресу, випадкову адресу десь. Вниз стрибати, а не нести.
Тож давай дістанемо цю адресу. Залиште там коментар, щоб нагадати нам,
що це все, для чого це все?
Отже, якщо п'ятий біт дорівнює нулю, він потрапить сюди.
Тож давайте скопіюємо адресу, перейдемо сюди і зробимо наш JNC.
Отже, вводимо JNC 0x, вставляємо вашу адресу.
Зверніть увагу, коли ми входимо, воно стає JAE.
Тепер JAE еквівалентний JNC.
Це одне й те саме, але JNC є більш описовим.
Він каже вам стрибати, якщо немає опори. Так, але x64dbg перетворить його у JAE.
Отже, JAE і JNC - це одне й те саме.
Отже, тут, внизу, вона буде працювати, вона
дійде сюди, якщо
біт п'ятий дорівнює одиниці. Тягнись сюди, він не стрибне.
І після цього нам потрібно зробити ще один стрибок, щоб вийти з циклу.
Тож, можливо, ми зможемо використати цей.
Нам потрібно вийти з циклу, щоб відновити початкове значення в -.
Отже, давайте виберемо десь тут, щоб вийти з циклу і зробимо ROL - шість.
Отже, ROL - шість, як я вже згадував, відновить початкове значення в -.
Тож давайте зараз скопіюємо цю адресу і підемо сюди, щоб стрибнути, щоб зробити стрибок.
Отже, він прийде сюди, якщо біт п'ятий буде одиницею, просто щоб нагадати вам.
А потім виконуйте інструкції.
Все, що ви хочете зробити, ви можете зробити.
А потім ми перейдемо до виходу з оператора if і виконаємо нашу роль.
Тож він вискочить сюди, щоб виконати свою роль.
Інакше він піде прямо.
Ось чому ми повинні стрибати.
Отже, в цій частині ми повинні робити все, що завгодно, якщо
біт п'ятий дорівнює нулю.
Гаразд.
Давай побіжимо зараз, і він потрапляє на наш брейк-пойнт, і переступимо через нього.
Отже, він перемістить наше значення в -, переступить через нього, а потім виконає поворот вправо.
І зверніть увагу на прапор CF, коли ми переступаємо через нього, CF стає одним цілим. Це означає, що він витягнув п'ятий
біт у наш прапор CF.
Зверніть увагу, що прапор один.
Ми не будемо стрибати.
Ми підемо прямо, тому що ваш прапор - це одиниця, а не нуль. Потім тут ми вистрибуємо і відновлюємо нашу
первісну - цінність.
Переступивши через це, ми повертаємось до свого первісного - цінності.
Ми можемо підтвердити це, скопіювавши його і вставивши в наш калькулятор. Як бачите, ми повертаємо собі початкову
вартість.
Це наша початкова вартість.
Тому нам потрібно використовувати ROR і ROL разом.
Ось як ми вирішуємо нашу вправу.
Отже, є два рішення.
Збережемо його зараз.
Давайте натиснемо на Patch, а потім назвемо це рішення 50_dash ROR_solution_to_exercise.
x. Натисніть "Зберегти".
І ось ми маємо це.
Ось і все.
Дякуємо за перегляд.