Вариант сборки Фибоначчи x86, должен вызывать его из основного метода C++, вид потерян в нескольких частях

Это код Фибоначчи,

unsigned int fib(unsigned int n)
{
if (n==1 || n ==2)
return 1;
else
return fib(n-2) + fib(n-1);
} 

но вместо этого для моего кода я должен изменить формулу на новую, f(n-2)/2 + f(n-1) * 2, поэтому последовательность составляет 1, 2, 4, 9, 20, 44, 98, 218

Мне нужно написать рекурсивную функцию под названием Mobonacci в ассемблере для вычисления n-го числа в последовательности, а также основную функцию в C++, которая читает положительное число n, затем вычисляет функцию ассемблера mobonacci с параметром n, затем выводит наш результат

Так что я немного растерялся, пишу ли я функцию в ассемблере, как я это делал ниже, а затем пишу функцию C++ для ее вызова? и как бы ребята изменили мой код с Фибоначчи на новую формулу? Вот мой код, что мне нужно изменить, и мне нужно было создать новую часть, которая позволяет коду читать ввод? Также мой код слишком короткий? мне нужно добавить что-нибудь еще?

.code
    main PROC
        mov ecx,0
        push 4          ; calculate the nth fib
        call Fib            ; calculate fib (eax)
        call WriteDec
        call Crlf
        exit
    main ENDP

    Fib PROC
        add ecx,1
        push ebp
        mov  ebp,esp
        mov  eax,[ebp+8]    ; get n
        cmp  eax,2      ; n == 2?
        je   exception2     
        cmp  eax,1      ; n == 1?
        je   exception2         
        dec eax
        push eax            ; Fib(n-1)
        call fib

        add eax,
        jmp Quit


    Exception2:
        dec eax
    Quit:
        pop  ebp            ; return EAX
        ret  4          ; clean up stack
    Fib ENDP

    END main

1 ответ

Зависит от того, где вы пытаетесь вставить asm-код в ваш код на C++... Для gcc/linux вы можете сделать что-то вроде:

    //Simple example:
    void *frame; /* Frame pointer */
    __asm__ ("mov %%ebp,%0":"=r"(frame));

   //Complicated example:
   int foo(void) {
     int joe=1234, fred;
     __asm__( 
        "  mov %1,%%eax\n"
        "  add $2,%%eax\n"
        "  mov %%eax,%0\n"
        :"=r" (fred) /* %0: Out */
        :"r" (joe) /* %1: In */
        :"%eax" /* Overwrite */
     );
     return fred;
  }

Важно понимать, как использовать вашу функцию asm в cpp. Вы можете найти некоторые полезные вещи на эту тему здесь: https://www.cs.uaf.edu/2011/fall/cs301/lecture/10_12_asm_c.html

О второй части вашего вопроса. Для многократного использования можно использовать команду "mul" и сделать деление "div". Поэтому, если вы хотите выполнить f(n-1) * 2, вам нужно зарегистрировать %eax после "call fib" и использовать mul.

Просто посмотрите здесь: http://www.tutorialspoint.com/assembly_programming/assembly_arithmetic_instructions.htm

Другие вопросы по тегам