russian ROMhacking
[ Новые сообщения · Участники · Правила форума · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Инструкции процессора Motorola 68000
SmokeДата: Понедельник, 29.06.2009, 23:03 | Сообщение # 1
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
В этой теме буду выкладывать описание инструкций главного проца SMD -- Motorola68000. Данная тема направлена на помощь в изучении ассемблера начинающим кодить для М68К. Пока машинные эквиваленты писать не стал, возможно и их укажу потом для некоторых вариантов инструкций. По мере возможностей буду добавлять.

Варианты адресования

1) Непосредственное адресование между регистрами данных

Обозначение <ea>: Dn

Синтаксис: move.x Dy, Dz
где х -- тип данных byte, word или longword
Dy, Dz -- регистры данных D0-D7

Пример: move.l D1, D0 копирует содержимое регистра D1 в регистр D0. Когда инструкция выполнена оба регистра
принимают одинаковое значение.

Инструкция До После

Code
-------------------------------------------------------
|MOVE.B D1,D0 | D0=FFFFFFFF   | D0=FFFFFF67    |
|                           | D1=01234567 | D1=01234567  |
-------------------------------------------------------
|MOVE.W D1,D0 | D0=FFFFFFFF   | D0=FFFF4567    |
|                            | D1=01234567 | D1=01234567  |
-------------------------------------------------------

2) Непосредственное адресование между адресным регистром и регистром данных

Обозначение <ea>: An

Синтаксис: move.x Ay, Dz
где х -- тип данных word или longword
Ay, -- адресный регистр a0-a7
Dz -- регистр данных D0-D7

Пример: move.l A1, D0 копирует содержимое регистра А1 в D0. После выполнения инструкции оба регистра принимают
одинаковое значение. Тип данных может быть только word или longword.

Инструкция До После

Code
------------------------------------------------------
|MOVE.W A1,D0 | D0=FFFFFFFF   | D0=FFFF4567   |
|                            | A1=01234567 | A1=01234567 |
------------------------------------------------------

3) Косвенное адресование между адресным и регистром данных

Обозначение <ea>: (An)

Синтаксис: move.x (Ay), Dz
где х -- тип данных byte, word или longword
Ay, -- адресный регистр a0-a7
Dz -- регистр данных D0-D7

Пример: move.l (A0), D0 копирует данные находящиеся по адресу записанному в регистре А0. Если тип данных
word или longword, то адрес в адресном регистре должен быть четным!!!

Инструкция До После

Code
--------------------------------------------------------------------------
|MOVE.L (A0),D0 | D0=FFFFFFFF                 | D0=01234567                  |
|                             | A0=00FF1000                | A0=00FF1000                  |
|                             | $00FF1000=01234567 | $00FF1000=01234567 |
--------------------------------------------------------------------------

4) Косвенное адресование между адресным и регистром данных с пост-инкрементированием

Обозначение <ea>: (An)+

Синтаксис: move.x (Ay)+, Dz
где х -- тип данных byte, word или longword
Ay, -- адресный регистр a0-a7
Dz -- регистр данных D0-D7

Примечание: работает также как и предыдущая инструкция, только после ее выполнения адресный регистр увеличивается
на размер типа данных(если byte, то на 1 байт, word -- на 2 байта, longword -- на 4 байта).

Пример: move.l (A1)+,D0 копирует данные находящиеся по адресу записанному в регистре А1 в регистр D0 и
увеличивает А1 на 4 байта.

Инструкция До После

Code
-------------------------------------------------------------------------
|MOVE.L (A1)+,D0 | D0=FFFFFFFF              | D0=01234567            |
|                    | A1=00FF1000             | A1=00FF1004             |
|                    | $00FF1000=01234567 | $00FF1000=01234567 |
-------------------------------------------------------------------------

5) Косвенное адресование между адресным и регистром данных с пре-декрементированием

Обозначение <ea>: -(An)

Синтаксис: move.x -(Ay), Dz
где х -- тип данных byte, word или longword
Ay, -- адресный регистр a0-a7
Dz -- регистр данных D0-D7

Примечание: работает также как и предыдущая инструкция, только до ее выполнения адресный регистр уменьшается
на размер типа данных(если byte, то на 1 байт, word -- на 2 байта, longword -- на 4 байта).

Инструкция До После

Code
------------------------------------------------------------------------------
|MOVE.L -(A1),D0 | D0=FFFFFFFF              | D0=01234567            |
|                         | A1=00FF1004             | A1=00FF1000             |
|                         | $00FF1000=01234567 | $00FF1000=01234567 |
------------------------------------------------------------------------------

6) Косвенное адресование между адресным и регистром данных со сдвигом

Обозначение <ea>: x(An)

Синтаксис: move.x n(Ay), Dz
где х -- тип данных byte, word или longword
Ay, -- адресный регистр a0-a7
Dz -- регистр данных D0-D7
n -- сдвиг

