Преобразование кода C в язык ассемблера Mips - PullRequest
0 голосов
/ 12 марта 2019

Привет, поэтому я новичок во всем коде сборки MIPS и пытаюсь научить себя с помощью онлайн-справки.Я могу понять некоторые его части и как это работает.Моя проблема, которую мне нужно решить сейчас:

int A[50], B[50]; 
for (i=1; i < 50; i++) { 
 A[i] = A[i] + B[i-1] / A[i-1]; 
}

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

1 Ответ

1 голос
/ 13 марта 2019

Вот как компиляторы переводят этот вид кода.
Это код C, но он строго эквивалентен вашему исходному коду и написан таким образом, что каждая инструкция C может быть сопоставлена ​​с инструкцией asm. Я даже написал, какую инструкцию следует использовать.

int * pA=&A[0];     // mov
int * pB=&B[0];     // mov
int i=1;            // addi
int n=50;           // addi
do{
  // body of for loop
  int B_1=*(pB-1) ; // lw
  int A_1=*(pA-1) ; // lw
  int D=B_1/A1;     // div
  int A=*pA;        // lw
  A += D;           // add
  *pA = A;          // sw
  // increment part of the loop
  i+=1;             // addi
  pA+=1;            // addi
  pb+=1;            // addi
  // test part of the loop
  while (i<N);      // blt -> do
 }

Вам просто нужно выбрать регистр для всех переменных (например, выбрать скопировать pA в $t3 (или r4 или что-то еще) и выяснить, как перевести эту инструкцию в asm. Посмотрите на Документация MIPS и перевод должны быть легкими.

Есть несколько важных вещей, которые нужно знать.

  1. Указатели аналогичны адресам памяти, которые обрабатываются процессором, за исключением случаев, когда речь идет об увеличении (или общей арифметике указателей). Если p является указателем на элемент типа T в C, p++ означает, что p будет указывать на следующий элемент типа T. Для адресов следует учитывать размер типа. Если int равен 4 байта, «точка к следующему целому» будет соответствовать «добавить к адресу размер целого» (то есть 4).

  2. lw и sw используют адресацию на основе, то есть они могут добавить немедленный адрес. Указатель арифметики также актуален. Таким образом, если p является указателем int, и вы хотите реализовать x=*(p+2), предполагая, что x находится в $t4, а p находится в $t7, вы должны сделать lw $t4,8($t7), что означает чтение память по адресу $t7+8 (как 8==2*sizeof(int).

Не должно быть слишком сложно написать первый код. Затем вы можете попытаться оптимизировать его. Может быть, загрузка A[i-1] на каждой итерации бесполезна, например? Может быть, вы можете уменьшить количество переменных (регистров)?

...