Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsia_12-14_2011_protsedury_SRC_slaydy.doc
Скачиваний:
9
Добавлен:
21.12.2018
Размер:
1 Mб
Скачать

1) Используя последовательность из n команд рор хх.

Лучше всего это делать в вызывающей программе сразу после возврата управления из процедуры;

2) Откорректировать регистр указателя стека sp на величину 2*n, например, командой

add sp,NN, где NN=2*n, и n – количество аргументов.

Лучше делать в вызывающей программе;

3) используя машинную команду ret n в качестве последней исполняемой команды в процедуре, где n – количество байт, на которое нужно увеличить содержимое регистра esp/sp после того, как со стека будут сняты составляющие адреса возврата. Этот способ аналогичен предыдущему, но выполняется автоматически микропроцессором.

Таким образом, если необходимо работать с процедурой типа near, то для доступа к arg_n достаточно сместиться от содержимого bp на 4, а для доступа к arg_{n-1} – на 6 байт и т. д.

Для far процедур, из за того, что при вызове процедуры дальнего типа в стек записывается полный адрес возврата, то есть содержимое регистров cs и ip для доступа к arg_n команда будет выглядеть так: mov ax,[bp+6], а для arg_{n-1}, соответственно mov ax,[bp+8] и т.д.

Локальные переменные

Локальные переменные процедуры могут располагаться в регистрах, в переменной в сегменте данных (процедуру, использующую этот метод, нельзя вызывать рекурсивно), в стеке. Принято располагать локальные переменные в стеке сразу после сохраненного значения регистра ВР, так что на них можно ссылаться изнутри процедуры, как [ВР-2], [ВР-4], [ВР-6] и т.д.:

Proc1 proc near

p

Пролог

ush bp ; сохранить предыдущий ВР

mov bp,sp ; установить ВР для этой процедуры

sub sp,6 ; зарезервировать 6 байт для локальных переменных

push 35 ; l

push 36 ; m

push 37 ; n

p_x equ [bp+8] ; параметры ; X

p_y equ [bp+6] ; Y

p_z equ [bp+4] ; Z

p_l equ [bp-2] ; локальные переменные ; 37=n

p_m equ [bp-4] ; 36=m

p_n equ [bp-6] ; 35=l

….. (тело процедуры)

m

Эпилог

ov sp,bp ; восстановить SP, выбросив из стека все локальные переменные

pop bp ; восстановить ВР вызвавшей процедуры

ret 6 ; вернуться, удалив параметры из стека

Proc1 endp

Внутри процедуры Proc1 стек будет заполнен следующим образом (см. рис. 5).

Рис. 5. Стек при вызове процедуры Proc1

Последовательности команд, используемые в начале и в конце таких процедур, оказались настолько часто применяемыми, что в процессоре 80186 были введены специальные команды ENTER и LEAVE, выполняющие эти же самые действия:

Proc1 proc near

1_x equ [bp+8] ; параметры

1_y equ [bp+6]

1_z equ [bp+4]

pr_l equ [bp-2] ; локальные переменные

pr_m equ [bp-4] ;

pr_n equ [bp-6]

enter 6,0 ; push bp

; mov bp,sp

; sub sp,6

(тело процедуры)

leave ; mov sp,bp

; pop bp

ret 6 ; вернуться, удалив параметры из стека

Proc1 endp

Реализация рекурсивных процедур

В ассемблере нет средств прямой поддержки рекурсивных алгоритмов.

Планируя использование рекурсивных процедур, необходимо продумывать следующие вопросы:

  • способы передачи параметров в процедуру и возврата результатов ее работы;

  • способ сохранения локальных переменных процедуры;

  • организацию выхода из процедуры.

Как правило, для работы с локальными данными процедуры и параметрами, передаваемыми в процедуру, используется стек. При этом необязательно использовать для этого только системный стек, иногда удобнее создать его модель, работу с которой осуществлять средствами самой программы.

Рассмотрим алгоритм вычисления факториала: F(0)=l: F(i)=i*F(i-1).

С точки зрения скорости работы кода рекурсивный вариант вычисления факториала менее эффективен по сравнению с итеративным методом.

.data

r_fact dw 1

.code

fact proc

push bp

mov bp,sp

mov cx,[bp+4]

mov ax,cx

mul r_fact

mov r_fact,ax

dec cx

jcxz end_p

push cx

call fact

end_p:

mov sp,bp

fact endp

start:

mov ax,@data

mov ds,ax

push 45

call fact

exit:

mov ax,4c00h

int 21h

end start

В любом случае, начало рекурсивной процедуры будет содержать код пролога:

fact рrос

push bp

mov bp,sp

mov cx.[bp+4]

Самостоятельно на практике: Довести программу расчёта факториала до рабочего состояния. (В приведённой выше программе отсутствует эпилог).

Вычисление CRC. Методы определения целостности информации.

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

