Отображение первых 24 значений в ряду Фибоначчи

Как мне написать программу, которая будет отображать первые 24 значения ряда Фибоначчи на ассемблере?

Если бы кто-нибудь мог мне помочь, я был бы очень признателен, я запутался с кодом в сборке.


person Stephanie Dente    schedule 22.03.2011    source источник
comment
Что за ассемблер?   -  person Greg    schedule 22.03.2011
comment
Пожалуйста, постарайтесь предоставить более подробную информацию о том, что вы пробовали и что вас смущает, вместо того, чтобы просто спрашивать ответ на то, что кажется проблемой домашнего задания.   -  person quarkdown27    schedule 22.03.2011


Ответы (4)


Ну, вы делаете это почти так же, как и в большинстве других языков, примерно так:

for loop counter = 1 to 24 do
    next_number = fibonacci(previous, previous2)
    print(next_number)
    previous2 = previous
    previous = next_number

К очевидным отличиям от других языков относятся:

  1. В этом случае все ваши «переменные», вероятно, будут в регистрах.
  2. Вероятно, вам придется написать собственный код для преобразования и печати числа.
person Jerry Coffin    schedule 22.03.2011

Я оставил два пробела, потому что код зависит от системы, в которой он будет работать (вы не указали компилятор и операционную систему).

Я не тестировал код, но думаю, что он будет работать.

    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

Надеюсь, поможет.

person Javi R    schedule 23.03.2011
comment
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.

person BlackBear    schedule 22.03.2011
comment
У вас всегда есть 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
person sam yo    schedule 25.03.2018
comment
Вы используете только 1-байтовые элементы массива, так что это переполняется задолго до Fib(24). - person Peter Cordes; 25.03.2018
comment
Немного больше объяснений сделало бы этот ответ более полезным для гораздо большего числа пользователей. - person Kind Stranger; 25.03.2018
comment
@KindStranger: не намного полезнее; это довольно неэффективно (перезагрузка вместо использования значения в регистре и медленная инструкция loop) и мало что добавляет к существующим ответы здесь. Мой ответ на другой question уже содержит полную и хорошо прокомментированную функцию для хранения первых n чисел Фибоначчи в массиве, где n передается в регистре, а не является константой времени компиляции. - person Peter Cordes; 25.03.2018
comment
@PeterCordes, если в ответе есть больше объяснений, это делает его более понятным для кого-то вроде меня, у которого нет понимания сборки, поэтому, возможно, я смогу понять, полезен он или нет. Это был комментарий для ответившего. - person Kind Stranger; 25.03.2018
comment
@KindStranger: Вы попали сюда из очереди на проверку новых пользователей? Код в этом ответе не ужасен, но Fib(24) = 46368 и является самым большим числом Фибоначчи, которое не выходит за пределы 16-битного целого числа. Таким образом, 16-битный код может легко решить вопрос с 16-битными регистрами, но не с 8. Я бы убрал свой отрицательный голос, если бы он хотя бы работал, но не стал бы голосовать, потому что я не думаю, что это хорошо< /i> решение, особенно без текста, объясняющего, почему они решили написать его именно так. В любом случае, я думаю, что вопрос является дубликатом того, на который я ответил. - person Peter Cordes; 25.03.2018
comment
@PeterCordes, нет. Я не говорю, что вы ошибаетесь или что ответ в любом случае правильный, я просто думаю, что ответ можно улучшить с помощью некоторого объяснения независимо от его правильности. - person Kind Stranger; 25.03.2018
comment
@KindStranger: да, я согласен с этим. Ответы никогда не должны быть дампами кода без текста. Я комментирую, чтобы дать вам краткое изложение того, что я думаю о его качестве (и было ли это полезным дополнением к этому вопросу или к SO в целом), поскольку вы сказали, что не знаете asm. TL:DR: тратить время на улучшение этого ответа, вероятно, будет иметь ограниченную ценность, хотя есть много возможностей для улучшения. Возможно, этот вопрос должен был быть об устаревшем 16-битном x86, учитывая отсечку Fib(24). В своих предыдущих комментариях я думал, что Fib(24) больше и нуждается в 32-битной версии. - person Peter Cordes; 25.03.2018
comment
@Sam: Добро пожаловать в Stack Overflow. Публикация дампов кода по старым вопросам не очень полезна. Если у вас есть что-то новое, чтобы добавить к старому вопросу, по крайней мере, включите текст, объясняющий, что показывает ваш ответ (например, сохранение значений в массиве вместо того, чтобы печатать их внутри цикла), чтобы люди, увидев ваш ответ, знали, может ли ваш код быть тем, что они ищут. Также объясните, почему вы реализовали его именно так, и всегда комментируйте свой код, чтобы показать, как он работает. Это необязательно в языке ассемблера, где вы не можете использовать описательные имена переменных, только регистры. - person Peter Cordes; 25.03.2018