Разделить 128 битное число на 5 - Assembler

Узнай цену своей работы

Формулировка задачи:

Я решил данную задачу так
_TEXT   SEGMENT
d0$ = 8;  положение в стеке частного от младшей 64bit части
r0$ = 16; положение в стеке остатка от младшей 64bit части
d1$ = 24; положение в стеке частного от старшей 64bit части
r1$ = 32; положение в стеке остатка от старшей 64bit части
?Div5@Integer128@@QEAAHXZ PROC              ;__int32 Integer128::Div5()
    mov rax, QWORD  PTR [rcx]
    xor rdx, rdx
    mov rbx,5
    div rbx; частное в rax, остаток в rdx
    mov QWORD PTR d0$[rsp], rax
    mov QWORD PTR r0$[rsp], rdx
    mov rax, QWORD  PTR [rcx+8]
    xor rdx, rdx
    div rbx; частное в rax, остаток в rdx
    mov QWORD PTR d1$[rsp], rax
    mov QWORD PTR r1$[rsp], rdx
    mov rax, 3333333333333333h
    mul rdx ; до умножения rdx = r1$ результат в rax, rdx=0
    mov rbx, rax
    inc rbx ; rbx = 0x3333333333333333*r1$+1
    mov rdx, QWORD PTR r0$[rsp]; rdx = r0$
    mov r8, QWORD PTR r1$[rsp]; r8 = r1$
    add rdx, r8; rdx = r0$+r1$
    mov r8, rdx; r8 = r0$+r1$
    sub r8, 5; r8 = r0$+r1$-5
    cmp rdx,5
    cmovae rax, rbx; if (r1$+r2$<5) rax = 0x3333333333333333*r1$ else rax = 0x3333333333333333*r1$+1
    cmovae rdx, r8; if (r1$+r2$<5) rdx = r1$+r2$ else r1$+r2$-5
    mov rbx, QWORD PTR d0$[rsp]; rbx = d0$
    mov r8, QWORD PTR d1$[rsp]; r8 = d1$
    add rax, rbx; rax = младшая часть частного
    adc r8, 0; r8 = старшая часть частного
    mov QWORD  PTR [rcx], rax
    mov QWORD  PTR [rcx+8], r8
    mov rax, rdx
    ret
?Div5@Integer128@@QEAAHXZ ENDP              ;__int32 Integer128::Div5()
_TEXT   ENDS
Кто-то предложит лучше? число находится в памяти по указателю rcx в классическом обратном порядке, младший байт rcx[15] старший rcx[0]

Решение задачи: «Разделить 128 битное число на 5»

textual
Листинг программы
_TEXT   SEGMENT
?Div5@Integer128@@QEAAHXZ PROC              ;__int32 Integer128::Div5()
    mov rax, QWORD  PTR [rcx]
    mov r10, QWORD  PTR [rcx+8]
    mov r8, rax; делимое в r8
    mov r9, 0CCCCCCCCCCCCCCCDh
    mul r9
    shr rdx, 2; частное в rdx
    mov r11, rdx; частное в r11
    mov rax, rdx
    mov rdx, 5
    mul rdx; rax = d0*5
    sub r8, rax; остаток от деления в r8
    mov rax, r10; старшее делимое в rax
    mul r9
    shr rdx, 2; частное в rdx; частное в rdx
    mov r9, rdx; частное в r9
    mov rax, rdx
    mov rdx, 5
    mul rdx; rax = d1*5
    sub r10, rax; остаток в r10
    ; r11 = d0 r8 = r0 r9 = d1 r10 = r1
    add r8, r10; r8 = r0+r1
    mov rdx, r8
    sub rdx,5; rdx = r0+r1-5
    cmp r8d, 5
    cmovae r8, rdx
    ;if(r0+r1<5) r8 = r0+r1 else r8 = r0+r1-5
    ;if(r8-r10>=0) -> r0+r1<5 else r0+r1>=5
    mov rax, 3333333333333333h
    mul r10
    mov rdx, rax
    inc rdx
    cmp r8, r10
    cmovl rax, rdx
    ;if (r1+r0<5) rax = 0x3333333333333333*r1 else rax = 0x3333333333333333*r1+1
    add rax, r11; rax = младшая часть частного
    adc r9, 0; r9 = старшая часть частного
    mov QWORD  PTR [rcx], rax
    mov QWORD  PTR [rcx+8], r9
    mov rax, r8
    ret
?Div5@Integer128@@QEAAHXZ ENDP              ;__int32 Integer128::Div5()
_TEXT   ENDS

Объяснение кода листинга программы

Список элементов:

  1. [rcx] - это адрес делимого числа, в сегменте данных
  2. [rcx+8] - это адрес старшего полубайта делимого числа, в сегменте данных
  3. r8 - это делимое число, в регистре
  4. r9 - это мультектор, в регистре
  5. rdx - это частное числа, в регистре
  6. r10 - это старший делитель, в регистре
  7. r11 - это младший делитель, в регистре
  8. rax - это результат операций, в регистре
  9. QWORD PTR [rcx] - это младшая часть частного числа, в сегменте данных
  10. QWORD PTR [rcx+8] - это старшая часть частного числа, в сегменте данных
  11. r8 - это остаток от деления, в регистре
  12. r10 - это остаток от деления, в регистре
  13. rdx - это мультектор, в регистре
  14. r9 - это мультектор, в регистре
  15. rax - это результат операций, в регистре
  16. rdx - это мультектор, в регистре
  17. r8 - это остаток от деления, в регистре
  18. r10 - это остаток от деления, в регистре
  19. rdx - это мультектор, в регистре
  20. r9 - это мультектор, в регистре

Оцени полезность:

6   голосов , оценка 3.5 из 5
Похожие ответы