|
|||
7. substract_simple. 8. building_ten_degree. 9. buffer_equalizer7. substract_simple На вход принимает однострочные число-строки: в rax — из чего вычитаем, в rbx — что вычитаем, в rdx — есть ли долг по предыдущим операциям. На выходе в rax кладётся результат операции вычитания, в rdx — 0 или 1 в зависимости от наличия «долга» за текущее вычитание.
Описание работы: Вычитание «нулевого» символа для перехода к работе с числами. После чего к вычитаемому добавляем флаг заёма на предыдущем шаге. Далее происходит сравнение двух чисел, если уменьшаемое больше или равно суммы вычитаемых, то заём не нужен, вычитается как есть, в противном случае флаг заёма устанавливается в 1, к уменьшаемому добавляется 10 и происходит обычное вычитание.
; | input ; rax = first digit-string ; rbx = second digit-string ; rdx = shift ; | output ; rax = result ; rdx = new shift substract_simple: push rcx sub rax, '0' sub rbx, '0' add rbx, rdx cmp rax, rbx jge. normal jmp. borrow . normal: sub rax, rbx xor rdx, rdx jmp. close . borrow: mov rdx, 1 add rax, 10 sub rax, rbx . close: add rax, '0' pop rcx ret
8. building_ten_degree На вход принимает степень десятки. На выход кладёт в буфер first_number 10степень_десятки — 1 в виде число-строки.
Описание работы: В первый байт first_number кладётся «1». Оставшиеся байты добиваются «0», каждый раз сдвигая указатель на одну позицию вправо.
; | input ; rax = size ; | output ; first_number = 10 ** (size - 1) building_ten_degree: push rbx push rdi push rcx push r8 mov rbx, rax xor r8, r8 mov rax, '1' mov rdi, first_number mov rcx, r8 stosb dec rbx inc r8 mov rax, '0' . next_iter: cmp rbx, 0 je. close mov rcx, r8 stosb dec rbx inc r8 jmp. next_iter . close: pop r8 pop rcx pop rdi pop rbx ret
9. buffer_equalizer На вход ничего не принимает, работает с буфером computation_result. На выходе буфер computation_result выравнен слева.
Описание работы: Сначала происходит подсчёт количества «0» слева. После чего метод узнаёт полезную нагрузку буфера. Далее, происходит очистка вспомогательного буфера helper и запись полезной нагрузки computation_result в helper. Далее очищается computation_result и обратная запись в него же. После чистится helper. Метод выполнил свою задачу. При получении нуля, возвращает «0».
; | input ; computation_result ; | output ; empty buffer_equalizer: push rax push rbx push rcx push rdi push rsi mov rax, computation_result xor rbx, rbx . next_iter: cmp [rax + rbx], byte'0' jne. alignment inc rbx jmp. next_iter . alignment: call get_length_number mov rcx, rax cmp rcx, 0 je. zero_situation push rcx mov rax, helper call clean_buffer mov rdi, helper mov rsi, computation_result . shift: cmp rbx, 0 je. copy inc rsi dec rbx jmp. shift . copy: rep movsb pop rcx mov rax, computation_result call clean_buffer mov rdi, computation_result mov rsi, helper rep movsb jmp. close . zero_situation: mov rax, computation_result call clean_buffer mov rax, '0' mov rdi, computation_result mov rcx, 0 stosq . close: mov rax, helper call clean_buffer pop rsi pop rdi pop rcx pop rbx pop rax ret
|
|||
|