Как мне написать программу, которая будет отображать первые 24 значения ряда Фибоначчи на ассемблере?
Если бы кто-нибудь мог мне помочь, я был бы очень признателен, я запутался с кодом в сборке.
Как мне написать программу, которая будет отображать первые 24 значения ряда Фибоначчи на ассемблере?
Если бы кто-нибудь мог мне помочь, я был бы очень признателен, я запутался с кодом в сборке.
Ну, вы делаете это почти так же, как и в большинстве других языков, примерно так:
for loop counter = 1 to 24 do
next_number = fibonacci(previous, previous2)
print(next_number)
previous2 = previous
previous = next_number
К очевидным отличиям от других языков относятся:
Я оставил два пробела, потому что код зависит от системы, в которой он будет работать (вы не указали компилятор и операционную систему).
Я не тестировал код, но думаю, что он будет работать.
mov eax, 0 ; first number
mov ebx, 1 ; second number
; edx will contain the third number (eax + ebx )
mov ecx, 24 - 2 ; print 24 numbers (don't count the first
and second because they are printed in the begining)
mov edx, eax
call print_number ; print the first number
mov edx, ebx
call print_number ; print the second number
fibo:
mov edx, eax
add edx, ebx ; edx = eax + ebx
call print_number
; now we have the third number in edx
; eax = 1st, ebx = 2nd, edx = 3rd
; to prepare eax and abx for the next iteration, shift the values to the right
; eax = 2nd, ebx = 3rd, edx = ?
mov eax, ebx
mov ebx, edx
loop fibo
; TO DO: exit program
print_number:
; TO DO: edx contains the number, print it
return
Надеюсь, поможет.
edx
обычно является регистром с затиранием вызовов. Если вы хотите иметь возможность использовать printf
или что-то еще в print_number
, вы должны предположить, что он забьет eax
, ecx
и edx
, но сохранит другие регистры. Так что не используйте ecx
для счетчика циклов и it-efficiently">никогда не используйте медленную инструкцию loop
, если вы не оптимизируете размер кода.
- person Peter Cordes; 25.03.2018
Число в ряду Фибоначчи — это сумма двух предшествующих ему чисел. Для простоты вы можете хранить эти числа в массиве с первыми двумя элементами, равными 1. esi и edi могут указывать на n-1 и n-2, поэтому fibonacci(n) = [esi] + [edi]] right ? В псевдокоде это выглядит так:
fibonacci DWORD 24 dup (?)
esi = fibonacci(0) // those are pointers to elements!
edi = fibonacci(1)
for x = 2 to 23
fibonacci(x) = [esi] + [edi]
esi += 4 // if you don't like DWORDs change this
edi += 4
end loop
вы можете хранить x в регистре ecx и fibonacci(x) в регистре eax.
eax
= последнее сохраненное значение; вам не нужно перезагружать его. И вам нужен только один указатель, потому что режимы адресации допускают смещение. Если вы вообще собираетесь перезагружать (вместо того, чтобы хранить значения в регистрах и только сохранять), вам нужно что-то вроде этого тела цикла: add eax, [edi-8]
/ mov [edi], eax
/ add edi, 4
. Прежде чем этот блок запустится, [edi-4] = eax=Fib(x-1)
, [edi-8] = Fib(x-2)
.
- person Peter Cordes; 25.03.2018
попробуйте этот код, он будет работать в соответствии с вашими требованиями. В этом ответе используется цикл, выполняемый 24 раза, а следующая метка зациклена, которая сначала берет данные из ax и bx, а затем добавляет их. все эти функции повторяются 24 раза до петля завершена.
data segment
org 0000h
arr dw 17h dup(0000h)
data ends
code segment
assume cs:code, ds:data
start: mov ax,data
mov ds,ax
mov cx,0018h
lea si,arr
inc si
mov [si],01h
next: mov ax,[si-1]
mov bx,[si]
add ax,bx
inc si
mov [si],ax
loop next
mov ah,4ch
int 21h
code ends
end start
end
loop
) и мало что добавляет к существующим ответы здесь. Мой ответ на другой question уже содержит полную и хорошо прокомментированную функцию для хранения первых n
чисел Фибоначчи в массиве, где n
передается в регистре, а не является константой времени компиляции.
- person Peter Cordes; 25.03.2018