Пример: move.l 4(A0), D0 копирует данные находящиеся по адресу записанному в регистре А1 + 4 байта в регистр D0
А0 после выполнения инструкции не меняется. Если n больше чем 7FFF, то оно считается отрицательным.

Инструкция До После

Code
--------------------------------------------------------------------
|MOVE.L 4(A0),D0 | D0=FFFFFFFF        | D0=01234567      |
|                          | A0=00001000      | A0=00001000      |
|                          | $1004=01234567 | $1004=01234567 |
--------------------------------------------------------------------

7) Косвенное адресование между адресным и регистром данных со сдвигом(еще вариант)

Обозначение <ea>: x(An,Dn.L)
x(An,Dn.W)
x(An,An.W)
x(An,An.L)

Синтаксис: move.x n(Ay,Dz.l), Ds
move.x n(Ay,Dz.w), Ds
move.x n(Ay,Az.w), Ds
move.x n(Ay,Az.l), Ds

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

Пример: move.l 4(A1,A2.w),D0 копирует адрес получившийся сложением A1(всего)+A2(word)+4 в D0. Регистры
А1 и А2 после выполнения не изменяются. Если n больше $7F, число считается отрицательным.

Инструкция До После

Code
-------------------------------------------------------------------------------------
|MOVE.L 4(A1,A2.w),D0 | D0=FFFFFFFF               | D0=01234567            |
|                    | A1=00FF1000             | A1=00FF1000             |
|                    | A2=00FF1000             | A2=00FF1000             |
|                    | $00FF2004=01234567 | $00FF2004=01234567 |
-------------------------------------------------------------------------------------

8) Абсолютное адресование

Обозначение <ea>: label

Синтаксис: move.x $y, Dz
где х -- тип данных byte, word или longword
$y, -- адрес из которого будут копироваться данные
Dz -- регистр данных D0-D7

Пример: move.l $00FF1234, D0 копирует данные(longword в этом случае) по адресу $00FF1234 в регистр D0.

Инструкция До После

Code
------------------------------------------------------------------------------------
|MOVE.L $00FF1234,D0 | D0=FFFFFFFF               | D0=01234567            |
|                    | $00FF1234=01234567  | $00FF1234=01234567 |
------------------------------------------------------------------------------------

P.S. Как-нибудь можно эти таблицы выровнять? А то я пытался, пытался и безрезультатно sad

Сообщение отредактировал Smoke - Пятница, 31.07.2009, 21:56
 
TLTДата: Вторник, 30.06.2009, 00:58 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 2367
Статус: Оффлайн
Quote
P.S. Как-нибудь можно эти таблицы выровнять? А то я пытался, пытался и безрезультатно

используй тэг "code"



Вот так.
 
zephyrДата: Четверг, 02.07.2009, 10:47 | Сообщение # 3
Сержант
Группа: Проверенные
Сообщений: 20
Статус: Оффлайн
Smoke,
Отлично! Спасибо!
Продолжай, я буду читать!


coder
 
SmokeДата: Четверг, 02.07.2009, 22:12 | Сообщение # 4
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
zephyr, спасибо! Итак, продолжим, в этот раз с небольшим примерчиком smile

9)Адресование со смещением относительно PC(Program Counter)

Обозначение <ea>: x(PC)

Синтаксис: move.x n(pc), Dy
где х -- тип данных byte, word или longword
рс -- значение Program Counter в момент выполнения инструкции
n -- величина смещения
Dy -- регистр данных D0-D7

Примечание: величина смещения(n) имеет тип word, также sign, т.е. изменяется в диапазоне -7FFF..+7FFF.

Пример: move.l $100(pc), d0 копирует данные(longword), находящиеся по смещению PC+$102(102 потому что х имеет тип word).

Code
       Инструкция                      До                           После
           ------------------------------------------------------- - - - --------------
           |MOVE.L $100(PC),D0 |    D0=FFFFFFFF     |    D0=01234567  |
           |(при этом PC=$1000)| $1102=01234567 | $1102=01234567 |
           ------------------------------------------------------------------------

10)Непосредственное адресование

Обозначение <ea>: #x

Синтаксис: move.x #n, Dy
где х -- тип данных byte, word или longword
#n -- обычное число, например $12
Dy -- регистр данных D0-D7

Пример: move.w #$1234, d0 копирует число $1234 в регистр D0

Code
       Инструкция                     До             После
           -------------------------------------------------------------
           |   MO VE.W #$1234,D0 | D0=FFFFFFFF | D0=FFFF1234 |
           |                    |                    |                     |
           -------------------------------------------------- -- -- -- -----

Т.к. варианты адресования рассматривались на примере инструкции MOVE, захватим оставшиеся ее варианты.
11)Быстрое копирование

