- •Лекция №12. Процедуры в программах на ассемблере. Crc-код
- •1) Если имя – это имя переменной, то тип может принимать значения byte, word, dword, pword, fword, qword и tbyte;
- •3) Если имя – это имя константы, то тип должен быть abs.
- •Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;
- •Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;
- •Cкомпановать программу утилитой tlink командной строкой вида:
- •1) Используя последовательность из n команд рор хх.
- •2) Откорректировать регистр указателя стека sp на величину 2*n, например, командой
- •1) Сложение по правилам полиномиальной арифметики по модулю 2 (crc-арифметика), будет выполнено так (нет переносов):
- •2) Операция вычитания:
- •1) Согласование имен,
- •2) Согласование параметров,
- •3) Согласование вызовов.
- •Примеры
- •1) Пример использования директивы asm и команд сопроцессора в программе на языке Паскаль (Delphi 5.0).
- •3) Программа, которая использует функцию stdcall get_str_length с асемблерной вставкой, для нахождения длины asciiz-строки.
- •4) Программа, которая складывает два числа в десятичной системе исчисления и выдаёт результат тоже в десятичной системе исчисления. (Example2)
- •Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;
- •Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;
- •Cкомпановать программу утилитой tlink командной строкой вида:
- •4) В ассемблерном модуле вызываемая процедура должна быть дополнительно объявлена при помощи директивы public.
- •К имени процедуры в объектном модуле автоматически добавляется @8 (а не @0).
- •Ассемблер автоматически управляется со стеком.
- •3) Сложение двух целых чисел.
1) Сложение по правилам полиномиальной арифметики по модулю 2 (crc-арифметика), будет выполнено так (нет переносов):
|
11111011 |
+ |
11001010 |
|
00110001 |
Правила сложения:
0+0 = 0;
0+1 = 1;
1+0 = 1;
1+1 = 0.
2) Операция вычитания:
|
11111011 |
- |
11001010 |
|
00110001 |
Правила выполнения вычитания в арифметике с отсутствием переносов:
0-0=0;
0-1=1;
1-0=1;
1-1=0.
Две операции CRC-арифметики (сложение и вычитание) идентичны и по принципу формирования результата они аналогичны команде ассемблера XOR.
Умножение в арифметике с отсутствием переносов также выполняется с учетом особенностей CRC-сложения:
|
|
|
1101 |
|
|
x |
1011 ------- |
|
|
|
1101 |
|
|
|
1101 |
|
|
|
0000 |
|
|
|
1101 |
|
|
|
--------------- |
1111111 |
При этом, в самом умножении особенностей нет, а вот сложение промежуточных результатов производится по правилам CRC-сложения.
Лекция №13. Прямой алгоритм вычисления CRC. Встроенный ассемблер.
Так как CRC-код – это по сути остаток от деления исходной последовательности на некоторое двоичное число.
CRC деление.
При делении необходимо ввести в рассмотрение понятие «слабое понятие размерности»: число X больше или равно числу Y, если оба числа имеют одинаковую размерность и позиции их старших битов единичны, то есть соотношение остальных битов X и Y для операции сравнения не имеет значения.
Рассмотрим обычное деление (по правилам двоичной арифметики с циклическим переносом) рис. 8;
Рис. 8. Схема вычисления двоичного деления (с циклическим переносом)
CRC-деление (рис. 9).
Рис. 9. Схема вычисления CRC-деления
Снос двоичных разрядов при CRC делении из делимого продолжается до тех пор, пока размерности промежуточного битового значения и делителя не сравняются, а их старшие разряды не станут равными 1. После этого над двоичными разрядами выполняется побитовое CRC-вычитание.
При вычитании соотношение разрядов не важно, главное — это одинаковая размерность и единичные старшие биты. В этом случае считается, что вычитаемое меньше уменьшаемого. Это и есть проявление слабого понятия размерности.
Частное для процесса вычисления CRC-кода не имеет никакого значения.
Реальные двоичные последовательности являются результатом сцепления большого количества отдельных байтов (символов), образуя одно большое двоичное число.
В терминах полиномиальной арифметики исходное двоичное число называется полиномом данных (сообщения) и обозначается как D(x).
В алгоритме вычисления CRC вводится еще несколько полиномов и соотношений между ними:
-
порождающий полином G(x) — предварительно особым образом выбранный полином, на который делится исходный полином сообщения;
-
полином-частное Q(x) — полином, получившийся в качестве частного от деления полиномов D(x)/G(x);
-
полином-остаток R(x) — полином, получившийся в качестве остатка от деления полиномов D(x)/G(x). Полином-остаток R(x) называется CRC (Cyclic Redundancy Code).
Между перечисленными полиномами существуют следующие отношения:
D(x)=Q(x)*G(x)+R(x), Q(x)=(D(x)-R(x))/G(x).
D(x)=Q(x)*G(x)+R(x);
Выбор делителя G(x)
При выборе делителя G(x) должны учитываться следующие свойства:
-
Число разрядов (количество членов) в полиноме-остатке R(x) непосредственно определяется длиной самого порождающего полинома G(x). Выбор G(x) длиной n гарантирует, что полином-остаток от деления R(x) будет иметь разрядность не более, чем n-1.
-
Способность порождающего полинома G(x) к выявлению ошибок, специфичных для передачи данных по каналами связи. Это такие ошибки, как ошибки в одном, двух, нечетном количестве битов, а также ошибки блока битов.
Для большинства алгоритмов вычисления CRC значение порождающего полинома известно и утверждено соответствующими стандартами. Определять новое значение порождающего полинома G(x) нет необходимости.
Значения некоторых известных полиномов, используемых на практике.
-
x16+х12+х5+х0 (1 0001 0000 0010 0001b) — полином 1021h, используемый в протоколе XMODEM и производных от него протоколах передачи данных. Он стандартизован в спецификации V.41 МККТТ «Кодонезависимая система контроля ошибок».
-
х16+х15+х2+х0 (1 1000 0000 0000 0101b)— полином 8005h, используемый в протоколе двоичной синхронной передачи фирмы IBM. Он также стандартизован. Этот полином широко известен как полином, используемый в алгоритме вычисления CRC — CRC16.
-
x32+x26+x23+x22+x16+x12+x11+x10+x9+x7+x5+x4+x2+x1+x0
(1 0000 0100 1100 0001 0001 1110 1011 0111b) – полином 04C1 1EB7h, используемый в алгоритме вычисления CRC — CRC32 и также стандартизованный в стандарте V.42 МККТТ. Этот полином, в частности, используется в технологии локальных вычислительных сетей Ethernet.
-
x32+x31+x30+x29+x27+x26+x24+x23+x21+x20+х19+х15+х9+х8+х5. (1 1110 1101 1011 1000 1000 0011 0010 0000b=EDB8 8320) Данный полином используют различные архиваторы.
Степень полинома – номер позиции его старшего единичного бита (считая с нуля). Например, для полинома 1011 степень равна 3.
Прямой алгоритм вычисления CRC
CRC-алгоритм удобно рассматривать с точки зрения двух сторон-участников процесса: источника и приемника. Действия источника следующие:
1. Выбрать полином G, в результате автоматически становится известной его степень N.
2. Добавить к исходной двоичной последовательности N нулевых битов. Это добавление делается для гарантированной обработки всех битов исходной последовательности.
3. Выполнить деление дополненной N нулями исходной строки S на полином G по правилам CRC-арифметики. Запомнить остаток, который и будет являться CRC.
4. Сформировать окончательное сообщение, которое будет состоять из двух частей: собственно сообщения и добавленного в его конец значения CRC. Длина присоединяемого к исходной последовательности значения CRC должна быть равна степени полинома, даже если CRC имеет ведущие нули.
Например: имеем исходную последовательность 1101001110010110100 (см. рис. 10). Окончательная последовательность на стороне источника будет выглядеть так (рис. 10):
Рис. 10. Схема формирования выходного сообщения из исходного с использованием CRC-алгоритма.
На стороне приёмника:
1) Выполняется CRC-деление полученной последовательности на полином и анализируется остаток.
2) Если остаток от деления нулевой, то исходная последовательность не была нарушена во время передачи. В противном случае - нарушена.
Для компьютерной реализации алгоритмов вычисления CRC выбирают полиномы со степенями, кратными 8 (то есть размерности регистров) — 8, 16, 24, 32 или 64. Пример: в качестве полинома выберем полином 4003h.
Cтепень полинома определяет размерность регистра, используемого в алгоритме, при этом считается, что старший (всегда единичный) бит полинома находится сразу за левой границей регистра.
Программа реализации прямого алгоритма вычисления CRC функционирует следующим образом:
А) в регистр побитно вдвигаются биты исходной строки (рис. 11). Это происходит до тех пор, пока при очередном сдвиге слева появится единичный бит.
Б) при появлении в 31 бите регистра еах единицы все содержимое регистра подвергается операции XOR со значением полинома без старшего бита. Результат операции XOR записывается в еах.
В) процесс сдвига и анализа выдвигаемого бита продолжается до тех пор, пока не будет выдвинут очередной единичный бит, и повторяется пункт (б).
Г) если последний бит данных вдвинут в регистр, в него вдвигается количество нулевых битов, равное степени полинома и повторяется алгоритм начиная с пункта (б).
Д) в результате в регистре остается значение CRC, которое необходимо добавить к исходной строке и передать приемнику.
Рис. 11. Схема вычисления значения CRC прямым алгоритмом
В результате вычисления CRC символьной последовательности "6476с8" получим CRC 35dah.
Самостоятельно на практике: Разработать программу, которая бы вычисляла с помощью прямого алгоритма вычисления CRC значение CRC-кода для входной последовательности, состоящей из 24 бит.
Встроенный ассемблер
Стыковка ассемблера с языками высокого уровня основывается на трех китах: