#assembly #recursion #masm #greatest-common-divisor #irvine32
#сборка #рекурсия #masm #наибольший общий делитель #irvine32
Вопрос:
Спасибо всем за помощь, я внес некоторые действительно хорошие изменения, но теперь он дает мне ответ 4198498 вместо 5 для первого набора значений, который, как я знаю, неверен. Я что-то не так нажал или неправильно ввел reg? Я правильно очистил стек, используя ret 8, который должен очистить стек для следующего вызова, верно?
Вот что у меня есть до сих пор:
TITLE MASM GCD (GCD.asm)
; Description:GCD recursive
;
; Revision date:
INCLUDE Irvine32.inc
.data
myMessage BYTE "Assignment 7 GCD Recursive style",0dh,0ah,0
myMess2 BYTE "GCD = " ,0dh,0ah,0
;first set of nums
val1 DWORD 5
val2 DWORD 20
;second set of nums
val3 DWORD 24
val4 DWORD 18
;3rd set
val5 DWORD 11
val6 DWORD 7
;4th set
val7 DWORD 432
val8 DWORD 226
;5th set
val9 DWORD 26
val10 DWORD 13
.code
main PROC
call Clrscr
mov edx,offset myMessage
call WriteString ;write message
call Crlf ;new line
push val1
push val2
call GCD
exit
main ENDP
;------------------------------------------------
GCD PROC,
; This finds GCD
; Gets values from stored values
;returns NA
;------------------------------------------------
xor edx,edx
mov eax,dword ptr[esp 8] ;dividend
mov ebx,dword ptr[esp 4] ;divisor
div ebx ;eax/ebx
cmp edx,0 ;remainder in edx
je L1 ;yes: quit
call GCD ;no: call GCD agian
L1:
mov eax,ebx ;move the divisor into eax for printing i.e GCD
mov edx,offset myMess2
call WriteString
call WriteInt ;Display GCD WriteInt uses EAX = qutent
call crlf
ret 8 ;clean up the stack
GCD ENDP
END main
Ответ №1:
Сначала я вижу несколько ошибок и вредных привычек:
GCD PROC,
dividend:DWORD,
divisor:DWORD
Объявление локальных переменных для ваших процедур, на мой взгляд, является плохой привычкой. (результат из языков высокого уровня)
Вам нужно поместить это в свой сегмент данных. Кроме того, есть синтаксическая ошибка, dw-слова неинициализированы, поэтому вы должны объявить их следующим образом:
.DATA ?
dividend dword ?
divisor dword ?
У вас также есть проблема с регистрами для инструкции div:
xor edx,edx
mov eax,xxx ;dividend
mov ebx,yyy ;divisor
div ebx ;eax/ebx
cmp edx,0 ;remainder in edx
Теперь, чтобы использовать ваши наборы значений и разделить их, у вас есть разные варианты:
1-переместите их вручную 1 на 1 в ваших регистрах
mov eax,dword ptr[val01] ;dividend
mov ebx,dword ptr[val02] ;divisor
2- вы помещаете их непосредственно в стек (например, параметры функции)
push val01
push val02
call GDC
;in GDC proc
mov eax,dword ptr[esp 8]
mov ebx,dword ptr[esp 4]
3-поместите их в «массив» и перебирайте их
exercise for you
Ответ №2:
Несколько вещей, которые я вижу (игнорируя правильность вычисления):
mov edx,dividend ;this is value 1
mov ebx,divisor ;this is the divider make sure its smaller number!
div ebx ;divide int1 by int2
DIV ebx
делится EDX:EAX
на EBX
, поэтому вы должны переместить дивиденд в EAX
и очистить EDX
.
cmp edx,0 ;does remainder = 0 ?
je L1 ;yes: quit
call GCD ;no: call GCD agian
Где вы настраиваете параметры для этого вызова?
L1:
mov eax,ebx ;EAX = GCD
Здесь вы перезаписываете частное делителем, это намеренно?
pop edx
pop ebx
Я не вижу, куда вы нажимаете эти регистры. Это делается автоматически MASM? Если нет, вам нужно их нажать.