Синтаксис: moveq #x, Dy
где х -- обычное число, тип byte, при значении больще чем $7F считается отрицательным
Dy -- регистр данных D0-D7

Пример: moveq #$26, d4 копирует число $26 в регистр D4, причем полностью изменяет его. Смотри ниже

Code
       Инструкция                   До             После
           -----------------------------------------------------------
           | MO VE Q #$26, D0 | D0=FFFFFFFF | D0=00000026 |
           |                    |                    |                       |
           ------------------------------------------------ -- -- -- -----

12)Копирование в адресный регистр

Синтаксис: movea.х #$n, Ay
где n -- адрес, который надо поместить в адресный регистр
х -- тип word или longword
Ay -- адресный регистр A0-A7(да, да SP тоже используется)

Пример: movea.l #$00FFFF0E, A3 помещает в регистр A3 значение(адрес) #$00FFFF0E

Code
       Инструкция                       До                         После
           -------------------------------------------------------- - - - --------
           |MOVEA.L #$00FFFF0E, A3 | A3=FFFFFFFF | A3=00FFFF0E |
           |________________________|                   |                      |
           ---------------------------------------------- --  -- -----------------

Все варианты адресования, характерные именно для инструкций MOVE будут приведены позже

Добавлено (02.07.2009, 22:12)
---------------------------------------------

Stack Pointer(SP)

SP это как бы системная память. Например, при выполнении перехода к подпрограмме jsr или bsr, нужно
обязательно вернуться назад(для этого отвечает rts). И поэтому при самом переходе в SP копируется смещение
этого перехода, а при RTS из SP смещение перехода копируется назад и процессор возвращается в исходное
место. Бывают случаи, когда при выполнении подпрограммы используются регистры(или регистр), в которых записаны
параметры для этой подпрограммы. Вот пример.
Пусть мы хотим вывести звук в игре. Это будет выглядеть типа такого:
Code
move.w    #$12, d0    ; загрузка номера звука в регистр d0, это нужно для последующего его определения в массиве
                        ; звуков
jsr       sub                 ; непосредственно переход к подпрограмме
move.w    d0, d1        ; копирование d0 в d1

Но, в этой подпрограмме изменяется регистр d0:

Code
;--------------SUBROUTINE-------------------
sub:
..................
..................
..................
moveq    #1, d0
..................
..................
rts

То есть мы видим, что по окончании подпрограммы в регистре d0 будет значение 1, а нам нужно $12. И поэтому,
чтобы сохранить значение $12 в памяти, но и используя в то же время регистр мы и используем SP. Вот обновленный
пример:

Code
;--------------SUBROUTINE-------------------
sub:
..................
..................
..................
move.w   d0, -(sp) ; копирование d0 в SP
moveq    #1, d0
..................    ; какие-либо инструкции, процедуры
move.w   (sp)+, d0 ; копирование $12 обратно в d0
..................
..................
rts

Можно вместо sp использовать A7, но это тоже самое. Как видите, нужно обязательно декрементировать SP до
выполнения инструкции и инкрементировать после. Для копирования нескольких регистров за раз используют
MOVEM (MOVE Multiply)
Вариантов может быть множество. Вот некоторые:
movem d0-d5, -(sp) ; копируются регистры с D0 по D5 включительно
movem d0-d2/a3-a5, -(sp) ; копируются регистры с D0 по D2 и с A3 по А5[code]

Сообщение отредактировал Smoke - Среда, 08.07.2009, 21:54
 
CARIДата: Четверг, 02.07.2009, 22:48 | Сообщение # 5
Полковник
Группа: Заблокированные
Сообщений: 152
Статус: Оффлайн
Smoke, Полезное дело делаешь, негде нет такой инфы, эксклюзив)) Продолжай в том же духе!

 
МаратДата: Понедельник, 06.07.2009, 01:36 | Сообщение # 6
Сержант
Группа: Проверенные
Сообщений: 31
Статус: Оффлайн
2Cari
Почему нет? Есть и уже давно.
 
CARIДата: Понедельник, 06.07.2009, 06:56 | Сообщение # 7
Полковник
Группа: Заблокированные
Сообщений: 152
Статус: Оффлайн
И где они. Ссылку в студию)

 
МаратДата: Понедельник, 06.07.2009, 10:54 | Сообщение # 8
Сержант
Группа: Проверенные
Сообщений: 31
Статус: Оффлайн
Вот она - ссылка ремонт smd
 
SmokeДата: Вторник, 07.07.2009, 23:01 | Сообщение # 9
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
Есть у меня эта дока, только в ней написано о инструкциях и адресовании все поверхностно, новичок сразу не поймет. По крайней мере я не понял в свое время. Я же хочу написать еще и пояснения с примерами чуть ли не на кухонном уровне, чтобы каждому было максимально понятно и доступно smile
 
