Ассемблер: взгляд издалека
Инфарх, 1998
Продолжение. Начало в |20
Итак, уважаемые читатели, продолжим наши
занятия. Надеюсь, вы уже обзавелись Ас-
семблером и прочли инструкцию к нему.
Впрочем, сегодня это не столь важно, а вот
когда теорию подтянем...
Но давайте по порядку. Сейчас предмет
нашего рассмотрения -
Представление чисел
Вы наверняка уже привыкли, что в двоич-
ной форме числа (в пределах байта) бывают
только положительные: от 0 до 255. Но в
действительности значение того или иного
числа зависит от того, как его интерпрети-
ровать. Возможно даже использование чисел
определенного диапазона как отрицательных.
Вы сами можете выбрать, в каких пределах
лежит ваше число: 0...255 или -128...+127.
Как же должно выглядеть отрицательное
число? Очевидно, оно должно давать нулевой
результат при сложении со своим положи-
тельным эквивалентом. Поэтому для получе-
ния числа с противоположным знаком необхо-
димо:
1) Инвертировать все биты числа;
2) Увеличить его на единицу.
"А есть ли другие виды представления чи-
сел?" - спросите вы.
Да, есть. Это - не так часто используе-
мая, но тем не менее иногда полезная -
двоично-десятичная форма. В ней числа бы-
вают от 0 до 99. Байт делится на полубайты
(4 бита). Каждый из них принимает значения
0...9. Вычисления с примененем такой формы
более сложны, но не отчаивайтесь! В свое
время это будет рассмотрено.
Регистры центрального процессора
Теперь поговорим о том, что можно найти
внутри Z80, если как следует там поковы-
ряться. Вообще-то, там много интересного,
но пока нам нужны только занятные предме-
ты, в просторечии именуемые РЕГИСТРЫ.
Предназначены они для того же, что и обык-
новенные, известные по Бейсику, перемен-
ные, а именно - для хранения информации и
безобразных издевательств над оной.
Регистр обозначается буквой латинского
алфавита. Для регистров общего назначения
процессора Z80 используются буквы:
A B C D E H L
Самым главным является регистр А, назы-
ваемый "аккумулятором". С ним прoизводятся
все арифметические и логические операции,
в нём же остаётся их результат.
Вмещает регистр один байт информации. Но
ведь иногда необходимо работать и с боль-
шими значениями! Выход есть: регистры мо-
гут объединяться в пары, соответственно
увеличивая свою ёмкость до одного слова
(2 байта). Объединение происходит отнюдь
не произвольно, а в весьма конкретной фор-
ме. Вот возможные варианты регистровых
пар:
BC DE HL
Главной регистровой парой является HL.
Она, как и аккумулятор, необходима почти
во всех операциях. Кстати, вас, наверное,
удивило, что для "А" пары не нашлось? На
самом деле есть и она, но регистр-пара к
"А" - вовсе не общего назначения, поэтому
его мы пока изучать не будем. Скажу лишь,
что имя его - "F", и образует он пару
"AF".
Ещё есть служебные регистры - "I" и "R".
Они не объединяются в пары, а существуют
сами по себе.
Ещё есть пары, которые на отдельные ре-
гистры не делятся (точнее, делятся, но
особо извращёнными методами, их упоминать
пока рано). Вот их имена:
IY IX
А ещё есть шестнадцатиразрядные, не де-
лимые на пары, регистры:
SP PC
Думаете, это всё? А вот и нет! Ещё есть
альтернативные регистры:
A' F' B' C' D' E' H' L'
Они, соответственно, образуют пары:
AF' BC' DE' HL'
Работа с регистрами общего назначения
Если мы хотим совершать какие-либо дейс-
твия над регистрами, то для начала надо
научиться придавать им конкретные значе-
ния. Для этой цели используется команда
ассемблера с мнемоникой "LD", которая яв-
ляется сокращением английского слова Load
(загрузить). Надо сказать, что команда эта
- не только для регистров, она ещё и для
ячеек памяти может пригодиться. Вот воз-
можные варианты её применения:
LD r,r
LD r,(HL)
LD r,n
LD r,(ii+n)
LD (HL),r
LD (ii+n),r
LD (HL),n
LD (ii+d),n
LD A,(BC)
LD A,(DE)
LD A,(nn)
LD (BC),A
LD (DE),A
LD (nn),A
LD rr,nn
LD ii,nn
LD HL,(nn)
LD rr,(nn)
LD ii,(nn)
LD (nn),HL
LD (nn),rr
LD (nn),ii
LD I,A
LD R,A
LD A,I
LD A,R
Расшифруем использованные сокращения:
r = A, B, C, D, E, H, L
rr = BC, DE, HL, SP
ii = IX, IY
n = байт [#00..#FF]
nn = слово [#0000..#FFFF]
Зная, что может команда "LD", остаётся
уточнить, что означают некоторые конструк-
ции, например, "(nn)" и "rr". А это - все-
го лишь байт, на адрес которого указывает
слово "nn" или содержимое регистровой пары
"rr".
Или вот "(ii+n)". Тоже просто: адрес
байта определяется сложением содержимого
регистра "ii" и байта "n". Это удобно при
большом количестве переменных, сведённых в
таблицы. В этом случае достаточно занести
адрес начала таблицы в "ii", а конкретный
элемент получать, задавая в команде смеще-
ние. Кстати, здесь есть одна тонкость. Та-
ким методом возможна адресация в диапазоне
не (ii)...(ii+255), а (ii-128)...(ii+127).
При использовании команд загрузки, равно
как и прочих команд процессора, помните
одно правило: пересылка происходит в на-
правлении от второго параметра команды в
первый. Иными словами, команды "LD A,5" и
"LD C,A" означают, что в регистр "А" поме-
щается число 5, а затем его содержимое пе-
ресылается в регистр "В".
Регистр "F" называется "флаговым". Его
биты (флаги) - каждый по отдельности -
служат для индикации результатов операций,
выполняемых процессором.
Шестнадцатиразрядный регистр "SP" указы-
вает на вершину машинного стека - область
памяти, предназначенную для хранения неко-
торой информации. Но это - отдельная исто-
рия.
Регистр "PC" является программным счёт-
чиком. Число, хранящееся в нём, является
адресом команды, исполняемой в текущий мо-
мент.
Помните! На начальном этапе обучения, во
избежание кошмарных глюков, зависаний и
прочего, не используйте для опытов ре-
гистры SP, PC, HL'. В случае с IY старай-
тесь не менять содержимое адресуемых им
ячеек памяти и собственно его содержимое.
Работа с альтернативными регистрами
Эти регистры включаются вместо основных
с помощью команды ассемблера
EXX
Её мнемоника происходит от слова "ex-
change" (обмен). При выполнении команды
происходит обмен
HL <=> HL'
DE <=> DE'
BC <=> BC'
Для включения альтернативной пары AF'
служит команда с мнемоникой
EX AF,AF'
Вообще-то, нет никакой возможности
узнать, какой набор регистров активен в
данный момент. Процессор тоже не в курсе -
ему это "фиолетово". Так что считайте
альтернативным тот набор, который в данный
момент не активен.
Арифметика
Здeсь у Z80 возможности несколько огра-
ничены. Он может производить только сложе-
ние и вычитание. Вот некоторые варианты
этих действий:
ADD A,r
ADD A,(HL)
ADD A,n
ADD A,(ii+n)
ADD HL,rr
ADD IX,ry
ADD IY,rx
SUB r
SUB (HL)
SUB n
SUB (ii+n)
ADD означает сложение, а SUB - вычита-
ние. Результат вычисления помещается в ре-
гистр, который в команде стоит первым. Но
не особенно старайтесь его запомнить. Если
вычисления производятся над однобайтным
числом, то первым всегда будет "А" (обра-
тите внимание: в этом случае команда SUB
не требует первого операнда). А если про-
изводятся операции над словом, то в начале
будет HL, IX или IY.
Флаги
Перечислим все возможные флаги регистра
"F":
D7 D6 D5 D4 D3 D2 D1 D0
S Z * H * P/V N CY
Флаг S (sign) устанавливается, если при
выполнении арифметической или логической
операции получился отрицательный ре-
зультат.
Флаг нуля Z (zero) устанавливается, если
в результате выполнения арифметической или
логической операции получился нулевой ре-
зультат.
Флаги H (half-carry) и N (negative) ис-
пользуются весьма редко - в основном, при
работе с двоично-десятичными числами.
Флаг чётности/переполнения P/V (parity/
overflow) - единственный, на который воз-
ложена индикация сразу двух условий. Флаг
чётности устанавливается, если в результа-
те логической операции в байте оказалось
чётное количество установленных в "1" бит.
Флаг переполнения показывает, что после
арифметического действия изменился знак
операнда.
Флаг переноса CY (carry) говорит, что в
результате арифметической операции произо-
шёл перенос из старшего разряда. Например,
в случае: 253 + 5 = 258. Разрядов регистра
не хватит для сохранения такого результа-
та. Поэтому реально мы получим число 2 и
установленный флаг CY.
К сему добавлю, что далеко не все коман-
ды процессора влияют на флаги, и, кроме
того, отдельные команды изменяют только
некоторые биты флагового регистра.
Назад к арифметике
А теперь, узнав о флагах, можно перейти
к арифметическим операциям, учитывающим
перенос:
ADC A,r
ADC A,(HL)
ADC A,n
ADC A,(ii+n)
ADC HL,rr
SBC A,r
SBC A,(HL)
SBC A,n
SBC A,(ii+n)
SBC HL,rr
В качестве примера рассмотрим такую си-
туацию: надо прибавить к "А" некое число.
Никаких проблем не возникнет, пока ре-
зультат можно описать одним битом.
Однако всё усложнится (хоть и не намно-
го) в такой, например, ситуации:
А = 200
n = 57
Естественно, 200 + 57 = 257. Но в одном
байте это не уместится. Поэтому там сохра-
нится число 1, и установится флаг CY. Вро-
де, пока всё понятно, и используемая ко-
манда никаких сомнений не вызывает:
ADD A,57
Но, если следующая команда будет из
группы ADD или SUB, то содержимое CY будет
потеряно, так что не забывайте о группах
ADC и SBC!
──══════════──
Ознакомившись со всем вышеизложенным и,
вооружась выбранным вами ассемблером, по-
экспериментируйте - и вы поймете, что в
этом что-то есть! Но не забывайте: любая
ассемблерная программа должна заканчи-
ваться командой
RET
Итак, дерзайте! И до новых встреч.
──══════════──