114 lines
6.8 KiB
Markdown
114 lines
6.8 KiB
Markdown
# BINCOM - справочник по командам NTSYS
|
||
Эта страница посвящена командам в NTSYS.
|
||
## Кратко
|
||
```c
|
||
void (*operations[])(void) = {
|
||
/* Операции со стеком (0 - 2) */
|
||
push, pop, push_str,
|
||
/* Арифметические операции (3 - 6) */
|
||
add, sub, mul, div_r,
|
||
/* Логические операции (7 - 12) */
|
||
nt_not, nt_shr, nt_shl, nt_or,
|
||
nt_and, nt_xor,
|
||
/* Переход (13) */
|
||
nt_goto,
|
||
/* Условия (14 - 21) */
|
||
bnez, bez,
|
||
up, down,
|
||
eq, neq,
|
||
upne, downe,
|
||
/* Работа с памятью (22 - 23) */
|
||
mwrt, mrd,
|
||
/* Адресация на стеке (24 - 25) */
|
||
get_sp, set_sp,
|
||
/* Системные вызовы (26) */
|
||
nt_fs_syscall
|
||
};
|
||
```
|
||
## Справочник
|
||
|
||
### Стек
|
||
- **PUSH 0x00** - Запись данных на стек. Формат: **0x00 РАЗМЕР ДАННЫЕ_1 ... ДАННЫЕ_N**
|
||
- **POP 0x01** - Удаление данных со стека. Формат: **0x01 РАЗМЕР**
|
||
- **PUSH_STRING 0x02** - Запись строки на стек. Формат: **0x02 СИМВОЛ_1 ... СИМВОЛ_N 0x00**
|
||
### Арифметика
|
||
> [!WARNING]
|
||
> По умолчанию все арифметические операторы работают с **UNSIGNED**.
|
||
> Для **SIGNED** нужно добавить **0xF0**. Например (**SIGNED DWORD**):
|
||
> ```c
|
||
> unsigned char Y[2] = {0x03, 0x00};
|
||
> unsigned char X = 4;
|
||
> X = X | 0xF0;
|
||
> Y[1] = X;
|
||
> fwrite(Y, 1, sizeof(Y), my_program);
|
||
> ...
|
||
> ```
|
||
- **ADD 0x03** - Сложение **ARG1 + ARG2** - сначала берётся **ARG1**. Формат: **0x03 РАЗМЕР**
|
||
- **SUB 0x04** - Вычитание **ARG1 - ARG2** - сначала берётся **ARG1**. Формат: **0x04 РАЗМЕР**
|
||
- **MUL 0x05** - Умножение **ARG1 * ARG2** - сначала берётся **ARG1**. Формат: **0x05 РАЗМЕР**
|
||
- **DIV 0x06** - Деление **ARG1 / ARG2** - сначала берётся **ARG1**. Формат: **0x06 РАЗМЕР**
|
||
### Логика
|
||
- **NOT 0x07** - Инвертирование **NOT ARG**. Формат: **0x07 РАЗМЕР**
|
||
- **SHR 0x08** - Сдвиг вправо **ARG1 >> ARG2** - сначала берётся **ARG1**. Формат: **0x08 РАЗМЕР**
|
||
- **SHL 0x09** - Сдвиг влево **ARG1 << ARG2** - сначала берётся **ARG1**. Формат: **0x09 РАЗМЕР**
|
||
- **OR 0x0A** - Или **ARG1 | ARG2** - сначала берётся **ARG1**. Формат: **0x0A РАЗМЕР**
|
||
- **AND 0x0B** - И **ARG1 & ARG2** - сначала берётся **ARG1**. Формат: **0x0B РАЗМЕР**
|
||
- **XOR 0x0C** - Исключающее ИЛИ **ARG1 & ARG2** - сначала берётся **ARG1**. Формат: **0x0C РАЗМЕР**
|
||
### Переход
|
||
- **JMP 0x0D** - Переход по аддресу. Формат: **0x0D**
|
||
### Условия
|
||
> [!WARNING]
|
||
> По умолчанию все условные операторы работают с **UNSIGNED**.
|
||
> Для **SIGNED** нужно добавить **0xF0**. Например (**SIGNED DWORD**):
|
||
> ```c
|
||
> unsigned char Y[2] = {0x0E, 0x00};
|
||
> unsigned char X = 4;
|
||
> X = X | 0xF0;
|
||
> Y[1] = X;
|
||
> fwrite(Y, 1, sizeof(Y), my_program);
|
||
> ...
|
||
> ```
|
||
|
||
> [!NOTE]
|
||
> Эти операторы сначала считывают **ARG1**, затем - **ARG2**, а потом - аддрес.
|
||
> Аддрес считывается всегда.
|
||
|
||
- **BNEZ 0x0E** - Не равно нулю **ARG != 0** - сначала берётся **ARG**. Формат: **0x0E РАЗМЕР**
|
||
- **BEZ 0x0F** - Равно нулю **ARG == 0** - сначала берётся **ARG**. Формат: **0x0F РАЗМЕР**
|
||
- **UP 0x10** - Больше **ARG1 > ARG2** - сначала берётся **ARG1**. Формат: **0x10 РАЗМЕР**
|
||
- **DOWN 0x11** - Меньше **ARG1 < ARG2** - сначала берётся **ARG1**. Формат: **0x11 РАЗМЕР**
|
||
- **EQ 0x12** - Равно **ARG1 == ARG2** - сначала берётся **ARG1**. Формат: **0x12 РАЗМЕР**
|
||
- **NEQ 0x13** - Не равно **ARG1 != ARG2** - сначала берётся **ARG1**. Формат: **0x13 РАЗМЕР**
|
||
- **UPNE 0x14** - Не больше (меньше или равно) **ARG1 <= ARG2** - сначала берётся **ARG1**. Формат: **0x14 РАЗМЕР**
|
||
- **DOWNE 0x15** - Не меньше (больше или равно) **ARG1 >= ARG2** - сначала берётся **ARG1**. Формат: **0x15 РАЗМЕР**
|
||
### Работа с памятью
|
||
> [!NOTE]
|
||
> Комманда для записи в память получает адрес в **ARG1**, а данные - в **ARG2**.
|
||
- **MWRT 0x16** - Запись **ARG1 ARG2** - сначала берётся **ARG1**. Формат: **0x16 РАЗМЕР**
|
||
- **MREAD 0x17** - Чтение **ARG**. Формат: **0x17 РАЗМЕР**
|
||
## Работа с указателем
|
||
- **GETSP 0x18** - Получить SP. Формат: **0x18**
|
||
- **SETSP 0x19** - Получить SP и записать. Формат: **0x19**
|
||
## Взаимодействие с пользователем
|
||
> [!NOTE]
|
||
> Формат следующий:
|
||
> - Вывод строки (Запись на стек строки и числа **0x00**)
|
||
> - Ввод символа (Запись на стек **0x01**)
|
||
> - Завершение со статусом (Запись на стек **WORD-статуса** и числа **0x02**)
|
||
> - Вызов BASH (Запись на стек строки и числа **0x03**)
|
||
> - Запрос к RANDOM (Запись на стек числа **0x04**)
|
||
> - Установка SEED (Запись на стек **WORD-SEED** и числа **0x05**)
|
||
- **SYSCALL 0x1A** - Выполнить вызов к ядру (**ARG**). Формат: **0x1A**
|
||
## Управление стеком
|
||
> [!NOTE]
|
||
> Как работает **SWAP**?
|
||
> Команда **SWAP** меняет местами два элемента на стеке, сдвигая другие.
|
||
> Она принимает количество элементов в качестве параметра.
|
||
> Элементы сдвигаются влево.
|
||
- **SWAP 0x1B** - Swap (**ARG1 ARG2**). Формат: **0x1B РАЗМЕР**
|
||
- **COPY 0x1C** - Скопировать последний элемент (**ARG**). Формат: **0x1C РАЗМЕР**
|
||
- **SET 0x1D** - Установить указатель виртуального стека (**ARG**). Формат: **0x1D**
|
||
- **MOV 0x1E** - Переключить стек (виртуальный/обычный). Формат: **0x1E**
|
||
## Функции
|
||
- **CALL 0x1F** - Аналогична инструкции **JMP**, но сохраняет стек вызовов (32 элемента). Формат: **0x1F**
|
||
- **RET 0x20** - Возврат из функции. Формат: **0x20** |