MefistotelДата: Среда, 08.07.2009, 05:05 | Сообщение # 10
Рядовой
Группа: Проверенные
Сообщений: 19
Статус: Оффлайн
Интересно.
Smoke, если будешь продолжать, то будет отлично.
Потом бы в будущем добавить примерчик процедур из какой-нибудь игры...


ПЕРЕВОД ПРИСТАВОЧНЫХ ИГР
 
SmokeДата: Среда, 08.07.2009, 22:25 | Сообщение # 11
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
Quote (Mefistotel)
Потом бы в будущем добавить примерчик процедур из какой-нибудь игры...

Как-нибудь тщательно разберу одну из своих подпрограмм в мк2 с пояснениями естественно smile

Отредактировал первые посты, теперь сначала идут описания вариантов адресования на примере MOVE, в будущем будем просто на них ссылаться(чтобы не писать по несколько раз один и тот же пример)

Арифметические инструкции

Code
ADD, ADDA, ADDI, ADDQ        Различные типы суммирования
CLR                    Обнуление операнда
CMP, CMPA, CMPI, CMPM         Различные типы сравнения двух операндов
DIVS, DIVU                             Деление Signed и Unsigned
MULS, MULU                            Умножение Signed и Unsigned
SUB, SUBA, SUBI, SUBQ          Различные типы вычитания
TST                    Сравнение операнда с нулем

1)Обычное суммирование ADD
Складывает между собой 2 операнда и записывает результат во втором

Синтаксис: 1)add.n <ea>, Dn
2)add.n Dn, <ea>

Варианты адресования: 1)<ea>: Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s), #x
2)<ea>: (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: byte, word или longword

Пример:

Code
       Инструкция            До             После
          ------------------------------------------------------------------
          |ad d. w ($00FFF70E).l, d0 | d0=FFFF0002       | d0=FFFF0004       |
          |                    | $00FFF70E=00020004| $00FFF70E=00020004|
          ------------------------------------------------------------------

Если берутся данные из RAM и тип данных word, то считываются левые 2 байта, если байт -- левый 1 байт

2)Суммирование с адресным регистром ADDA
Складывает операнд со значением в адресном регистре.

Синтаксис: ADDA <ea>, An

Варианты адресования <ea>: Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l,
x(PC), x(PC,xr.s), #x

Тип данных: Word, longword

Пример:

Code
       Инструкция            До             После
          --------------------------------------------
          |adda.w d0, a0 | a0=00FF0002 | a0=00FF0006 |
          |                  | d0=10000004 | d0=10000004 |
          --------------------------------------------

Добавлено (08.07.2009, 22:25)
---------------------------------------------
3)Быстрое суммирование ADDQ
Работает также как и add, за исключением того, что в качестве первого операнда ВСЕГДА используется число,
отсутствует тип данных и инструкция очень мала(2 байта)

Синтаксис: ADDQ #<data>,<ea>
<data> -- число от 1 до 8

Варианты адресования <ea>: Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Пример:

Code
       Инструкция            До             После
          -------------------------------------------
          |addq #$5, d0 | d0=00FF0002 | d0=00FF0007 |
          |                  |             |             |
          -------------------------------------------

4)Непосредственное суммирование ADDI
Прибавляет натуральное число к операнду

Синтаксис: ADDI #x,<ea>

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, Word, longword

Пример:

Code
       Инструкция            До             После
          ----------------------------------------------
          |addi.w #$45, d0 | d0=00FF0002 | d0=00FF0047 |
          |                     |             |             |
          ----------------------------------------------

5)Обнуление CLR
Обнуляет операнд

Синтаксис: CLR <ea>

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Пример:

Code
       Инструкция     До             После
          ---------------------------------------
          |clr.w d0 | d0=00FF0002 | d0=00FF0000 |
          |            |                      |                        |
          ---------------------------------------

6)Сравнение CMP
Сравнивает регистр данных с операндом. Ни регистр, ни операнд после инструкции не изменяются. Часто
используется в связке с условными переходами типа Bcc(будут рассмотрены позже)

Синтаксис: CMP <ea>,Dn

Варианты адресования <ea>: Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l,
x(PC), x(PC,xr.s), #x

Тип данных: Byte, word, longword

Пример:
cmp.w d0, d1 ; сравнение двух регистров
beq.s label ; переход, если регистры равны
...........

Добавлено (08.07.2009, 22:25)
---------------------------------------------
7)Сравнение с адресным регистром CMPA
Сравнивает адресный регистр с операндом. Ни регистр, ни операнд после инструкции не изменяются. Часто
используется в связке с условными переходами типа Bcc(будут рассмотрены позже)

Синтаксис: CMPA <ea>,An

Варианты адресования <ea>: Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l,
x(PC), x(PC,xr.s), #x

Тип данных: Word, longword

