Напишите код на ассемблере, чтобы заставить процессор 6502 считать до 65536.

Я новичок в программировании на ассемблере и хочу, чтобы 6502 считал от 0 до 65536, и мне нужна помощь в коде. Я должен использовать 2 байта (слово), но проблема в том, что команда INC увеличивает только один байт.


person Roy Navjord    schedule 20.05.2021    source источник
comment
Используйте инструкцию ADC.   -  person Michael    schedule 20.05.2021
comment
с 16 битами вы можете сосчитать только до 65535. Вам нужно 17 бит, чтобы получить 65536   -  person phuclv    schedule 20.05.2021
comment
Что вы пробовали? Как вы собираетесь хранить значение 65536 в двух 8-битных байтах, поскольку диапазон 16 бит составляет 0-65535?   -  person some    schedule 22.05.2021
comment
Привет. Я указываю 65535. И я буду использовать 2 бита. Используйте команду ADC, и это, кажется, работает. Но у меня проблема с BCS (ветвь если нести). После этого программы не работают.   -  person Roy Navjord    schedule 22.05.2021
comment
@RoyNavjord Вы говорите, что у вас проблема с BCS. Не могли бы вы изменить свой вопрос, чтобы добавить код и объяснить, что пошло не так?   -  person JeremyP    schedule 11.06.2021


Ответы (2)


Я новичок в программировании на ассемблере

Подсказка на будущее

Большинство современных компьютеров (за редкими исключениями) работают с байтами. Это означает: эти компьютеры работают в системе base-256.

Те же математические правила, которые применяются к десятичной системе, применимы и ко всем другим системам, включая основание 256.

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

чтобы считать до 65536 ... я должен использовать 2 байта (слово), но проблема в том, что команда INC увеличивает только один байт.

Соответствующая задача в десятичной системе:

Я должен считать от 0 до 100. Однако в школе я только учил, какая десятичная цифра следует за другой цифрой (например, за 6 следует 7), но меня не учили, какое двузначное число следует за другим двузначным (например, 86). следует 87).

Теперь давайте рассмотрим десятичную задачу:

Для счета от 0 до 99 можно использовать две цифры; для счета до 100 уже требуется три цифры.

Вы, вероятно, решили бы проблему следующим образом:

  • Вы начинаете с 000
  • You would count up by one the following way:
    • You would replace the last digit by the following one.
      Example: If the current value is 086, you would replace the 6 by a 7 so you end up in 087.
    • Если последняя цифра 9, вы замените 9 на 0 и замените среднюю цифру.
      Пример. Если число 079, вы сначала замените последнюю цифру: 070 и поскольку вы заменили последнюю цифру на a 0, вы также заменяете среднюю цифру: 080
    • Если вы замените среднюю цифру на 0, вы также замените первую цифру: Выполняя шаги, описанные выше, 099 сначала становится 090, затем 000, затем 100
  • Как только вы выполнили последний шаг, ваша задача выполнена, потому что вы достигли значения 100.

Язык ассемблера:

Давайте снова посмотрим на шаги, сделанные в десятичной системе, и сравним их с шагами, которые мы должны сделать на ассемблере:

  • Десятичный: для счета от 0 до 99 можно использовать две цифры; для счета до 100 уже требуется три цифры.
    Ассемблирование: счет от 0 до 65 535 может выполняться с использованием двух байтов; 65536 уже требует три байта.
  • Десятичный: вы начинаете с 000
    Ассемблирование: вы должны использовать некоторые инструкции (например, LDA и STA), чтобы гарантировать, что три (или два) байта изначально иметь значение 0.
  • You would count up by one the following way:
    • Decimal: You would replace the last digit by the following one.
      Assembly: You use the INC instruction to increment (this means: count up) the last byte.
    • Десятичный: если последняя цифра 9, вы должны заменить 9 на 0 и...
      Ассемблирование: инструкция INC будет считать от 255 до 0 ; это как считать от 9 до 0 в десятичной системе. Инструкция INC установит флаг Z, когда будет считать от 255 до 0; он очистит флаг Z, если он этого не сделал.
      Используя инструкцию BNE, вы можете перейти к какой-либо инструкции, если флаг Z не установлен. Это означает, что вы можете пропустить некоторые инструкции, которые выполняются только в том случае, если INC считает от 255 до 0. (Или вы можете перейти назад к началу некоторого цикла, если вы не считали от 255 до 0...)
    • Десятичный: ... и заменить среднюю цифру.
      Ассемблирование: вы применяете инструкцию INC к среднему байту.
    • Десятичный: Если вы замените среднюю цифру на 0 ...
      Ассемблирование: Это означает: Инструкция INC, которую вы применили к среднему байту, заменила 255 на 0 и поэтому установите флаг Z!
  • Десятичный: как только вы выполнили последний шаг, ваша задача выполнена, так как вы достигли значения 100.
    Ассемблирование: то же верно для подсчета до 65536. в системе base-256.

