MIPS Сборка заданий ПОМОГИТЕ! - PullRequest
1 голос
/ 02 декабря 2009

Мой самый близкий друг проходит курс EE (я его последняя надежда: /), я знаю Java примерно 7 лет назад, но его (набросок) последнего задания EE по программированию - использовать Сборка MIPS делает следующее:

Напишите программу, которая принимает два натуральных числа (m и n) и вычисляет:

x= (m^n) - (1+2+3+…+n) * min(m,n)!

Оба целых числа должны быть больше нуля. Мне не разрешено использовать арифметические инструкции R-типа (add, mult, sub). Вместо этого я пишу код для своих функций, используя другие инструкции ???? «Ваша программа должна продолжать получать новые значения для m и n после каждого вычисления, пока пользователь не введет ноль, который станет концом для вашей программы».

У меня нет доступа ни к одному из его предыдущих заданий, и попытка погрузить голову 1-го на язык ассемблера БЕЗ использования (add, mult, sub) не работает для меня слишком хорошо.

ece.ucdavis.edu / ~ Vojin / КЛАССЫ / EEC70 / W2001 / pr4.pdf Проф, казалось, использовал назначение ols с того времени, когда он преподавал в Калифорнийском университете в Дэвисе.

// редактировать Вот версия проблемы на языке c ++, она не охватывает все базы назначения, но является отправной точкой:

#include <iostream.h>

//x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)
int m; //User Input
int n; //User Input
double answer; //Answer yo.

int findMin(int, int); //Takes 2 int inputs and outputs the smallest int.
int minFound; //Function output

double factorial(int); //Do eet.
double factOutput; //Function output

double sumN(int); //1+2+3+...+n
double sumFound; //Function output

double expMtoN(int, int); //m^n, float for number size,
double expFound; //Function output, float for number size,

int main(void)
{
    cout << "Please enter a positive integer (m): ";
    cin >> m;

    //Escape if zero.
    if ( m == 0)
    {
        cout << "User input for \"m\" is equal to zero; escape on zero." << endl;
        return 0;
    }

    cout << "Please enter a positive integer (n): ";
    cin >> n;

    //Escape if zero.
    if ( n == 0)
    {
        cout << "User input for \"n\" is equal to zero; escape on zero." << endl;
        return 0;
    }

    expFound   = expMtoN(m, n);       //m^n
    sumFound   = sumN(n);             //1+2+3+...+n
    minFound   = findMin(m, n);       //Takes 2 int inputs and outputs the smallest int.
    factOutput = factorial(minFound); //Factorial math for minFound (z!)

    answer = expFound - sumFound * factOutput; //x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)

    cout << endl;
    cout << m << " raised to the power of " << n << " is: " << expFound << endl;
    cout << "Sum of " << n << " is: " << sumFound << endl;
    cout << "Lowest number out of " << m << " and " << n << " is: " << minFound << endl;
    cout << minFound << " factorial is: " << factOutput << endl;

    cout << endl << "x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)" << endl;
    cout << "x = " << answer << endl;
}

//all temp variables below are confined to their respective functions.
//return functions output temp into variable from main.

double expMtoN(int userBase, int userExp)
{
    double temp = 1; //Must establish  1 so you are not multiplying by zero.

    for ( int i = 1; i <= userExp; i++ )
        temp *= userBase;

    return temp;
}

double sumN(int userN)
{
    double temp = 0;

    for ( int i = 1; i <= userN; i++ )
        temp = temp + i;

    return temp;
}

int findMin(int userM, int userN)
{
    if( userM <= userN )
        return userM;
    else
        return userN;
}

double factorial(int minFound)
{
    double temp;

    if ( minFound <= 1 )
        return 1;

    temp = minFound * factorial(minFound - 1);

    return temp;
}

Input.s


;-----------------------------------------------------------------------------
;Subprogram call by symbol "InputUnsigned"
;expect the address of a zero-terminated prompt string in R1
;returns the read value in R1
;changes the contents of registers R1,R13,R14
;-----------------------------------------------------------------------------

  .data

  ;*** Data for Read-Trap
ReadBuffer: .space  80
ReadPar: .word  0,ReadBuffer,80

  ;*** Data for Printf-Trap
PrintfPar: .space  4

SaveR2:  .space  4
SaveR3:  .space  4
SaveR4:  .space  4
SaveR5:  .space  4


  .text

  .global  InputUnsigned
InputUnsigned: 
  ;*** save register contents
  sw  SaveR2,r2
  sw  SaveR3,r3
  sw  SaveR4,r4
  sw  SaveR5,r5

  ;*** Prompt
  sw  PrintfPar,r1
  addi  r14,r0,PrintfPar
  trap  5

  ;*** call Trap-3 to read line
  addi  r14,r0,ReadPar
  trap  3

  ;*** determine value
  addi  r2,r0,ReadBuffer
  addi  r1,r0,0
  addi  r4,r0,10 ;Decimal system

Loop:  ;*** reads digits to end of line
  lbu  r3,0(r2)
  seqi  r5,r3,10 ;LF -> Exit
  bnez  r5,Finish
  subi  r3,r3,48 ;´0´
  multu  r1,r1,r4 ;Shift decimal
  add  r1,r1,r3
  addi  r2,r2,1  ;increment pointer
  j  Loop

Finish:  ;*** restore old register contents
  lw  r2,SaveR2
  lw  r3,SaveR3
  lw  r4,SaveR4
  lw  r5,SaveR5
  jr  r31  ; Return 

1 Ответ

2 голосов
/ 14 марта 2011

К сожалению, если это код C, то код MIPS будет как минимум в 4 раза длиннее и намного дольше с учетом ограничений. Этот код может занять некоторое время, но я могу дать псевдо-прогон:

x = (m ^ n) - (1 + 2 + 3 +… + n) * min (m, n)!

Давайте сначала заметим, что, как и в любом другом языке программирования, мы должны разделить нашу задачу на как можно больше методов. В MIPS мы хотим разделить задачу на как можно больше «процедур» (меток). Мы уже видим, что нам понадобится процедура для экспоненты, факториала и т. Д. Начнем с m ^ n. Мы не можем использовать mult, так как это R-тип, но мы можем использовать multi, то есть I-тип. Мы можем использовать все непосредственные I-типы в качестве замены для этого назначения. Таким образом, мы могли бы сделать: multi m, m, например, в цикле for и сделать это n раз, давая m ^ n (в каждой итерации мы должны были бы перемещать результаты из регистров умножения Hi и Lo, используя инструкции mfhi и mflo, для расчета, чтобы они не перезаписывались). Это будет наша первая процедура.

Теперь мы смотрим на 1 + 2 + 3 + ... + n. Это не так уж плохо, мы просто продолжаем использовать addi (инструкция добавления типа I, которая добавляет «немедленные» константы в регистр), такие как addi $ s1, $ s1, b, где a равно 1, которое увеличивается в a цикл и добавляется к результату n раз, получая, таким образом, 1 + 2 + 3 + ... + n.

Наконец, нам нужна еще одна процедура, чтобы умножить это на min (m, n) !. Factorial является рекурсивным, поэтому нам понадобится рекурсивная процедура, которая вызывает сама себя и эффективно использует стек памяти и разлив регистров (IE сначала сохраняет аргументы процедуры и адрес возврата в стеке, вводит тело, снова сам вызов). Я думаю, этого достаточно, чтобы вы начали. Не уверен, когда задание назначено, но удачи!

...