Пример смотри в пункте 6 -- Сравнение

[b8)Сравнение с числом CMPI[/b]
Сравнивает операнд с натуральным числом. Ни регистр, ни операнд после инструкции не изменяются. Часто
используется в связке с условными переходами типа Bcc(будут рассмотрены позже)

Синтаксис: CMPI #<data>, <ea>

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

9)Деление(Signed) DIVS
Делит регистр данных на операнд. Регистр имеет тип longword, операнд всегда word. Результат сохраняется
в регистре данных следующим образом: целая часть записывается в правых 2-х байтах, остаток -- в левых.

Синтаксис: DIVS <ea>,Dn

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l, x(PC),
x(PC,xr.s), #x

Тип данных: word

[bi]Пример:[/i]

Code
       Инструкция         До             После
          ----------------------------------------------
          |divs   #$10, d0 | d0=00000026 | d0=00060002 |
          |                     |                   |                   |
          ----------------------------------------------

10)Деление(Unsigned) DIVU
Работает также как и DIVS, за исключением того, что регистр cчитается Unsigned.

11)Умножение(Signed) MULS
Умножает регистр данных с операндом(оба типа word). Результат размером 4 байта записывается в регистр данных

Синтаксис: MULS <ea>,Dn

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l, x(PC),
x(PC,xr.s), #x

Тип данных: Word

Пример:

Code
       Инструкция         До             После
          ----------------------------------------------
          |muls   #$10, d0 | d0=00FF0026 | d0=00000260 |
          |                     |                     |                     |
          ----------------------------------------------

12)Умножение(Unsigned) MULU
Работает также как и MULS, за исключением того, что регистр cчитается Unsigned.

13)Вычитание SUB, SUBA, SUBI, SUBQ имеют те же свойства, что и подобные инструкции сложения, за исключением того,
что здесь выполняется не сложение, а вычитание :Р Поэтому смотрим выше в инструкции сложения.

14)Тест TST
Сравнивает операнд с нулем. Часто используется в связке с условными переходами типа Bcc(будут рассмотрены позже)

Синтаксис: TST <ea>

Варианты адресования <ea>: Dn, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Сообщение отредактировал Smoke - Пятница, 31.07.2009, 21:55
 
МаратДата: Пятница, 10.07.2009, 02:56 | Сообщение # 12
Сержант
Группа: Проверенные
Сообщений: 31
Статус: Оффлайн
Ну так, Smoke, я тебя ведь и не отговариваю. Продолжай в том же духе. Это я для Cari писал.
 
SmokeДата: Четверг, 16.07.2009, 20:21 | Сообщение # 13
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
Перемещение данных

Эти инструкции копируют данные из одного места в другое

Code
EXG   (EXchanGe)         Меняет местами содержимое двух регистров
LEA   (Load Effective Address) Просчитывает нахождение метки в программе и записывает его в адресный регистр
MOVE                    Копирует содержимое одного регистра(ячейки памяти) в другой регистр или ячейку памяти
MOVEA (MOVE Address)          Тоже что и MOVE, только принимаемым операндом является адресный регистр
MOVEM (MOVE Multiple)          копирует множество регистров в память или из нее.
MOVEQ (MOVE Quick)             записывает константу в регистр данных
PEA   (Push Effective Address) Просчитывает нахождение метки в программе и записывает его в SP
SWAP                    Меняет местами байты(word) в регистре данных

1)Замена EXG
Меняет местами содержимое двух регистров

Синтаксис: EXG Rx,Ry

Варианты адресования (Rx и Ry): Dn, An

Тип данных: Longword

Пример:

Code
       Инструкция         До           После
         -------------------------------------------
         |exg   d0, d1 | d0=00FF0026 | d0=12345678 |
         |                  | d1=12345678 | d1=00FF0026 |
         -------------------------------------------

2)Загрузка адреса LEA
Записывает адрес метки программы в адресный регистр. Часто используется, когда нужно, чтобы программа
не зависела от смещения самой метки.

Синтаксис: LEA <ea>,An

Варианты адресования(<ea>): (An), x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s)

Тип данных: Longword

Пример:

Code
       Инструкция             До                     После
         ----------------------------------------------------------
         |lea    ( label).l, a0 | label: 00374A26 | label: 00374A26 |
         |                         | a0=00FF0000     | a0=00374A26     |
         ----------------------------------------------------------

3)Копирование MOVE
Копирует содержимое одного регистра(ячейки памяти) в другой регистр или ячейку памяти.

Синтаксис: MOVE <ea>,<ea>

Варианты адресования(<ea>): (для источника) Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s),
label.w, label.l, x(PC), x(PC,xr.s), #x
Варианты адресования(<ea>): (для принимающего) Dn, (An), (An)+, -(An), x(An), x(An,xr.s),
label.w, label.l

Тип данных: byte, word, longword