Наиболее известные из методов обнаружения ошибок передачи данных:

  1. Посимвольный контроль четности, называемый также поперечным (рис. 6), подразумевает передачу с каждым байтом дополнительного бита, принимающего единичное значение по четному или нечетному количеству единичных битов в контролируемом байте. Может использоваться два типа контроля четности — на четность и нечетность. Алгоритм вычисления контрольного бита при контроле на четность предполагает его установку таким образом, чтобы общее количество бит в битовой последовательности (включая и сам бит четности) было четным. И наоборот, контроль на нечетность предполагает установку контрольного бита так, чтобы общее количество битов в битовой последовательности (включая и сам бит четности) было нечетным.

Посимвольный контроль четности прост как в программной, так и в аппаратной реализации, но неэффективен при обнаружении ошибок, так как искажение более одного бита исходной последовательности снижает вероятность обнаружения ошибки передачи. Этот вид контроля обычно реализуется аппаратно в устройствах связи.

Рис. 6. Схема выполнения посимвольного контроля четности при передаче информации

  1. Схема поблочного контроля четности (продольный метод) приведена на рис. 7. Этот метод подразумевает, что для источника и приемника информации заранее известно, какое число передаваемых символов будет рассматриваться ими как единый блок данных. В этой схеме контроля для каждой позиции разрядов в символах блока (поперек блока) рассчитываются свои биты четности, которые добавляются в виде обычного символа в конец блока.

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

Рис. 7. Схема выполнения поблочного контроля четности при передаче информации.

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

  2. Контроль циклически избыточным кодом — CRC (Cyclical Redundancy Check). Это гораздо более мощный и широко используемый метод обнаружения ошибок передачи информации. Он обеспечивает обнаружение ошибок с вероятностью до 99 %.

Метод определения факта нарушения целостности информации CRC.

При распаковке файла может быть выдано сообщение на экран:

«Неправильная сумма CRC. Архив нарушен!»

CRC (Cyclic Redundancy Code) — последовательность бит, полученная по определенному алгоритму на основании другой (исходной) битовой последовательности.

Значение CRC однозначно идентифицирует исходную битовую последовательность и поэтому используется в различных протоколах связи, таких, как HDLC и ZMODEM, а также для проверки целостности блоков данных, передаваемых различными устройствами.

CRC используется во многих архиваторах. Работа многих архиваторов заключается в следующем: архиватор упаковывает файлы в соответствии с некоторым алгоритмом архивации, вычисляя для каждого упаковываемого файла значение CRC.

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

Идея вычисления CRC

1) Исходная последовательность байтов представляется единой последовательностью битов.

2) Эта последовательность делится на некоторое фиксированное двоичное число.

3) Интерес представляет остаток от этого деления, который и является значением CRC.

4) Полученное значение CRC сохраняется и передаётся вместе с исходной последовательностью.

5) Приемник данной информации выполняет деление на то же фиксированное двоичное число и сравнивает его остаток с исходным значением CRC.

6) Если при сравнении оказалось, что полученное при делении CRC и старое значение CRC равны, то исходное сообщение не повреждено, иначе – повреждено.

Реальный алгоритм вычисления CRC использует особые правила арифметики, в соответствии с которыми производятся все вычисления – правила CRC-арифметики. Эти правила отличаются от правил обычной двоичной арифметики.

CRC-арифметика

CRC-арифметика отличается от привычной двоичной арифметики с циклическим переносом отсутствием переносов и вычислением всех коэффициентов по модулю 2.

Особенности CRC-арифметики.

В основе CRC-арифметики лежит полиномиальная арифметика.

По определению, полином — линейная комбинация (сумма) произведений целых степеней заданного набора переменных с постоянными коэффициентами. Частный случай — полином, содержащий одну переменную:

.

Здесь un — элементы некоторой алгебраической системы S, называемые коэффициентами; х — переменная полинома, которую можно рассматривать как формальный символ без определенного значения.

Для рассмотрения CRC арифметики важна полиномиальная арифметика по модулю 2, в которой каждый коэффициент полинома равен одному из двух значений — 0 или 1. Например, шестнадцатеричное значение 0Е3h может быть представлено следующим полиномом:

1*27 + 1*26 + 1*25 + 0*24 + 0*23 + 0*22 + 1*21 + 1*2°.

Если ввести в качестве переменной х=2, то получим следующий двоичный полином:

1*x7 + 1*x6 + 1*x5 + 0*х4 + 0*x3 + 0*x2 + 1*x1 + 1*х°.

Далее

1*x7+1*x6+1*x5+0*х4+0*x3+0*x2+1*x1+1*х = x7+x6+x5+x1+х°.

Над полиномами можно выполнять арифметические операции: сложение, умножение и вычитание.

Например, для умножения 7h (0111b) на 5h (0101b) выполняются действия:

2 + х1 + х°)*(х2 + х°) = (х4 + х3 + х2 + х2 + х1 + х°) =

4 + х3 + 2*х2 + х1 + х° = х4 + х3 + х3 + х1 + х° =

= х4 + 2*х3 + х1 + х°=х4+ х4 + х1 + х°=2*х4 + х1 + х°= х5 + х1 + х°

Переносы можно выполнять в случае, когда известно основание системы счисления. То есть до тех пор, пока мы не знаем х, мы не можем производить и переносы.

Операции сложения и вычитания в полиномиальной арифметике абсолютно идентичны и вместо них можно оставить одну.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]