|
|||
5. clean_buffer. 6. add_string5. clean_buffer Принимает на вход в rax указатель на буфер, после чего обнуляет первые 32 байта.
; | input ; rax = pointer on buffer ; | output ; empty clean_buffer: push rbx mov rbx, 0 . next_iter: cmp rbx, 32 je. close mov [rax + rbx], byte0 inc rbx jmp. next_iter . close: pop rbx
6. add_string В качестве входных данных использует данные, которые лежат на конкретный момент времени в буфере first_number и second_number. На выход кладёт сумму чисел-строк, лежащих в first_number и second_number в буфер comutation_result.
Описание работы: В регистрах r10 и r11 кладётся длина чисел-строк first_number и second_number соответственно. Далее, эти регистры используются как указатели на конкретный байт в буфере. Регистр r12 используется как счётчик, на каждой итерации цикла compute он увеличивается. Используется для определения длины получаемой числа-строки. Регистры rax, rbx, rdx используются в качестве входных данных для вспомогательного метода add_simple, где rax отвечает за первый r12-й символ в число-строке first_number, rbx — за r12-й символ в число-строке second_number, а rdx — за флаг переноса. Если длина число-строки меньше, чем текущая итерация, то в отвечающий за эту строку регистр устанавливается константа «0». Цикл прекращает своё выполнение, если в результате очередного сложения, 0 в rdx и самое большое из слагаемых уже «закончилось». В противном случае, при помощи методов rep movsb происходит «аккумулирование» результата: сначала происходит сохранение предыдущего результата, путём сохранения его во вспомогательный буфер, потом в накопительный буфер переносится значение из rax — результат суммирования, после чего из вспомогательного буфера происходит возвращение результата, с учётом сдвига.
; | input ; first_number ; second_number ; | output ; computation_result add_string: push rax push rbx push rcx push rdx push r10 push r11 push r12 push rdi xor r10, r10 xor r11, r11 xor rbx, rbx mov rax, first_number call get_length_number mov r10, rax dec r10 mov rax, second_number call get_length_number mov r11, rax dec r11 xor rdi, rdi mov rdi, r10 cmp r10, r11 jge. next mov rdi, r11 . next: inc rdi xor rdx, rdx xor r12, r12 . compute: inc r12 . first_equal: cmp r10, 0xffffffffffffffff jne. first_char mov rax, '0' jmp. second_equal . first_char: push rbx mov rbx, first_number mov al, byte [rbx + r10] pop rbx dec r10 jmp. second_equal . second_equal: cmp r11, 0xffffffffffffffff jne. second_char mov rbx, '0' jmp. recieve_result . second_char: push rax mov rax, second_number mov bl, byte [rax + r11] pop rax dec r11 jmp. recieve_result . recieve_result: call add_simple . to_next_iteration: . save_old: push rsi push rdi mov rcx, r12 mov rdi, condensator mov rsi, computation_result rep movsb pop rdi pop rsi . move_new: push rsi push rdi mov rdi, helper stosq mov rcx, 1 mov rdi, computation_result mov rsi, helper rep movsb pop rdi pop rsi . compilation: push rsi push rdi mov rcx, r12 mov rdi, computation_result inc rdi mov rsi, condensator rep movsb pop rdi pop rsi cmp r12, rdi jge. end_addinng jmp. compute . end_addinng: cmp rdx, 0 je. close jmp. compute . close: mov rax, condensator call clean_buffer mov rax, helper call clean_buffer pop rdi pop r12 pop r11 pop r10 pop rdx pop rcx pop rbx pop rax ret
|
|||
|