Пример: смотри в главе "методы адресования"

Добавлено (16.07.2009, 20:21)
---------------------------------------------
4)Копирование в адресный регистр MOVEA
Копирует содержимое операнда в адресный регистр. Допускаются только данные типа word или longword.

Синтаксис: MOVEA <ea>,An

Варианты адресования(<ea>): Dn, An, (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l,
x(PC), x(PC,xr.s), #x

Тип данных: word, longword

Примечание: Большинство компиляторов при указании принимающего операнда как адресный регистр,
автоматически заменяют MOVE на MOVEA.

Пример: смотри в главе "методы адресования"

5)Множественное копирование MOVEM
Копирует группу регистров в память за один раз или наоборот. Инструкция часто используется для записи
регистров в SP и последующего оттуда копирования обратно по регистрам. Т.о. можно временно хранить там
содержимое регистров.

Синтаксис: 1)MOVEM <registerlist>,<ea>
2)MOVEM <ea>,<registerlist>

Варианты адресования(<ea>): 1)(An), -(An), x(An), x(An,xr.s), label.w, label.l
2)(An), (An)+, x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s)

Тип данных: Word, longword

Пример: смотри в главе "Stack Pointer"

6)Быстрое копирование MOVEQ
Инструкция копирует число в диапазоне от -127 до +127 в регистр данных. Размер ее всего лишь 2 байта,
когда размер например MOVE.L равен 6-ти байтам.

Синтаксис: MOVEQ #<data>,Dn

Варианты адресования: только число

Тип данных: вообще всегда longword, но индекс ".l" не пишется

Пример:

Code
       Инструкция            До             После
         ---------------------------------------------
         |MOVEQ #$26, D0 | D0=FFFFFFFF | D0=00000026 |
         |                          |                    |                      |
         ---------------------------------------------

7)Запись адреса в SP. PEA
Инструкция просчитывает адрес операнда и записывает его в SP.

Синтаксис: PEA <ea>

Варианты адресования(<ea>): (An), x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s)

Тип данных: Longword

Пример:

Code
       Инструкция            До                       После
         -------------------------------------------------------------
         | pea (label).l  | a7=00FFFFFC             | a7=00FFFFFC         |
         |                   | $00FFFFFC: 87654321 | $00FFFFFC: 01234567 |
         |                   | label: 01234567         | label: 01234567     |
         -------------------------------------------------------------

8)Замена в регистре SWAP
Меняет данные(word) в регистре местами.

Синтаксис: SWAP Dn

Тип данных: word

Пример:

Code
       Инструкция      До          После
         ------------------------------------------
         |SWAP D0     | D0=01234567 | D0=45670123 |
         |                 |                  |                  |
         ------------------------------------------


Сообщение отредактировал Smoke - Пятница, 31.07.2009, 21:54
 
zephyrДата: Пятница, 17.07.2009, 20:40 | Сообщение # 14
Сержант
Группа: Проверенные
Сообщений: 20
Статус: Оффлайн
Smoke,
Молодец! Отлично! Я читаю... Пиши еще!!! Ждем!!!


coder
 
SmokeДата: Воскресенье, 16.08.2009, 22:40 | Сообщение # 15
Подполковник
Группа: Проверенные
Сообщений: 139
Статус: Оффлайн
После небольшого затишья, еще один небольшой, но довольно интересный апдейт smile

Программные инструкции

--------------
К ним относятся переходы, прыжки и вызовы подпрограмм

Code
Bcc          Группа переходов, состоящая из 15 инструкций.
DBcc       15 инструкций циклов
BSR, JSR  Вызовы подпрограмм
RTS         Возврат после выполнения подпрограммы
JMP         Прыжок к метке

1)Переходы Bcc
Эти инструкции приводят к переходу к какой-либо части программы. Всего таких типов переходов -- 15. Некото-
рые из них я никогда не использовал, и даже не встречал. Так что те которые я не знаю как работают, просто
отмечу флаги, при которых происходит переход.

Синтаксис: Bcc.s <label>
Bcc.w <label>

Тип данных: byte, word

Начнем сразу с примера. Переходы обычно идут после сравнения двух операндов. Допустим идет сравнение:
cmp.w D0, D1
И после него сразу один из переходов:

Code
BCC  Branch if Carry Clear        - Переход, если C-flag равен 0.
BCS  Branch if Carry Set           - Переход, если C-flag равен 1.
BEQ  Branch if EQual                 - Переход, если D0 = D1
BNE  Branch if Not Equal            - Переход, если D0 не равен D1
BGE  Branch if Greater or Equal  - Переход, если D0 >= D1 тип Signed
BGT  Branch if Greater Than       - Переход, если D0 > D1 тип Signed
BHI  Branch if HIgher than         - Переход, если D0 > D1 тип UnSigned
BLE  Branch if Less or Equal       - Переход, если D0 <= D1 тип Signed
BLS  Branch if Lower or Same    - Переход, если D0 <= D1 тип UnSigned
BLT  Branch if Less Than           - Переход, если D0 < D1 тип Signed
BMI  Branch MInus                   - Переход, если N=1.
BPL  Branch PLus                     - Переход, если N=0.
BVC  Branch V Clear                - Переход, если V=0
BVS  Branch V Set                   - Переход, если V=1.
BRA  BRanch Always                - Переход происходит всегда, независимо ни от чего

