Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ovcharik/pdp11-asm
pdp11-asm
https://github.com/ovcharik/pdp11-asm
Last synced: 7 days ago
JSON representation
pdp11-asm
- Host: GitHub
- URL: https://github.com/ovcharik/pdp11-asm
- Owner: ovcharik
- License: unlicense
- Created: 2013-12-15T21:41:34.000Z (almost 11 years ago)
- Default Branch: master
- Last Pushed: 2021-06-25T11:38:43.000Z (over 3 years ago)
- Last Synced: 2023-07-08T22:10:25.246Z (over 1 year ago)
- Language: C++
- Size: 2.98 MB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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
* Константы