Некоторые примечания:

6502 имеет три регистра: A, X и Y. По этой причине вы также можете считать в регистрах (INX, INY...) вместо подсчета в памяти, если ваше наибольшее число меньше 2^24.

person Martin Rosenau    schedule 20.05.2021
comment
вы можете считать только до 65535 с 2 байтами - person phuclv; 20.05.2021
comment
@phuclv Изначально я упомянул, что требуется три байта, но случайно удалил это предложение. обновляю свой ответ... - person Martin Rosenau; 20.05.2021
comment
Хотя может быть какой-то особый случай, когда вы захотите использовать INC + BNE, обычно вы используете ADC для увеличения многобайтового счетчика. - person Michael; 20.05.2021
comment
@Michael В случае подсчета INC имеет то преимущество, что операцию можно выполнить непосредственно в памяти; при использовании ADC требуется комбинация CLC (для младшего байта), LDA, ADC и STA. А инструкцию BNE можно использовать для перехода к началу цикла; в любом случае необходим переход к началу цикла. - person Martin Rosenau; 20.05.2021
comment
@phuclv два байта + перенос = 65536;) - person some; 22.05.2021

Мы знаем из начальной школы и базы 10, что говорят

 19
+ 1
====

вы используете перенос, чтобы перенести значения в следующую степень 10

 1
 19
+ 1
====
  0

9+1 = 0 нести 1.

Это работает для всех баз. Теперь также поймите ноль, есть подразумеваемый ноль, прежде чем вы начали

  0
 19
+ 1
====

в качестве переноса к этой первой цифре.

 10  
 19
+ 1
====
 20

это то, что он выглядит завершенным. Но что, если бы моя бумага была такой тонкой или я писал свои числа такими большими, что не мог уместиться, кроме одной колонки на странице?

колонка тех

10  
 9
+1
====
 0

столбец десятков должен был бы принести перенос из столбца единиц

01  
 1
+0
====
 2

подразумевает нуль для второго операнда, а также признает, что эта операция также имеет перенос, она равна нулю, поэтому нам все равно, тогда мы можем взять две операции, приводящие к 0 и 2, и объединить их в нашей голове, чтобы понять результат будет 20. 19+1 = 20

основание 2 или основание 16 ничем не отличаются

  1FFF
+ 0001
=======

младший значащий байт, без переноса

 110
  FF
+ 01
=======
  00

затем оставшиеся байты для столько байтов, сколько вы хотите, необходимо добавить перенос из предыдущей операции

  11
  1F
+ 00
=======
  20 

давая результат 0x2000, используя математику по одному байту за раз.

Таким образом, в зависимости от того, сколько вы хотите добавить за цикл, вы можете просмотреть инструкции, которые делают это, обращая особое внимание на то, изменяется ли флаг переноса в качестве вывода для этой операции. Затем найдите операцию добавления, которая добавляет этот флаг переноса для каскадирования. Обратите внимание, что для этого в той или иной форме требуется четыре байта, два для верхнего и два для нижнего операнда, хотя вы можете найти ярлыки.

аналогичным образом, если вы хотите остановиться на 65535 (мы предполагаем, что вы сделали там опечатку), вам нужно подумать о том, как выполнить сравнение с 0xFFFF побайтно и продолжать цикл, если оба байта не являются окончательным значением.

Или вы на самом деле должны считать 65536 раз от 0x0000 до 0x0000? Та же разница, за исключением того, где вы проводите циклический тест? В C это будет, например, while() или do...while().

person old_timer    schedule 20.05.2021
comment
Спасибо за хороший совет. На мой взгляд, я мог видеть команду, которая делает это автоматически, но теперь я вижу, как я должен это решить. И я имел в виду 65535 и 2 байта. - person Roy Navjord; 21.05.2021
comment
независимо от того, какой у вас процессор, существует ограничение на размер регистра. 32-битная машина должна синтезировать 64-битную математику, 64-битная машина должна синтезировать 128, 256, 1007-битную математику... для сложения, поэтому в большинстве наборов инструкций есть добавление с переносом. - person old_timer; 21.05.2021