Если условие перехода не соответствует тому, что произошло на самом деле, то переход не происходит
и программа идет дальше
cmp.w D0, D1
beq.s label ; пойдет к label, если D0=D1
jmp end ; если D0 не равен D1 программа не выполняет переход, просто идет дальше

2)Переход к подпрограмме BSR
Branch to SubRoutine. Эта инструкция выполняет переход к указанной подпрограмме. Записывает смещение в SP
и после выполнения подпрограммы, происходит возврат.

Синтаксис: BSR.S <label>
BSR.W <label>

Тип данных: word, longword

Пример:

Code
                .............
                    .............
                    movea.l a0,a4
                    movea.l a1,a5
                    bsr.w   sub_8238  ; переход к подпрограмме на метку sub_8238
                    movea.l a4,a0     ; программа идет дальше после того, как выполниться подпрограмма sub_8238
                    movea.l a5,a1
                    .............
                    .............

sub_8238:       sf      d3
                    move.w  (a5)+,d1  
                    b  le.s   loc_8246
                    bsr.w   sub_82E6
                    st      d3
                    rts               ;  возврат после выполнения(за возврат отвечает rts)

3)Циклы DBcc
Это инструкции-циклы, аналогия как с языками высокого уровня for i=0 to 5 do. Условия для выполнения(сс) смотри
в пункте 1 "Переходы Bcc". Также здесь имеются еще 2 условия, характерных только для цикла.
Инструкция зависит от регистра данных, при каждом попадании на DBcc при прохождении цикла, регистр данных
уменьшается на единицу и происходит переход назад к указанной в инструкции метке. Цикл будет продолжаться
до тех пор пока значение в регистре данных не будет равняться -1.

Синтаксис: DBcc Dn,<label>

Тип данных: word

Пример:

Code
                ...............
                    ...............
                    move.w   #$9, d1        ; устанавливаем число кругов цикла в регистре d1
cfg_load1:      move.w   d0, (a0)+
                    add.w    #1, d0
                    dbf      d1, cfg_load1  ; инструкция цикла. Будет возвращать к метке cfg_load1 до тех пор
                       ; пока значение в d1 не будет равно -1, то есть FFFF
                    ...............         ; если значение в d1 равно -1 программа выходит из цикла и идет дальше
                    ...............

4)Прыжок JMP
Обыкновенный прыжок к метке. Работает также как и move .l label, PC так как по сути JMP просто меняет
значение Program Counter(PC).

Синтаксис: JMP <ea>

Варианты адресования(<ea>): (An), x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s)

Тип данных: -

5)Вызов подпрограммы JSR
Jump to SubRoutine. Работает также как и JMP за исключением того, что после прыжка к подпрограмме пи выполнении
инструкции RTS произойдет возврат назад(как и в случае с BSR)

Синтаксис: JSR <ea>

Варианты адресования(<ea>): (An), x(An), x(An,xr.s), label.w, label.l, x(PC), x(PC,xr.s)

Тип данных: -

5)Возврат после подпрограммы RTS
Return from SubRoutine. Эта инструкция используется для возврата PC к месту вызова подпрограммы. Подпрограмма
должна всегда оканчиваться этой инструкцией.

Как работает: при переходе к подпрограмме(JSR или BSR) в Stack Pointer записывается смещение инструкции,
следующей точно после инструкции перехода(JSR или BSR), а в Program Counter записывается смещение самой
подпрограммы. После ее выполнения по команде RTS из Stack Pointer'a копируется смещение инструкции, которое
было записано при переходе к подпрограмме. Таким образом происходит возврат.

Это можно вовсю использовать при поиске нужной части кода в роме. Допустим вы нашли нужную подпрограмму,
но в роме вызовов на нее очень много, не проверять же каждый. Ставим брейкпоинт в дебаггере на нашу процедуру,
ждем пока сработает. Сработал, смотрим, что у нас записано в регистре а7(это и есть Stack Pointer). Пусть
там будет значение $FFFFFFFC. Это адрес в оперативной памяти, где в данный момент находится Stack Pointer.
Открываем просмотрщик памяти(все это время программа остановлена брейкпоинтом, не вздумайте снимать!), смотрим
что у нас записано в $FFFFFFFC. Записанный там адрес и будет адресом, по которому произошел вызов/переход
к подпрограмме.

