Урок 4. Циклы и условия: умножение повторным сложением

В картинках

В этом уроке нет новых деталей — только программа. Процессор не умеет умножать, но умеет повторять: 13 × 11 — это 13, сложенное 11 раз. Счётчик в памяти, флаг Z и условный переход — и готов цикл.


4.1. Идея: счётчик до нуля

  • сумма лежит в ячейке 0, счётчик — в ячейке 1;
  • в петле: сумма + 13, счётчик − 1;
  • SUB #1 ставит флаг Z, когда счётчик дошёл до нуля;
  • JNZ loop возвращается в начало петли, пока Z = 0.

Так же карта будет принимать байт: «8 раз взять бит».

сумма = 0, счётчик = 11сумма = сумма + 13счётчик = счётчик − 1ноль?нет (JNZ)даA = 14313 × 11
Умножать не нужно — достаточно повторять. Флаг Z после SUB #1 говорит «счётчик дошёл до нуля», JNZ решает: ещё раз или дальше.

4.2. Программа

Тот же проект, что в уроке 3. Новых деталей нет: переходы по флагам собраны в уроке 2, память — в уроке 3. Этот урок — про то, как на них пишут программы.

КомандаПереходит, еслиФлаг ставят
JMPвсегда—
JZZ = 1 (результат был 0)LD, ADD, ADC, SUB, AND, OR, XOR, CMP
JNZZ = 0те же
JCC = 1 (перенос; у SUB/CMP — A ≥ B)ADD, ADC, SUB, CMP
JNCC = 0те же
CALLвсегда, запомнив адрес возврата—
RETна запомненный адрес—

Шаг 1. Программа в ПЗУ

⚙ у ROM → кнопка ⬆ → файл 04-mul.rom.json. Clock можно поставить на 10Hz — петля длинная.

; Урок 4 — умножение повторным сложением: 13 × 11 = 143. Счётчик в ячейке 1 убывает до нуля — петля, как у карты; «принять 8 бит». JNZ смотрит на флаг Z, который поставила SUB.        LD #0        ST 0             ; сумма = 0        LD #11        ST 1             ; счётчик = 11loop:   LD 0        ADD #13        ST 0             ; сумма = сумма + 13        LD 1        SUB #1        ST 1             ; счётчик = счётчик − 1        JNZ loop         ; не ноль — ещё раз        LD 0             ; ответ — в A, на лампыdone:   JMP done         ; стоп: программа шагает на месте

4.3. Проверка

Сброс (RST на один-два такта) — и смотри, как идёт петля. Одна строка — один проход (7 команд от loop до JNZ):

ПроходТактСчётчик (ячейка 1)Сумма (ячейка 0)ZJNZ
11110130ещё раз
2189260ещё раз
3258390ещё раз
4327520ещё раз
5396650ещё раз
6465780ещё раз
7534910ещё раз
86031040ещё раз
96721170ещё раз
107411300ещё раз
118101431выход из петли
—8301430A = 143: стоп, PC стоит на 12
  • Табло PC бегает по кругу 4 … 10, после 11-го прохода уходит на 11, потом стоит на 12: JMP done прыгает сам на себя.
  • В конце на табло A и лампах — 143 (1000 1111).
  • Внутри петли A прыгает между суммой и счётчиком: его загружают то из ячейки 0, то из ячейки 1 — так и должно быть.

Подумай. Что будет, если счётчик поставить 0? (Петля пройдёт 256 раз: 0 − 1 = 255, и до нуля ещё далеко.)

Не получается? Что-то не работает →