Как мне запрограммировать наибольшую распространенную программу делителей 80х86?
Я знаю, что существуют разные методы поиска gcd из двух чисел, но я хочу знать, какие из команд лучше всего заданы на ассемблере, и как мне внедрить этот метод в программу?
Вот что у меня так далеко:
.586
.MODEL FLAT
INCLUDE io.h ; header file for input/output
.STACK 4096
.DATA
number1 DWORD ?
number2 DWORD ?
prompt1 BYTE "Please enter an integer for X", 0
prompt2 BYTE "Please enter an integer for Y", 0
string BYTE 40 DUP (?)
resultLbl BYTE "The greatest common divisor of X and Y is", 0
gcd BYTE 11 DUP (?), 0
.CODE
_MainProc PROC
input prompt1, string, 40
atod string
mov number1, eax
input prompt2, string, 40
atod string
mov number2, edx
mov eax, number1
mov edx, number2
Get_GCD:
xchg eax,edx
cmp eax,edx
jb Get_GCD
sub eax,edx
test edx,edx
jnz Get_GCD
ret
dtoa gcd, edx
output resultLbl, gcd
mov eax, 0
mov edx, 0
ret
_MainProc ENDP
END ; end of source code
Я запускаю его, и ничего не происходит.
3 ответа
Удалите ret, который находится после jnz Get_GCD и перед dtoa. Цикл алгоритма вычитания Евклида может быть сокращен:
; ;eax and edx are the numbers
gcd0: cmp edx,eax ;edx = smaller number
jb gcd1
xchg eax,edx
gcd1: sub eax,edx ;subtract smaller from larger
jnz gcd0 ;loop if not done
; ;edx = gcd
Обратите внимание, что наихудшим случаем для вышеуказанного цикла является eax = 0xffffffff и edx = 1, где для завершения требуется 4 миллиарда циклов. Алгоритм по модулю Евклида, показанный ниже, использует деление, но в наихудшем случае число циклов n равно: n <= 5 log10 (меньшее число) или n <= 1.50515 log2 (меньшее число). Для 32-разрядных целых чисел без знака наихудший случай - это два числа Фибоначчи, 1836311903 и 2971215073 (gcd = 1), где число циклов = 45, что составляет <= 5 log10(1836311903) (~= 46.32).
Метод Евклида по модулю:
; ;eax and ebx are the numbers
cmp ebx,eax ;ebx = smaller number
jb gcd0
xchg eax,ebx
gcd0: xor edx,edx ;divide: larger / smaller
div ebx
mov eax,ebx ;eax = new larger (was smaller)
mov ebx,edx ;ebx = new smaller (new remainder)
or ebx,ebx ;loop if new smaller != 0
jnz gcd0
; ;eax = gcd
include Irvine32.inc
.data
factor DWORD 60
i DWORD 2
largest DWORD ?
str1 BYTE "Greatest common factor",0
.code
main PROC
top:
mov eax,factor
mov ebx,i
xor edx,edx
div ebx
call writedec
cmp ebx,eax
je L2
call crlf
cmp eax,factor
jb L1
inc i
jmp top
L1:
mov largest,ebx
L2:
mov eax,largest
mov edx,OFFSET str1
call writestring
call writedec
exit
main ENDP
END main
Get_GCD:
xchg EAX,EDX
cmp EAX,EDX
jb Get_GCD
sub EAX,EDX
test EDX,EDX
jnz Get_GCD
ret