Files
solutions/03-asm-bios/task2.asm
Miheev Egor 49d3c02d7d feat: task2 создан
Решен второй пункт в виде ассемблерного кода, однако он отформатирован вполне определенным образом
2024-09-22 15:27:21 +03:00

82 lines
2.4 KiB
NASM
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

global _start
%define STDIN 0
%define STDOUT 1
%define STDERR 2
section .data
src db 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
src_size equ $-src
; резервируем 1 килобайт для буффера ввода и вывода
; также в отдельной переменной сохраняем размер этого буфера
print_buf: times 1024 db 0
buf_size equ $-print_buf
section .text
%macro DIGIT_TO_ASCII 1 ; макрос, принимающий один регистр
add %1, '0'
%endmacro
%macro PUSH_M 1-* ; push many; пушит в порядке следования
%rep %0
push %1
%rotate 1
%endrep
%endmacro
%macro POP_M 1-* ; pop many. читает в порядке следования
%rep %0
pop %1
%rotate 1
%endrep
%endmacro
%macro RPOP_M 1-* ; pop many. читает в обратном порядке
%rotate -1
%rep %0
pop %1
%rotate -1
%endrep
%endmacro
; Передачу аргументов будем делать при помощи ABI - стандартная практика для linux
; Аргументы передаются в следующем порядке: rdi, rsi, rdx, rcx, r8, r9. Все, что не влезло, пушится в стек
; У передачи через стек тоже есть особенности, но их мы пока касаться не будем
print_from_buf: ; word -> void
PUSH_M rax, rsi, rdx, rdi ; сохраним регистры, которые точно попортим
mov rdx, rdi ; сколько выводить, в rdi содержится единственный аргумент
mov rsi, print_buf ; откуда выводить. Адрес буфера
mov rdi, STDOUT; куда выводить. Дескриптор файла. В нашем случае стандартного вывода
mov rax, 1
syscall
RPOP_M rax, rsi, rdx, rdi ; вернем значения регистров
ret
_start:
mov rcx, src_size
mov rsi, src
mov rdi, print_buf
xor rax, rax ; обнуляем регистр
.transfer: ; в цикле передаем данные, попутно конвертируя их в ascii
lodsb
DIGIT_TO_ASCII rax
stosb
loop .transfer
mov [rdi + 1], BYTE `\n` ; Чтобы система не ругалась на отсутствие переноса
mov rdi, src_size
call print_from_buf
exit:
mov rax, 60
mov rdi, 0
syscall