\documentclass[a4paper,fontsize=14bp]{article}

\input{../common-preamble}
\input{../fancy-listings-preamble}
\input{../bmstu-preamble}
\numerationTop

\begin{document}
\thispagestyle{empty}
\makeBMSTUHeader

Официальное описание из комментария к функции хорошо объясняет, что именно она делает:
\begin{verbatim}
Description: minimum Value and Index of the minimum 
    element of a vector
\end{verbatim}

Снаружи функция будет вызываться вот так
\begin{verbatim}
void minvec (DATA *x, ushort nx, DATA *val, DATA *idx)
\end{verbatim}
То есть передадим
\begin{itemize}
\item вектор (массив чисел) \code{DATA *x}, важно, что вектор у нас из типа \code{DATA}, который, на самом деле \code{ushort (unsigned short)}, 16-разрядный, то есть при подсчёте сдвига по вектору для получения следующего значения - нужно смещаться на 2 байта.
\item длину вектора \code{ushort nx}, 
\item указатель на полученное значение \code{DATA *val}, 
\item указатель на полученный индекс \code{DATA *idx}.
\end{itemize}

Для языка ассемблера, умеющего манипулировать только регистрами, важно понимать, в какие именно регистры будут положены эти параметры
\begin{itemize}
\item \code{DATA *x} - указатель AR0 
\item \code{ushort nx} - регистр T0
\item \code{DATA *val} - указатель AR1
\item \code{DATA *idx} - указатель AR2
\end{itemize}

дальше последовательно опишем что именно делает функция и как:

\begin{verbatim}
 .text 
 .global _minvec 
_minvec: 
\end{verbatim}

до вызова функции система находилась в каком-то статусе, соответственно, нам нужно этот статус сохранить, чтобы наша функция ничего не сломала
\begin{verbatim}
 PSH mmap(ST0_55) ; Сохранение регистров статуса на стеке 
 PSH mmap(ST1_55) 
 PSH mmap(ST2_55) 
 PSH mmap(ST3_55) 
\end{verbatim} 

далее происходит одновременное действие, знак \code{II} показывает, что два этих действия будут выполняться параллельно. Запись очередного значения из вектора во временный регистр \code{AC1} и вычитание 2 из регистра \code{T0}. Запись \code{*AR0+} означает, что мы не только разыменовали указатель (получили значение по указателю, знак *), но и сдвинули указатель вектора на следующий адрес (знак +)
\begin{verbatim}
 MOV *AR0+,AC1
 || SUB #2,T0
\end{verbatim}

Сохраним значение из \code{T0} в \code{BRC0} и одновременно запишем 0 в \code{AR3}. Это вспомогательное действие, чтобы высвободить регистры, при помощи которых мы будем делать дальнейшие вычисления.
\begin{verbatim}
 MOV T0,BRC0 
 || MOV #0,AR3 
\end{verbatim} 

Далее происходит обнуление регистра \code{T0} и цикл между значением \code{RPTBLOCAL} и \code{end_block:} 
\begin{verbatim}
 MOV #0,T0 
 || RPTBLOCAL end_block-1 
\end{verbatim}

В цикле мы кладём следующее значение из вектора в \code{AC0}, помнишь, мы уже клали значение из вектора в \code{AC1}, вот теперь в \code{AC0}. Мнемоника \code{MAR} в явном виде не описана в документации, но есть предположение, что MAR это аббревиатура от Modify Auxiliary Register, то есть по факту это просто увеличение временного указателя на будущий вычисленный индекс на единицу. Напомню, в этот регистр два шага назад, до цикла, мы положили 0, то есть, скорее всего, это будет конечный индекс в векторе, который мы должны вернуть.
\begin{verbatim}
 MOV *AR0+,AC0 
 || MAR *AR3+ 
\end{verbatim}

Тут, понятно, мы ищем минимальное из двух значений (мы же положили последовательно два значения из вектора в \code{AC0} и \code{AC1}). Значение, полученное в результате сравнения, будет положено в \code{AC1}\footnote{TMS320C55x-Mnemonic Instruction Set. Reference Guide-2009, p.428}. То, что мы положим минимальное в \code{AC1} даст нам возможность на следующей итерации цикла снова сравнивать с ним прочитанное в \code{AC0} следующее значение из вектора, как мы это делаем на предыдущем шаге.
\begin{verbatim}
 MIN AC0,AC1
\end{verbatim}

Это проверка условия завершения цикла \footnote{TMS320C55x-Mnemonic Instruction Set. Reference Guide-2009, p.749 (XCCPART), p.20(CARRY)} по биту переноса и одновременно вывод информации из \code{AR3} (в котором, напомню, у нас хранился индекс минимального значения в векторе) по указателю \code{AR2}, который, напомню, нам передали с параметрами функции 
\begin{verbatim}
 XCCPART end_block, !CARRY 
 || MOV AR3,*AR2 
\end{verbatim}

По завершении цикла, сохраним полученное значение минимума по указателю \code{AR1}, который мы передали снаружи в параметре \code{val}.
\begin{verbatim}
end_block: 
 MOV AC1,*AR1 
\end{verbatim}

Вернём на место статус системы из сохранённого ранее и выйдем из функции
\begin{verbatim}
 POP mmap(ST3_55) 
 POP mmap(ST2_55) 
 POP mmap(ST1_55) 
 POP mmap(ST0_55) 
 RET
\end{verbatim}

\begin{lstlisting}[language=C,style=CCodeStyle]
void minvec (DATA *x, ushort nx, DATA *val, DATA *idx) {
  while (nx-- >= 0) {
    if (*val > *(x + nx)) {
      *val = *(x + nx);
      *idx = nx;
    }
  }
}
\end{lstlisting}

\end{document}



