labs/03 #3
@ -79,7 +79,9 @@ print_from_buf: ; qword -> void; пытается вывести данные и
|
||||
mov rsi, print_buf ; откуда выводить. Адрес буфера
|
||||
mov rdi, STDOUT; куда выводить. Дескриптор файла. В нашем случае стандартного вывода
|
||||
mov rax, 1
|
||||
push rcx
|
||||
syscall
|
||||
pop rcx
|
||||
RPOP_M rax, rsi, rdx, rdi ; вернем значения регистров
|
||||
ret
|
||||
|
||||
@ -114,26 +116,33 @@ print_number: ; qword (rdi) -> void
|
||||
; создаем базу для адресации. Тогда первая будет на rbp - 8 - делитель, а вторая на rbp - 16 - количество
|
||||
mov rbp, rsp
|
||||
; [WARNING] тут надо будет сохранить регистры
|
||||
sub rsp, 16 ; выделяем место под 2 переменные
|
||||
mov qword [rbp - 8], 10 ; пусть и жирно, но операнд обязан быть 64 разрядным для корректного деления
|
||||
mov qword [rbp - 16], 0 ; счетчик
|
||||
push rsp ; сохраню, потому что после всей вакханалии я концов не сыщу
|
||||
sub rsp, 16 ; выделяем место под 3 переменные
|
||||
mov qword [rbp - 16], 10 ; пусть и жирно, но операнд обязан быть 64 разрядным для корректного деления
|
||||
mov qword [rbp - 24], 0 ; счетчик
|
||||
mov rax, rdi
|
||||
push byte 0 ; при выводе он ориентируется на это как на конец строки
|
||||
.division_loop:
|
||||
xor rdx, rdx ; обнулим найденый остаток. (он просто еще и при делении принимает участие)
|
||||
div qword [rbp - 8]
|
||||
div qword [rbp - 16]
|
||||
DIGIT_TO_ASCII dl
|
||||
PUSHR8 dl ; поскольку в процессор не завезли возможность закинуть в стек 8 битный регистр, я им немного помог макросами
|
||||
inc qword [rbp - 16] ; увеличиваем счетчик на единицу
|
||||
inc qword [rbp - 24] ; увеличиваем счетчик на единицу
|
||||
test rax, rax ; делает and поразрядное с самим собой. Меня интересует, лежит ли в rax ноль
|
||||
jnz .division_loop ; если в rax не ноль, то продолжаем цикл
|
||||
; выводим число
|
||||
mov rax, 1
|
||||
mov rdi, STDOUT
|
||||
mov rsi, rsp
|
||||
mov rdx, [rbp-16]
|
||||
add rsp, 16 ; освобождаем память
|
||||
mov rdx, [rbp-24] ; уже не надо очищать, потому что в конце я просто восстановлю как было
|
||||
push rcx
|
||||
syscall
|
||||
pop rcx
|
||||
|
||||
mov rsp, [rbp - 8]
|
||||
RPOP_M rdx, rdi, rsi
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
_start:
|
||||
mov rbp, rsp
|
||||
@ -156,6 +165,7 @@ _start:
|
||||
dec rcx
|
||||
mov rax, [rbp - 8]
|
||||
stosq
|
||||
xor rax, rax
|
||||
inc word [rbp - 18]
|
||||
mov qword [rbp - 8], 0
|
||||
test rcx, rcx
|
||||
@ -171,25 +181,26 @@ _start:
|
||||
|
||||
ASCII_TO_DIGIT al ; Если цифра, то конвертируем ее из ascii
|
||||
; Поскольку умножение и деление можно сделать только через регистр, придется извратиться
|
||||
PUSH_M ax, rdx
|
||||
PUSH_M rax, rdx
|
||||
mov rax, [rbp - 8]
|
||||
mov qword [rbp - 16], 10
|
||||
mul qword [rbp - 16]
|
||||
mov [rbp - 8], rax
|
||||
RPOP_M ax, rdx
|
||||
RPOP_M rax, rdx
|
||||
add [rbp - 8], rax ; результат деления запишем в локальную переменную
|
||||
loop .read_byte ; читаем буфер ввода до конца
|
||||
|
||||
.check_buf:
|
||||
call poll_stdin
|
||||
test BYTE [revents], POLLIN
|
||||
test dword [revents], POLLIN
|
||||
jnz .read_loop
|
||||
|
||||
; Теперь выведем прочитанный массив на экран
|
||||
xor rcx, rcx
|
||||
mov cx, [rbp - 18]
|
||||
.output_loop:
|
||||
mov rsi, array
|
||||
call clean_print_buf
|
||||
.output_loop:
|
||||
lodsq
|
||||
mov rdi, rax
|
||||
call print_number
|
||||
|
||||
Reference in New Issue
Block a user