Инструменты пользователя

Инструменты сайта


examination:asm:question42

Вопрос №42. Битовые строки. Примеры работы.

Очень часто для экономии памяти в байт или слово упаковывают несколько коротких чисел, называемых битовыми полями. Для выполнения различных операций с этими числами вначале нужно выделить последовательность битов, составляющих поле, которая называется битовой строкой. Например, при написании программ для системы MS DOS пользуются функцией 57 00h прерывания INT 21h, чтобы определить дату последней модификации файла. Она возвращается в регистре DX в упакованном формате. При этом значение, определяющее день месяца (число 1…31), находится в битах 0—4. В битах 5-8 находится значение, соответствующее месяцу (число 1…12), а в битах 9-15 содержится значение, соответствующее количеству лет, прошедших с 1980 года.

Примеры работы с битовыми строками

Рассогласование битовых строк

Наглядный пример рассогласования последовательностей битов — преобразование неупакованного BCD-числа в упакованное BCD-число. Один из вариантов такого преобразования был рассмотрен нами ранее при обсуждении команды линейного сдвига SHL Попробуем выполнить подобное преобразование с использованием команд сдвига двойной точности (листинг 9.2). В общем случае длина числа может быть произвольной, но при этом нужно учитывать ограничения, которые накладываются используемыми ресурсами процессора. Ограничения связаны в основном с тем, что центральное место в преобразовании занимает регистр ЕАХ, по- этому, если преобразуемое число имеет размер более четырех байтов, то его придется делить на части. Но это уже чисто алгоритмическая задача, поэтому в нашем случае предполагается, что неупакованное BCD-число имеет длину 4 байта.

Листинг 9.2. Преобразование BCD-числа (вариант 2)

;prg_9_2.asm

masm

model small

stack 256

.data

len=4 ;длина неупакованного BCD-числа

unpck_BCD label dword

dig_BCD db 2,4,3,6 ;неупакованное BCD-число 6342

pck_BCD dd 0 ;pck_BCD=00006342

.code

main: ;точка входа в программу

mov ax,@data

mov ds.ax

xor ax,ax

mov cx.len

.386 ;это обязательно

mov eax,unpck_BCD

ml:

shl eax,4 ;убираем нулевую тетраду

shld pck_BCD,eax,4 ;тетраду с цифрой заносим в поле pck_BCD

shl eax,4 ;убираем тетраду с цифройиз еах

loop ml ;цикл

exit: ;pck_BCD=00006342 mov ax,4c00h

int 21h

end main

Команды сдвига двойной точности SHLD и SHRD позволяют осуществлять с максимально возможной скоростью вставку битовой строки из регистра в произвольное место другой (большей) строки битов в памяти и извлечение в регистр битовой подстроки из некоторой строки битов в памяти. В результате этих операций смежные с подстрокой биты по ее обеим сторонам остаются неизменными.

Вставка битовых строк

Рассмотрим пример вставки битовой строки длиной 16 битов, находящейся в регистре ЕАХ, в строку памяти str, начиная с ее бита 8 (листинг 9.3). Вставляемая битовая строка выровнена к левому краю регистра ЕАХ.

Листинг 9.3. Вставка битовой строки

<1> ;prg_9_3.asm

<2> raasm

<3> model small

<4> stack 256

<5> .data

<6> bit_str dd HOlOlllh -.строка для вставки

<7> P_str dd OffffOOOOh вставляемая подстрока Qffffh

<8> .code

<9> main: ;точка входа в программу

<10> mov ax,@data

<11> mov ds.ax

<12> xor ax, ax

<13> .386 ;это обязательно

<14> mov eax,p_str

<15> ; правый край места вставки циклически переместить к краю

<16> ;строки bit_str (сохранение правого контекста):

<17> ror bit_str,8

<18> shr bit_str,16 ;сдвинуть строку вправо

;на длину подстроки (16 битов)

<19> shld bi t_str ,eax,16 ;сдвинуть 16 бит

<20> rol bit_str,8 восстановить младшие 8 бит

<22> exit: ;bi t_str=llf f f f 11

<23> mov ax,4c00h

<24> int 21h

<25> end main

Листинг 9.3 удобно исследовать в отладчике. При этом важно понять зависимость между непосредственными значениями, используемыми в командах строк 17-20, и исходными значениями. Общая методика вставки битовых строк выглядит следующим образом.

1. Подогнать к правому краю строки младший бит места вставки в этой строке. Делать это нужно командой циклического сдвига, чтобы сохранить правую часть исходной строки. Величина сдвига определяется очень просто — это номер начальной позиции места вставки (строка 17).

2. Сдвинуть исходную строку вправо на количество битов, равное длине вставляемой подстроки (строка 18). Эти биты нам больше не нужны, поэтому для сдвига используется команда простого сдвига SHR.

3. Командой SH LD вставить вставляемую подстроку в исходную подстроку. Перед этим, естественно, левый край вставляемой подстроки находится у левого края регистра ЕАХ (строка 19).

4. Восстановить командой циклического сдвига правую часть исходной строки (строка 20).

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

Извлечение битовых строк

Рассмотрим пример извлечения 16 битов из строки в памяти bit_str, начиная с бита 8, в регистр ЕАХ (листинг 9.4). Результат следует выровнять по правому краю регистра ЕАХ; строка bit_str не изменяется. Этот пример можно рассматривать как обратный тому, который мы только что привели в листинге 9.3. Методика извлечения битовой подстроки, если вы разобрались с программой вставки битовой строки, не должна вызвать у вас затруднений.

Листинг 9.4. Извлечение битовой строки

;prg_9_4.asm

masm

model small

stack 256

.data

bit_str dd llffffllh ;строка для извлечения

.code

main: ;точка входа в программу

mov ax,@data

mov ds.ax

xor ax,ax

.386 ;это обязательно

;левый край места извлечения циклически переместить к левому краю

;строки bit_str (сохранение левого контекста)

rol bit_str,8

mov ebx,bit_str подготовленную строку в ebx

shld eax,ebx,16 ;вставить извлекаемые 16 бит

;в регистр еах

ror bit_str,8 восстановить старшие 8 бит

exit: ;eax=0000ffff

mov ax,4c00h

int 21h

end main

Пересылка битов

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

bit_strl dd 0abcdefabh

bit_str2 dd 012345678h

Из этих строк получите строку

bit_str2 dd 0abcd34abh

examination/asm/question42.txt · Последние изменения: 2014/01/15 08:13 (внешнее изменение)