как в ассамблерном языке NASM можно написать как можно более быстрый остаток от деления, когда деление округляет в ближайшую сторону?
Вот пример кода на NASM:
section .text
global _start
_start:
; золотое сечение
mov rbp, rsp
push qword -1836311903 ; [rbp-8]
push qword -1134903170 ; [rbp-16]
; алгоритм Евклида
; <БЕНЧМАРК>
rdtsc
push rax ; [rbp-24]
; {
; rdx — числ. & rcx — знам.
mov rdx, [rbp-8]
cmp rdx, 0
jns _1
neg rdx
_1:
mov rcx, [rbp-16]
cmp rcx, 0
jns _2andeuclid_loop
neg rcx
; сам алгоритм Евклида
_2andeuclid_loop:
cmp rcx, 0
jz _euclid_loop_end
mov rax, rdx
xor rdx, rdx
div rcx
; место, которым отличаются 2 варианта алгоритма.
; либо остаток от деления, округляющего вниз,
; либо остаток от деления, округляющего к ближайшему:
;
; mov rbx, rdx ; rbx — temp
; shl rbx, 1
; cmp rbx, rcx
; js _3
; sub rdx, rcx
; neg rdx
; _3:
xor rdx, rcx
xor rcx, rdx
xor rdx, rcx
jmp _2andeuclid_loop
_euclid_loop_end:
push rdx ; НОД: [rbp-32]
; }
rdtsc
sub rax, [rbp-24]
mov qword [rbp-24], rax
; </БЕНЧМАРК>
mov rax, 60 ; syscall: exit
xor rdi, rdi ; exit code 0
syscall
(см закомментированную часть кода, которым отличаются два алгоритма) — можно ли этот код как-то поправить, чтобы ускорить выполнение этой программы? Или этот код уже является реально самым быстрым для решения алгоритмом Эвклида? Акцент делается на взятии остатка, мы же измеряем скорость для этого остатка.