Курс программирования на ассемблере для C64(Ghouls/Mechanix). Урок 1

Публикую первый из пяти уроков машинного кода от датского кодера Ghouls. уроки довольно старые но по сей день актуальные. В первом уроке рассматриваются основы ассемблера для процессора 6502. В уроках используется компилятор ассемблера Turbo Assembler v5, скачать можно отсюда. За перевод уроков огромное спасибо Crazy_Bender. Свои замечания, пожелания, вопросы оставляйте в комментариях.

Первое что вы должны узнать начиная изучать программирование на языке ассемблер это как работает компьютер. Компьютер воспринимает все данные как двоичные числа. Число также называют байтом, байт состоит из 8 бит.

Пример:

0 00000000
1 00000001
2 00000010
3 00000011
4 00000100
5 00000101
6 00000110
7 00000111

Цифры с левой стороны — привычные нам  десятичные. Справа — двоичные,  как их видит компьютер. В двоичной системе  бит, который располагается первым слева, называется бит №7, а самый правый называется бит №0. Поскольку байт состоит из 8 бит, и как каждый бит может иметь значение 0 либо 1, то мы имеем: 2*2*2*2*2*2*2*2=256 различных комбинаций. Наибольшее число, какое можно выразить с помощью байта — 255,  в двоичном представлении 11111111. Если нам будут нужны бОльшие числа, мы должны будем использовать второй байт, поэтому получим 256*256=65636 различных комбинаций. Числа более чем 65535 используются редко.

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

Пример:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12

Верхняя строка в десятичной системе, а нижняя — в шестнадцатеричном формате. Если у вас  есть  калькулятор, который может преобразовать из двоичной системы в другую, держите его  поблизости от компьютера — по крайней мере, на начальных этапах. Со временем вы поймете, что использование шестнадцатеричной системы счисления весьма и весьма практично в программировании. Ниже приведены некоторые примеры:

DEC BIN HEX
0 00000000 0
1 00000001 1
7 00000111 7
8 00001000 8
16 00010000 10
32 00100000 20
64 01000000 40
128 10000000 80
255 11111111 FF

Возможно есть немного логики в этом безумии, не так ли?

Ну все, достаточно о числах! Теперь, поговорим о памяти и программировании. Память состоит из 65536 ячеек пронумерованных от 0 до 65535 (или 0 — FFFF в шестнадцатеричном формате).  1024 байт называется 1 килобайт (или 1Kб ОЗУ).  64*1024 — это  65536, отсюда и название «Commodore 64.

Для написания программ мы будем использовать пакет ‘TURBO-ASS.V5’. Программа написанная на языке ассемблер состоит из небольших машинных команд. Все 56 инструкции состоят из 3-х букв, например: NOP , LDA, BCC, TXA, PLA некоторые из этих команд должны также сопровождаться 1 или 2-мя операндами, но об этом позже.

После того как вы набрали программу в Ассемблере нажмите ‘ < — ‘, а затем ‘3 ‘. Теперь компьютер преобразует все наши буквы и цифры в то, что он может понять: в двоичные числа.  Ассемблер различает десятичные, двоичные и шестнадцатеричные числа  следующим образом: перед двоичными числами ставится знак процента, а перед шестнадцатеричными числами знак доллара. Например:

DEC BIN HEX
16 %00010000 $10

Процессор 6510 (мозг С64) имеет 5 регистров, а именно:

  • A-регистр (аккумулятор)
  • X-регистр
  • Y-регистр
  • Программный счетчик
  • Указатель стека
  • Регистр состояния

Программный счетчик  содержит адрес байта, с которым процессор работает.

А — регистр, который будет использоваться в большинстве команд. Самая простая (и наиболее часто используемая) команда:

LDA     (LoaD Accumulator)

Например:

LDA #23 означает загрузить число 23 в аккумулятор. 6510-процессор 8-разрядный процессор, 255 самое большое число, которое A-регистр, может содержать. Знак # перед числом 23 означает что это число, а не адрес. Если мы его уберем, то получим  LDA 23. Это будет означать, что сначала берется число по адресу 23, и затем его значение присваивается  регистру А. Если после знака # добавить $, полчится  LDA #$23. Это будет означать, что регистр A будет содержать шестнадцатеричное число 23 (или  35 в десятичном эквиваленте). LDA $23 будет означать, что компьютер возьмет число по  адресу $23 (35 DECIMAL) и установит  это значение  в аккумуляторе.

Упражнение 1
Объясните разницу между LDA #%00010111 и LDA %00010111

Скрытый текст

Противоположна команде LDA команда:

  • STA (STore Accumulator) — она сохраняет  значение аккумулятора по указанному программистом  конкретному адресу.

Например:

а можно и так:

или:

Адреса всегда вводятся без #

Другие варианты:

Надеюсь, вы уже поняли принцип.

Попробуйте запустить следующую небольшую программу:

Что происходит?

Если вы сделали все правильно, должно быть «HEJ» в левом верхнем углу экрана. RTS означает «возвращение из подпрограммы”.  В этом случае означает, что компьютер должен  вернуться в BASIC. Подробнее о RTS позже.

Регистры X и Y работают так же, как регистр A. Примеры:

Также  — 255 ($FF) наибольшее число, которое они могут содержать. В дополнение к возможности загрузки и сохранения чисел, значение регистров X и Y также можно увеличивать и уменьшать. 4 Команды (2 для каждого) влияющие  напрямую на X и Y:

  • INY  (INcrease Y by one) — увеличивает значение регистра Y на 1
  • DEY (DEcrease Y by one) — уменьшает значение регистра Y на 1
  • INX  (INcrease X by one) — увеличивает значение регистра X на 1
  • DEX (DEcrease X by one) — уменьшает значение регистра X на 1

Пример:

После выполнения этого кода регистр X содержит значение $11. Но если бы было вместо INX стояла бы команда DEX значение  было бы $0F.  Но попробуйте следующий пример:

Что содержит  Y сейчас? Он содержит значение $00!  Не 256, поскольку  регистр не может содержать число больше 255.

Упражнение 2
Какое значение содержит регистр X?

Скрытый текст

У регистров X и  Y  гораздо больше возможностей, например:

Загружаем  в аккумулятор число из адреса $2000 и сохраняем его по адресу $1000(строки 1 и 2). Затем $08 сохраняется в регистре Y, число  по адресу $2008 загружается в регистр A  и сохраняется  по адресу $1001. Почему именно адрес $2008? Команда LDA $XXXX,Y добавляет содержимое Y к адресу $2000, но не к содержимому адреса $2000! Аналогичным образом:

Получить число из $3001 и сохранить его в $3000. НЕ читайте дальше, пока вы не убедитесь, что полностью понимаете.

Добавить комментарий