Skip to content

Latest commit

 

History

History
84 lines (67 loc) · 4.55 KB

loop.md

File metadata and controls

84 lines (67 loc) · 4.55 KB

LOOP

Здесь вы сможете найти как минимум 3 способа, как сломать команду loop. Наслаждайтесь =)

Прямая загрузка

Когда мы используем прямую загрузку операнда в LOOP:

loop #75

Каждый раз будет загружаться одно и то же значение, оно же будет уменьшаться и далее передаваться управление в зависимости от предоставленного значения. Таком образом для любого положительного числа (например, 0x75) предоставленного прямой загрузкой, loop всегда будет передавать управление следующей команде, поскольку в ячейке памяти всегда будет положительное число (логично) Если значение отрицательное (e.g. 0xF5) команда будет вести себя, будто в памяти отрицательное число, то есть, всегда перепрыгнет через 1 команду.

(Положительное значение) Перед исполнением:

-> 8F75
   0700
   0100

После:

   0074
-> 0700
   0100

(Отрицательное значение) Перед исполнением:

-> 8FF5
   0700
   0100

После исполнения:

   FFF5 ; знак был расширен, именно поэтому вы видите FFF5 вместо 00F5
   0700
-> 0100

Note: остальные режимы адресации должны корректно работать с этой командой

Косвенная автоинкрементная адресация

Нормальное состояние

Этот режим адресации не ломает команду loop если она используется так, как показано ниже:

org 0x10
word 0x5           ; <- операнд
POINTER: word 0x10 ; <- адрес
loop (POINTER)+    ; <- автоинкрементная адресация
inc
hlt
  1. Увеличивает адрес на 1 и помещает его в Data Register

  2. Сохраняет содержимое Data Register (т.е. увеличенный адрес) в POINTER (0x10 -> 0x11)

  3. Уменьшает адрес хранимый сейчас в Data Register (далее DR) обратно на 1 (0x11 -> 0x10). Учтите, что DR не был очищен после инкрементирования адреса, поэтому этот адрес остается в регистре.

  4. loop уменьшает операнд 0x5 (находится по адресу, сохраненному в DR т.е. 0x10). (0x5 -> 0x4)

Вечного цикла НЕ произойдет поскольку loop выполняет уменьшение операнда а НЕ адреса.

The WTF

Но стойте! Что... Что если адрес и операнд станут одни и те же. Итак... Мы получим следующее:

org 0x10
POINTER: word 0x10 ; notice pointer points to itself
LP: loop (POINTER)+
jump LP
hlt

Пожалуйста! Не запускайте это так как это разрушит вселенную до непоправимого состояния!

Таким образом происходит зацикливание команды loop.

0x10 -> 0x11 -> 0x10 и так далее.

Обратите внимание что сначала произойдет инкрементирование, поскольку инкрементирование адреса является частью цикла выборки адреса. В свою очередь, декремент операнда происходит во время цикла исполнения. Цикл выборки адреса предшествует Циклу исполнения.

Переполнение

Если значение в ячейке памяти эквивалентно 0x8000 или 0x8001 то команда НЕ совершит прыжок! Из-за особенностей проверок в команде loop внутри команды произойдет переполнение с данными значениями.