diff --git a/03-asm-bios/task4.asm b/03-asm-bios/task4.asm index ed69cae..37d281d 100644 --- a/03-asm-bios/task4.asm +++ b/03-asm-bios/task4.asm @@ -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