BMSTU/02-dspmd-02-hw-var-lama.tex

119 lines
6.9 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\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}