Добавлено (16.08.2009, 22:40)
---------------------------------------------

Сдвиги и повороты

------------------

Code
ASL, ASR   Арифметический сдвиг влево и вправо
LSL, LSR   Логический сдвиг влево и вправо
ROL, ROR, ROXL, ROXR Повороты(пока рассмотрены не будут)

1)Арифметический сдвиг влево ASL
Проделывает арифметический сдвиг данных в регистрах или в памяти влево.
Для того, чтобы сдвинуть число в десятичной системе счисления нужно просто умножить(если сдвиг влево)
или разделить(если вправо) это число на 10. Т.к. процессор понимает только двоичную систему, то естественно
умножать или делить будем на 2 и еще на число шагов сдвига. Т.е. если нужно сдвинуть число 4 на 2 влево, нужно проделать
следующее: 4х2х2 = 16 = $10 = %10000. Итак, смотрим что получилось:
4 = %100
16 = %10000
Вот здесь наглядно виден пример сдвига влево на 2.
Вариантов этого сдвига может быть 3:
1)Сдвиг числа в регистре данных влево. Число шагов записано в другом регистре данных;
2)Сдвиг числа в регистре данных влево. Число шагов задается простым целым числом.
3)Сдвиг числа в памяти влево на один бит.

Синтаксис: ASL Dx,Dy
ASL #<data>,Dy
ASL <ea>

Варианты адресования(<ea>): 3) (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Пример:

Code
       Инструкция          До          После
       -----------------------------------------------
       |asl.w #2, D0     | D0=00000003 | D0=0000000C |
       |                       |                    |                      |
       -----------------------------------------------

2)Арифметический сдвиг вправо ASR
Проделывает арифметический сдвиг данных в регистрах или в памяти вправо. Работает также как и ASL за исключением
того, что сдвиг происходит вправо => вместо умножения проводим деление.
Вариантов этого сдвига может быть 3:
1)Сдвиг числа в регистре данных вправо. Число шагов записано в другом регистре данных;
2)Сдвиг числа в регистре данных вправо. Число шагов задается простым целым числом.
3)Сдвиг числа в памяти вправо на один бит.

Синтаксис: ASR Dx,Dy
ASR #<data>,Dy
ASR <ea>

Варианты адресования(<ea>): 3) (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Пример:

Code
       Инструкция          До          После
       -----------------------------------------------
       |asr.w #2, D0     | D0=00000010 | D0=00000004 |
       |                      |                   |                   |
       -----------------------------------------------

3)Логический сдвиг влево LSL
Проделывает логический сдвиг данных в регистрах или в памяти влево. Работает также как и ASL за исключением
того, что здесь число считается Signed(т.е $FF = -1, $FE = -2 и т.д. до $80). Итак, если мы хотим
сдвинуть число $FF = %11111111 влево на 1 шаг мы получим $FFx(2x1) = $7F = %111111111. Но если считать,
что $FF число негативное($FF = -1), то -1x2x1 = -2 = $FE = %11111110. То есть мы здесь получаем два различных результата.
Первый характерен для арифметических сдвигов, второй - для логических.
Вариантов этого сдвига может быть 3:
1)Сдвиг числа в регистре данных влево. Число шагов записано в другом регистре данных;
2)Сдвиг числа в регистре данных влево. Число шагов задается простым целым числом.
3)Сдвиг числа в памяти влево на один бит.

Синтаксис: LSL Dx,Dy
LSL #<data>,Dy
LSL <ea>

Варианты адресования(<ea>): 3) (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Code
       Инструкция          До          После
       -----------------------------------------------
       |lsl.w #2, D0     | D0=000000FF | D0=000000FC |
       |                      |                  |                   |
       -----------------------------------------------

4)Логический сдвиг вправо LSR
Проделывает логический сдвиг данных в регистрах или в памяти вправо. Работает также как и LSL, только
сдвиг проводится вправо, следовательно умножение заменяется делением.
Вариантов этого сдвига может быть 3:
1)Сдвиг числа в регистре данных вправо. Число шагов записано в другом регистре данных;
2)Сдвиг числа в регистре данных вправо. Число шагов задается простым целым числом.
3)Сдвиг числа в памяти вправо на один бит.

Синтаксис: LSR Dx,Dy
LSR #<data>,Dy
LSR <ea>

Варианты адресования(<ea>): 3) (An), (An)+, -(An), x(An), x(An,xr.s), label.w, label.l

Тип данных: Byte, word, longword

Пример:

Code
       Инструкция          До          После
       -----------------------------------------------
       |lsr.w #1, D0     | D0=000000F0 | D0=000000F8 |
       |                      |                  |                  |
       -----------------------------------------------


Сообщение отредактировал Smoke - Воскресенье, 16.08.2009, 22:35
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: