Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ovcharik/pdp11-asm

pdp11-asm
https://github.com/ovcharik/pdp11-asm

Last synced: 7 days ago
JSON representation

pdp11-asm

Awesome Lists containing this project

README

        

# pdp11-asm

Ассемблер для архитектуры pdp-11.

# Система команд

## Метки

Задаются вначале строки, и могут содержать только `_A-Z0-9`, заканчиваеться метка должна `:`, и метка не может начинаться с цифры.

## Регистры

Существует 8 регистров и 7 из них общего назначения. Обозначаются как `R0` - `R7`, `R7` - счетчик комманд, который изменяется после выполнения каждой команды автоматически.

Существует так же 8 режимов обращения к регистрам:

0) `Rn` - непосредственное обращение к содержимому регистру

1) `@(Rn)` - прямая адресация (по адресу в регистре)

2) `(Rn)+` - косвено-регистровая адресация 2-го уровня, с автоикрементом содержимого регистра

3) `@(Rn)+` - косвено-регистровая адресация 3-го уровня, с автоикрементом содержимого регистра

4) `-(Rn)` - косвено-регистровая адресация 2-го уровня, с автодекрементом содержимого регистра

5) `@-(Rn)` - косвено-регистровая адресация 3-го уровня, с автодекрементом содержимого регистра

6) `X(Rn)` - индексная адресация, итоговый адрес получается как сумма индекса (`X`) и содержимого регистра

7) `@X(Rn)` - косвенно-индексная адресация, адрес получается как сумма индекса (`X`) и содержимого регистра

## Операнды

### Регистры

Регистры в командах описываются так же, как представленно выше.

### Значения

Непосредственно значение можно просто записать на месте операнда, при записи значения допускается использование различных систем счисления

`0\d+` - восьмеричная

`(-)\d+` - десятичная

`0x\d+` - шеснадцатиричная

При записи значения в скобках, оно будет восприниматься как адрес (используется 3 режим для регистра `R7`)

### Метки

Также на месте операнда можно указать метку, при сборке, вместо метки подставится ее адрес.

Пока есть возможность использования только адресов меток.

## Команды

В некоторых командах содержатся модификаторы размера: `W` - операция над словом, `B` - операция над байтом.

### Одноадресные

` `

`CLRW`, `CLRB` - обнуление операнда

`INCW`, `INCB` - инкрементация

`DECW`, `DECB` - декриментация

`COMW`, `COMB` - инверсия

`TSTW`, `TSTB` - проверка

`NEGW`, `NEGB` - отрицание

`ASRW`, `ASRB` - арифметический сдвиг вправо

`ASLW`, `ASLB` - арифметический сдвиг влево

`RORW`, `RORB` - циклический сдвиг вправо

`ROLW`, `ROLB` - циклический сдвиг влево

`ADCW`, `ADCB` - добавления флага переноса `C` к операнду

`SBCW`, `SBCW` - вычитание флага переноса `C` к операнду

`SWAB` - перестановка байтов

`SXT` - знаковое преобразование из 16-разрядного числа в 32-х

### Двухадресные

` , `

`MOVW`, `MOVB` - пересылка значения

`CMPW`, `CMPB` - сравнение

`BITW`, `BITB` - проверка разрядов

`BICW`, `BICB` - отчистка разрядов

`BISW`, `BISB` - установка разрядов

`ADDW`, `ADDB` - сложение, результат заносится в приемник

`SUBW`, `SUBB` - вычитание, значение приемника минус значение источника, результат заносится в приемник

### Дополнительные арифметические

` , `

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

`MUL` - умножение, результат заносится в два регистра, в `Rn`.`R(n+1)`, `Rn` - регистр указанный в качестве приемника. Если `n` нечетное, запоминается только младшие 16 разрядов резултата

`DIV` - деление, `Rn`.`R(n+1)` / `(dest)`, в `Rn` - заносится частное, в `R(n+1)` - остаток. `n` должно быть четным.

`ASH` - сдвиг содержимного регистра приемника, на заданное количество разрядов. Учитываются при сдвиге только младшие шесть разрядов и рассматриваются они как число в дополнительном коде, в зависимости от знака числа выбирается направление сдвига.

`ASHC` - аналогично `ASH` только сдвигается двойное слово: `Rn`.`R(n+1)`

`XOR` - исключающее или

### Операции над числами с плавающей точкой

` `

Регистр в данном случае должен ссылаться на память, где лежат операнды:

`X` - `(register)`

`Y` - `(register + 4)`

Вещественное число представляется двумя словами, в формате числа с одинарной точностью (http://en.wikipedia.org/wiki/Single_precision_floating-point_format).

Порядок операндов: `X := X (op) Y`

Команды: `FADD`, `FSUB`, `FMUL`, `FDIV`

### Команды переходов

` `

Адрес перехода вычисляется следующим образом: `addr = R7 + (diff * 2)`. `diff` - имеет разрядность одного байта. Таким образом можно осуществить максимальный относительный переход на 200 слов-команд.

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

`BR` - безуслоный

`BNE` - по ненулю

`BEQ` - по нулю

`BPL` - по плюсу

`BMI` - по минусу

`BVC` - по отсутствию переполнения

`BVS` - по переполнению

`BCC` - по отсутствию переноса

`BCS` - по переносу

`BGE` - по "не меньше нуля"

`BLT` - по "меньше нуля"

`BGT` - по "больше нуля"

`BLE` - по "не больше нуля"

`BHI` - беззнаковый по "больше нуля"

`BLOS` - беззнаковый по "не больше нуля"

### Остальные

`JMP` - абсолютный безусловный переход, адресом для перехода является значение операнда. `JMP `.

`JSR` - переход к подпрограмме. `JSR , `. Сначала увеличивается содержимое регистра стека (`R6`) на два, после чего значение регистра `reg` сохраняется в стекке (по адресу `R6-2`), далее в регистр `reg` заносится текущее значение `R7`, и в `R7` заносится значение операнда

`RST` - возврат из подпрограммы. `RST `. `R7` присваивается значение регистра `reg`, а регистру `reg` значение из стека `(R6)`.

`MARK` - возврат из подпрограммы с отчисткой стека. `MARK `. Значение регистра стека увеличивается на `2 * N`, после чего осуществляется переход по адресу из стека. (?) В методичке по которой написан компилятор криво описана эта команда, и в эмуляторе она не реализована, так что я не уверен что все так происходит.

`SOB` - переход по счетчику. `SOB `. `diff` состоит из 6 разрядов, и в нем содержется беззнаковое число, означающее количество слов, на которое будет совершен переход назад. `counter reg` регситр счетчик, при выполнения данной команды, содержимое регистра декриментируется, и если оно не равно нулю осуществляется переход на адрес для перехода. Адрес для перехода, высчитывается как `addr = R7 - (diff * 2)`. При использовании меток адрес высчитывается автоматически, если полученное значение выходит за рамки 6 разрядов, выдается ошибка на этапе компиляции.

`EMP `, `TRAP `, `IOT`, `BPT` - команды прерываний*

Следующие команды не используют дополнительных параметров

`RTI`, `RTT` - возврат из прерывания*

`RESET` - сброс*

`WAIT` - ожидание прерывания*

`*` - реализованы, но из-за недостаточной документации не знаю что они делают

`HALT` - остановка выполнения

`CLC`, `CLV`, `CLZ`, `CLN` - команды сброса соответсвующий флагов

`SEC`, `SEV`, `SEZ`, `SEN` - команды установки соответсвующий флагов

`CLALL`, `SEALL` - сброс, установка всех флагов

`NOP` - просто `nop`

## Секции

`.SECTION (.CODE|.DATA|.STACK)`

Программа должна содержать минимум одну секцию с кодом.

### .CODE

Данная секция также должна содержать объявление глобальной функции (пока не используется, выполнение начинается с первой команды): `.GLOBAL LABEL_NAME`.

И в данной секции могут находиться только метки и команды.

### .DATA

`: [, ]`

`label` - используется для задания имени переменной

`type` - допускаются к использованию следующие типы:

* `.STRING` - значение (`value`) должно содержаться в скобках, при адресации, сразу после строки подставляется нулевой байт
* `.SPACE` - используется совместно с `fill`, этот параметр указывает каким значение будет заполнены выделенная область
* `.BYTE`, `.WORD`, `.FLOAT` - целые и вещественные данные, `.FLOAT` - 4 байта

### .STACK

Нереализовано

## Дополнительная информация

Регистр букв не имеет значения.

Комментарии начинаюся с `#` в начале строки.

# Hello, World!

# acd address: 0177566
# acd check address: 0177564

.SECTION .DATA
HELLO_STR: .STRING "HELLO, WORLD!"


.SECTION .CODE
.GLOBAL MAIN

MAIN:
MOVW HELLO_STR, R0
MOVW 13, R1
LOOP:
TSTB @(R0)
BEQ END_LOOP

MOVB (R0)+, (0177566)
ADC_LOOP:
BITW 0200, (0177564)
BEQ ADC_LOOP

SOB R1, LOOP
END_LOOP:
HALT

# TO-DO

* Константы