ntsys/EXAMPLES.md
2026-03-20 15:01:44 +04:00

8.6 KiB
Raw Blame History

Примеры на ассемблере NTSYS

Это небольшой набор примеров для ассемблера NTSYS. Для их компиляции используйте:

ntsys --asm имя_файла.asm --out имя_файла.exe --mem 128

Hello, world!

main:                                   ; Метка main
    push.string "Hello, world!\n"       ; Записываем строку
    push byte, 0x00                     ; Запись номера SYSCALL
    syscall                             ; Системный вызов

Выводим имя пользователя

main:                                             ; Метка main
    push.string "echo Ваше имя: $USER\n"          ; Запрос к системе
    push byte, 0x03                               ; Код
    syscall                                       ; Вызов

Пример программной задержки

main:                                             ; Метка main
    push.string "This is example of wait!\n"      ; Строка
    push byte, 0x00                               ; Номер
    syscall                                       ; Системный вызов

mload:                                            ; Функция mload
    push word, 0x00                               ; Данные для записи
    push word, 0x00                               ; Адрес в VRAM
    mwrt word                                     ; Комманда записи

lwait:                                            ; Цикл задержки
    push db, lwait                                ; Его адрес
    push word, 0x01                               ; Увеличивать счетчик на 1
    push word, 0x00                               ; Счетчик по адресу 0x00
    mread word                                    ; Читаем
    add word                                      ; Складываем
    push word, 0x00                               ; Адрес для записи
    mwrt word                                     ; Записываем обратно
    push word, 0x00                               ; Адрес
    mread word                                    ; Читаем
    push word, 0xFFFF                             ; Значение для сравнения
    neq word                                      ; Если не равно - повторить цикл

mloop:                                            ; Главный цикл              
    push db, main                                 ; Адрес main
    jmp                                           ; Повторяем цикл

Пример инструкции SWAP

main:                                 ; Метка main
    push.string "Hello, world!\n"     ; Строка
    push byte 0x00                    ; Дескриптор
    syscall                           ; Системный вызов
    push.string "Hello, world!\n"     ; Строка
    push byte 3                       ; Кол-во блоков
    swap word                         ; Блок размером в 2 байта
    push byte 0x00                    ; Дескриптор
    syscall                           ; Системный вызов

Запрос ввода у пользователя

global db main                             ; Точка входа

readmem:                                   ; Функция чтения из памяти
    push dw 0x00                           ; Адрес
    mread dw                               ; Читаем
    ret                                    ; Конец функции

insub:                                     ; Уменьшение адреса
    push dw 1                              ; На сколько уменьшать
    push byte 2                            ; Поменять два места
    swap dw                                ; Тип данных - size_t
    sub dw                                 ; Уменьшить
    ret                                    ; Конец функции

writemem:                                  ; Функция записи в память
    push dw 0x00                           ; Адрес
    mwrt dw                                ; Записываем
    ret                                    ; Конец функции

decrement:                                 ; Управление данными
    rcall db readmem                       ; Прочитать
    rcall db insub                         ; Уменьшить
    rcall db writemem                      ; Записать
    ret                                    ; Конец функции

main:                                      ; Точка входа
    push.string "Введите ваше имя: "       ; Строка
    push byte 0x00                         ; Дескриптор
    syscall                                ; Выводим

begin:                                     ; Настройка адресов
    push dw 0x02                           ; Указатель
    push dw 0x00                           ; Адрес
    mwrt dw                                ; Записываем

inloop:                                    ; Цикл чтения символов
    push byte 0x01                         ; Дескриптор
    syscall                                ; Читаем
    copy byte                              ; Копируем char

    push dw 0x00                           ; Адрес
    mread dw                               ; Читаем

    mwrt byte                              ; Записываем

    push dw 0x00                           ; Читаем
    mread dw                               ; Указатель

    push dw 0x01                           ; Увеличить
    add dw                                 ; На 1

    push dw 0x00                           ; Адрес
    mwrt word                              ; Сохраняем указатель

    push byte 0x0A                         ; Символ переноса
    push db inloop                         ; Цикл
    push byte 2                            ; Кол-во слов
    swap word                              ; Меняем их местами
    neq byte                               ; Если не \n - повторить цикл
 
userhello:                                 ; Приветствие
    push.string "Привет, "                 ; Текст
    push byte 0x00                         ; Дескриптор
    syscall                                ; Выводим
    rcall db decrement                     ; Уменьшаем
    push byte 0x00                         ; Символ конца строки

readcycle:                                 ; Цикл чтения
    push db writeusername                  ; Конец цикла
    push dw 0x00                           ; Адрес
    mread dw                               ; Указатель
    push dw 0x01                           ; Число 
    eq dw                                  ; Если равно - выйти

    push db rdecrem                        ; Адрес

    push dw 0x00                           ; Иначе
    mread dw                               ; Читаем указатель
    mread byte                             ; Читаем байт по указателю

    push byte 0x0A                         ; Если символ переноса
    eq byte                                ; Пропускаем добавление на стек

    push dw 0x00                           ; Иначе
    mread dw                               ; Читаем указатель
    mread byte                             ; Читаем байт по указателю

rdecrem:                                   ; Уменьшение указателя
    rcall db decrement                     ; Уменьшаем
    push db readcycle                      ; Указатель на цикл
    jmp                                    ; Повторить цикл

writeusername:                             ; Выводим имя
    push byte 0x00                         ; Дескриптор
    syscall                                ; Выводим
    push.string "!\n"                      ; Выводим !
    push byte 0x00                         ; Дескриптор
    syscall                                ; Выводим