2016-08-08 9 views
-3

Я написал код, чтобы решить эту подсказку:HLA Ассамблея Рекурсивных Фибоначчи Программа

Создать программу языкового HLA Ассамблеи, которая запрашивает число от пользователя. Создайте и вызовите функцию, которая вычисляет значение в последовательности Фибоначчи. В математике последовательность Фибоначчи названа в честь итальянского математика Леонардо из Пизы, который был известен во время его жизни как Фибоначчи. Последовательность Фибоначчи начинается с 1 и 1. Каждый последующий член в последовательности представляет собой сумму двух предыдущих значений. Таким образом, серия будет: 1,1,2,3,5,8,13 и так далее. Чтобы получить полный кредит, вы должны использовать рекурсию для решения этой проблемы, создавая функцию, подпись которой:

процедура fibRec (значение: int8); @нет дисплея; @noframe; Вот несколько примеров программ диалогов, чтобы направлять свои усилия:

Указывайте номер: 3 выдумки (3) = 2

Предоставить письмо: 5 выдумки (5) = 5

В одном из чтобы помочь вам сосредоточиться на создании программы Ассамблеи, я хотел бы предложить вам следующие операторы С, которые соответствуют указанным выше спецификациям программы. Если хотите, используйте их в качестве основы для создания вашей программы сборки.

SAMPLE C CODE: 
------------------------ 
int main() 
{ 
    int value; 
    printf("Provide a value: "); 
    scanf("%d", &value); 
    int f = fibRec(value); 
    printf("fib(%d) = %d\n", value, f); 
    return(0); 
} 

int fibRec(int value) 
{ 
    int result = 1; 
    if (value == 1 || value == 2) // base case 
     result = 1; 
    else 
     result = fibRec(value-1) + fibRec(value-2); 
    return(result); 
} 

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

еще результат = fibRec (значение-1) + fibRec (значение-2);

часть реализации С.

Вот что у меня есть:

program fib; 
#include("stdlib.hhf"); 

static 
     value : int8; 
     //returnAddress : dword; 
     //temp: int16; 


procedure fibRec(value : int8); @nodisplay; @noframe; 

begin fibRec; 

     mov(CL, value); 
     mov(1, DL); 

     cmp(CL, 1); 
     je Res1; 
     cmp(CL, 2); 
     je Res1; 

     jmp Else1; 

     //else result = fibRec(value-1) + fibRec(value-2); 
Else1: 

     //mov(1, DL); 

     dec(CL); 
     call fibRec; 

     sub(2, CL); 
     call fibRec; 

     add(CL, DL); 

     jmp ProgExit; 

Res1: 
     mov(1, DL); 
     jmp ProgExit; 

ProgExit: 


end fibRec; 


///////////////////////////////////////////////////////////////////////////////////////////////////// 

begin fib; 

    stdout.put("Provide a value: "); 
    stdin.get(value); //CHANGED TO IVALUE 

    mov(CL, value); //SAVES THE INPUT TO A REGISTER 


    call fibRec; // MUST CALL THE PROCEDURE 
    stdout.put("fib("); 
    stdout.puti8(value); 
    stdout.put(") = "); 
    stdout.put(DL); 



end fib; 
+0

звучит как назначение sch. – Mox

+3

См. Http://stackoverflow.com/a/38795365/224132 для рекурсивного Fib (n) для x86. (Это часть ответа об игрушке asm, но я использовал пару макросов и общее подмножество этого языка с x86 для записи рекурсивного Fib (n), который будет работать для обоих.) В любом случае, downvoted это для того, чтобы быть не полезным для другие люди, плохо изученные и полные много ненужного текста. Вся первая половина сообщения может быть «У меня есть задание реализовать Fibonacci (n) в HLA». –

ответ

1

Узнайте, как отлаживать код, есть очевидные проблемы, если бы вы попытаетесь выйти на него, как и в начале перезаписи пользовательского ввода со значением в CL.

Затем в процедуре вы указываете параметр «значение», но вместо этого работаете с CL, перезаписывая содержимое value (не знаете, что это такое в HLA, переменной стека или памяти?).

Вы используете 8-битные регистры CL/DL для значений, но пример C использует int (32b подписан).

Вы можете использовать «@noframe»:

варианта

@NOFRAME говорит HLA, что вы не хотите, чтобы компилятор автоматически генерировать запись и коды выхода для процедуры. Это говорит HLA не автоматически генерировать инструкцию RET (наряду с несколькими другими инструкциями).

Но у вас нет «ret();» в конце вашей процедуры, поэтому выполнение будет продолжено с некоторым случайным кодом после вашей процедуры.

И, наконец, о вашей проблеме рекурсии.

ASM не является C, когда вы вызываете подпрограмму, регистры «живут», как есть, все время, только один набор из них.

Так что это совершенно неправильно:

dec(CL); 
    call fibRec; 
    sub(2, CL); 
    call fibRec; 
    add(CL, DL); 

После первого называют ваш CL и DL уже переписаны. Самый простой и самый простой способ сохранить значения регистра-хранителя - использовать стек, то есть push ecx, edx перед вызовом, затем pop edx, ecx, чтобы восстановить их из стека.

Например, fib. подпрограмма написана на x86 32b ассемблере (синтаксис NASM Intel Так что mov destination, source, другой путь, чем ваш ВУТ!):

fibRecursion: 
    ; expects unsigned "n" (1+) in eax, returns fibonacci(n) in eax 
    ; will crash on large "n" due to stack overflow 
    cmp eax,2 
    ja moreThanTwo 
    mov eax,1   ; n: 0, 1 and 2 returns "1" 
    ret 
moreThanTwo: 
    push edx   ; preserve edx 
    dec eax 
    push eax   ; store n-1 in stack 
    call fibRecursion ; eax = fib(n-1) 
    xchg eax,[esp]  ; store fib(n-1) in stack, get n-1 into eax 
    dec eax 
    call fibRecursion ; eax = fib(n-2) 
    pop edx   ; edx = fib(n-1) 
    add eax,edx  ; eax = fib(n) = eax+edx 
    pop edx   ; restore edx 
    ret 

Yep, так что теперь вы должны просто исправить синтаксис ВУТ ... (больше похоже перепишите его, чтобы вы поняли, как это работает).

И узнайте, как отлаживать ваш код, я думаю, что забыл упомянуть об этом.

Также я упомянул, что вы должны отлаживать свой код?

Я отлаживал эту шахту, так что я на 100% уверен, что она работает так, как ожидалось (для небольших «n», например, несколько сотен/тысяч, не уверен, насколько большой стек по умолчанию для двоичных файлов linux elf32, m не собирается пытаться, когда он сбой при переполнении стека).

+1

* «HLA изначально был задуман как инструмент для обучения программированию на ассемблере». * - Так что да, добавьте C-like вещи в ASM, чтобы сделать его «проще» ... Я не согласен с этим подходом. Особенно со студентами, у которых есть нуль (1-2 семестра), подскажите о C. – Ped7g

 Смежные вопросы

  • Нет связанных вопросов^_^