Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум по ВМСиС.doc
Скачиваний:
25
Добавлен:
05.06.2015
Размер:
2.31 Mб
Скачать

Содержание отчета

Для защиты лабораторной работы каждым студентом должен быть написан отчет о лабораторной работе, оформленный в отдельной тетради для лабораторных работ по курсу «Вычислительные машины, системы и сети», включающий тему, цель работы и содержащий следующие пункты:

  1. Общие сведения о системах счисления.

  2. Задание на занятие.

  3. Алгоритм работы программы (блок-схема или словесное описание).

  4. Листинг программы (смысловая часть).

  5. Ответ на контрольный вопрос.

Контрольные вопросы

  1. Что такое позиционная система счисления?

  2. Как можно записать общую формулу для представления чисел в двоичной системе счисления?

  3. Запишите общую формулу для представления чисел шестнадцатеричной системы счисления.

  4. Как переводить целое десятичное число в двоичную систему счисления?

  5. Как переводить целое шестнадцатеричное число в двоичную систему счисления?

  6. Правило перевода целого десятичного числа в шестнадцатеричную систему счисления.

  7. Как преобразовать двоичные и шестнадцатеричные дробные числа в десятичный вид?

  8. Чем ограничивается длина дробной части числа при переводе из десятичной системы в двоичную?

  9. Как связана длина дробной части десятичного числа и дробная часть шестнадцатеричного числа?

Задание на занятие

Запрограммировать один из способов преобразования вида чисел, написав программу на языке высокого уровня (Паскаль, Си).

Требования к программированию:

  • При написании программы нельзя использовать встроенные строки форматирования и стандартные процедуры преобразования вида чисел (itoa( ),pow(), (%x) и пр.)

  • Для ввода и вывода чисел можно использовать строковые переменные.

  • Длины целой и дробной частей в десятичном виде можно ограничить тремя знаками для каждой части.

  • Способ преобразования вида чиселдля программирования производится по следующим вариантам:

  1. двоичное число в шестнадцатеричное (целая и дробная часть)

  2. шестнадцатеричное число в двоичное (целая и дробная часть)

  3. целое десятичное число в двоичное (2йспособ)

  4. целое двоичное число в десятичное (2йспособ)

  5. целое десятичное число в шестнадцатеричное

  6. дробное десятичное число в дробное двоичное (без целой части)

  7. дробное двоичное число в дробное десятичное (1йспособ, без целой части)

  8. дробное двоичное число в дробное десятичное (2йспособ, без целой части)

Лабораторная работа №2

Побитовые операции

Продолжительность: 4 часа.

Цель: Изучение приемов установки, сброса и маскирования битов числа.

Основные сведения

Внутри компьютера числа, как и все остальные данные и команды, хранятся в двоичном виде. Минимальной единицей информации в компьютере является бит. Любой из битов может бытьустановлен (включен, то есть равен единице) илисброшен (выключен, то есть равен нулю).

Каждые восемь бит образуют байт. Одним байтом можно представить 28=256 различных значений от 000000002до 111111112. Несколько байт образуютслово, которое по длине обычно соответствует разрядности регистра данных процессора. Мы будет рассматривать 16-ти разрядные слова.

Группы бит. Отдельные биты внутри байта или слова могут нести определённую информацию. Например, информация в байте, отвечающем за цветовой атрибут текста, распределена следующим образом:

7

6

5

4

3

2

1

0

B

b

b

b

f

f

f

f

  • ffff = 4-битный цвет символов (от 0 до 0xF)

  • bbb = 3-битный цвет фона (от 0 до 7)

  • B = бит мерцания (или бит интенсивности)

Наборы битов ffff,bbbиBназываютсяполями.

Поля цвета имеют побитовое смысловое значение: RGB, то есть младший бит отвечает за синий (Blue) цвет, средний бит – зеленый (Green) а старший бит – красный (Red). Наличие установленных битов в разных цветахRGBдаёт соответствующую смесь цветов [2]. Для четырёхбитного поляffffсамый старший бит отвечает за интенсивность цвета (см. Табл. 2.1.)

Таблица 2.1. Коды цветов.

Инт./ мерц.

R

G

B

Значение байта цвета

Цвет (интенсивный/мигающий)

0

0

0

0

0

Черный

0

0

0

1

1

Синий

0

0

1

0

2

Зеленый

0

0

1

1

3

Бирюзовый

0

1

0

0

4

Красный

0

1

0

1

5

Малиновый

0

1

1

0

6

Коричневый

0

1

1

1

7

Светло-серый

1

0

0

0

8

Темно-серый /Черный

1

0

0

1

9

Ярко-синий /Синий

1

0

1

0

A

Ярко-зеленый /Зеленый

1

0

1

1

B

Ярко-бирюзовый /Бирюзовый

1

1

0

0

C

Ярко-красный /Красный

1

1

0

1

D

Ярко-малиновый /Малиновый

1

1

1

0

E

Желтый /Коричневый

1

1

1

1

F

Белый /Светло-серый

В языке Си для изменения цветового атрибута текста служит стандартная функция textattr(CONIO.h):void textattr(int newattr).

Следует отметить, что стандартные функции вывода на стандартное устройство не реагируют на изменение атрибута цвета [3]. Для вывода цветного текста следует использовать стандартные функциивывода в текстовое окно, например,cprintf(CONIO.h).

Пример 2.1 На синем фоне жёлтыми буквами вывести фразу "Hello, world!".

#include <conio.h>

#include <stdio.h>

void main()

{ clrscr(); //очистка экрана

textattr(0x1E); //установка цветов фона и символов

printf("Это печать стандартного устройства");

printf("\nА это печать в текстовое окно:");

cprintf("\n\rHello, world!");

getch(); //ожидание нажатия клавиши

}

Функция cprintf()в отличие отprintf()выводит управляющую комбинацию\n(перевод строки) просто как перевод строки. Для привычного начала новой строки в функцииcprintf()следует дополнительно применять еще одну управляющую комбинацию\r (возврат каретки).

Команда textattr(0x1E)устанавливает цвет символов – жёлтый на синем фоне. В данной команде мы использовали шестнадцатеричное представление чисел с той целью, чтобы было легче определить цвет фона и цвет символа. Но результат выполнения команды не изменится, если мы будем использовать десятичные числа:textattr(30).

Для того чтобы задать цвет символа и фона с помощью переменных, можно использовать операцию побитового сдвига влево на четыре бита (пример 2.2), что соответствует умножению на . Таким способом переменнаяпомещается в поле цвета символов, а переменнаяв поле цвета фона.

Пример 2.2 Задать цвет фона и символа с клавиатуры и вывести фразу "Hello, world!" на языке Си.

#include <conio.h>

#include <stdio.h>

int i,j;

void main()

{ clrscr(); //очистка экрана

printf("Введите цвет фона: ");

scanf("%d",&i); //чтение цвета фона

printf("Введите цвет символов: ");

scanf("%d",&j); //чтение цвета символов

textattr(j+(i<<4)); //установка цветовых атрибутов

cprintf("\n\rHello, world!"); //вывод фразы на экран

getch(); //ожидание нажатия клавиши

}

Чтобы задать ярко-синий фон для выводимого текста, недостаточно одной команды textattr(0x9E). По умолчанию эта команда даёт в результате мигающие жёлтые символы на синем фоне. Для переключениярежима интенсивность/мерцаниеиспользуется прерываниеBIOS10h, функция 10h, подфункция 3. Если регистрbl=0, то включаетсярежим интенсивного цвета фона:

asm { mov ax, 1003h

mov bl, 0

int 10h}

В случае bl=1 – включаетсярежим мерцания символов:

asm { mov ax, 1003h

mov bl, 1

int 10h}

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

Более подробно рассматривать вызов прерываний и регистры процессора мы будем на лабораторном занятии №6.

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

Операция, при которой изменяется только часть байта, а остальные биты остаются неизменными, называется маскированием.Установкой бита называется присваивание ему значения единица.Сбросом бита называется присваивание ему значения нуль.Инвертирование бита означает изменение его значения на противоположное (в двоичной системе счисления значения 0 и 1 являются противоположными).

Маской называется байт, в котором установлены биты, соответствующие битам измененяемого байта. Если значения всех битов в маске инвертированы, то маска называетсяинвертированной.

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

Таблица 2.2. Описание побитовых операторов.

Оператор языка Си

Описание операторов

&

и

^

исключающее или

|

или

~

не (отрицание)

>> k

побитовый сдвиг на k бит вправо

<< k

побитовый сдвиг на k бит влево

Таблица 2.3. Значения побитовых операторов.

Аргументы

Значения функций

0

0

0

0

0

1

0

1

0

1

1

1

1

0

0

1

1

0

1

1

1

0

1

0

Для установкибитов в байте (или слове) применяется следующая последовательность действий:

  1. Создаётся маска на изменяемые биты.

  2. Маска накладывается на байт (слово) с помощью операции "или".

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

Пример 2.3 Установить седьмой бит в числе а.

Для установки седьмого бита используем выражение a |= 0x80 (тоже самое, что a = a | 0x80). В таблице 3.4 показано формирование маски и накладывание на исходный байт с помощью оператора | "или".

Таблица 2.4. Установка седьмого бита

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Пример исходного байта (a)

0 0 1 1 0 0 1 0

3 2

Маска

1 0 0 0 0 0 0 0

8 0

Результат операции "или"

1 0 1 1 0 0 1 0

B 2

Чтобы установить группу битв байте (или слове), необходимо сложить маски для изменяемых бит или определить одну общую маску на все изменяемые биты, а затем накладывается на искомый байт (слово) с помощью операции "или".

Пример 2.4 Установка седьмого, четвёртого и третьего бита в числе а.

Для изменения указанных битов используем выражение a |= 0x98 (a = a | 0x98). Как формируется маска, можно посмотреть в таблице 2.5.

Таблица 2.5. Установка группы бит.

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Исходный байт (a)

0 0 1 1 0 0 1 0

3 2

Маска на седьмой бит

1 0 0 0 0 0 0 0

8 0

Маска на четвёртый бит

0 0 0 1 0 0 0 0

1 0

Маска на третий бит

0 0 0 0 1 0 0 0

0 8

Сумма масок или общая маска на 7, 4 и 3

1 0 0 1 1 0 0 0

9 8

Результат операции "или"

1 0 1 1 1 0 1 0

DA

Для сбросабитов в байте (или слове) применяется следующая последовательность действий:

  1. Создаётся маска на изменяемые биты.

  2. Маска инвертируется.

  3. Инвертированная маска накладывается на байт (слово) с помощью команды "и".

Пример 2.5 Сброс седьмого бита в числе а.

Для сброса седьмого бита используем выражение a &= ~0x80. Как формируется маска и результат операции можно посмотреть в таблице 2.6.

Таблица 2.6. Сброс седьмого бита.

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Исходный байт (a)

1 0 1 1 0 0 1 0

B 2

Маска

1 0 0 0 0 0 0 0

8 0

Инвертированная маска

0 1 1 1 1 1 1 1

7 F

Результат операции "и"

0 0 1 1 0 0 1 0

3 2

Чтобы сбросить группу битв байте (или слове), необходимо сложить маски для изменяемых бит или определить одну общую маску на изменяемые биты, затем общая маска инвертируется и накладывается на искомый байт (слово) с помощью операции "и".

Пример 2.6 Сброс седьмого, шестого и первого бита в числе а.

Для изменения указанных битов используем выражение a &= ~ 0x3D. Как формируются маски и результат операции можно посмотреть в таблице 2.7.

Таблица 2.7. Сброс группы бит.

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Исходный байт (a)

0 0 1 1 0 0 1 0

3 2

Маска на седьмой бит

1 0 0 0 0 0 0 0

8 0

Маска на шестой бит

0 1 0 0 0 0 0 0

4 0

Маска на первый бит

0 0 0 0 0 0 1 0

0 2

Сумма масок или общая маска на 7, 6 и 1

1 1 0 0 0 0 1 0

С 2

Инвертированная общая маска

0 0 1 1 1 1 0 1

3 D

Результат операции "и"

0 0 1 1 0 0 0 0

3 0

Для инвертированиябитов в байте (или слове) применяется следующая последовательность действий:

  1. Создаётся маска на инвертируемые биты.

  2. Маска накладывается на байт (слово) с помощью команды "исключающее или".

Пример 2.7 Инвертирование шестого и седьмого бита в числе а.

Для инвертирования указанных битов используем выражение a ^= 0xC0. Как формируются маски и результат операции можно посмотреть в таблице 2.8.

Таблица 2.8. Инвертирование группы бит:

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Исходный байт (a)

1 0 1 1 0 0 1 0

B 2

Маска

1 1 0 0 0 0 0 0

C 0

Результат операции "искл. или"

0 1 1 1 0 0 1 0

7 2

Определение одного или группы бит. Для того чтобы считать один или группу бит из байта (слова), необходимо сбросить ненужные разряды и выделенную группу бит сдвинуть вправо до нулевого разряда.

Пример 2.8 Определение значения пятого бита числа а.

Для определения значения указанных битов используем выражение bit5 = (a & 0x20) >> 5. Как формируется маска и результат операции можно посмотреть в таблице 2.9.

Таблица 2.9. Определение значения пятого бита.

Номера разрядов

Основание

2

16

7 6 5 4 3 2 1 0

1 0

Исходный байт (a)

1 0 1 1 0 0 1 0

B 2

Маска

0 0 1 0 0 0 0 0

2 0

Результат операции "и"

0 0 1 0 0 0 0 0

2 0

Результат операции >> 5

0 0 0 0 0 0 0 1

0 1

Обратите внимание на то, что значение переменной bit5 (unsigned char bit5) всегда будет, в зависимости от значения переменной a, либо нулем, либо единицей.

Для получения значений трёх разрядов подряд, например, 5, 4 и 3 бит, можно совершать аналогичные операции. Но результатом может оказаться значение от 0 до 7, что опять потребует расшифровки по разрядам. Поэтому желательно значения в группе бит определять поразрядно: для пятого, четвёртого и третьего бита отдельно, а результат сохранять не в отдельных переменных, а в массиве bit (unsignedcharbit[8]):

Пример 2.9 Определение пятого бита числа а.

bit[5] = (a&0x20)>>5, или bit[5] = (a>>5)&1

Пример 2.10 Определение четвёртого бита числа а.

bit[4] = (a&0x10)>>4, или bit[4] = (a>>4)&1

Пример 2.11Определение третьего бита числа а.

bit[3] = (a&8)>>3, или bit[3] = (a>>3)&1

Пример 2.12Определение k-того бита числа а в общем виде.

bit[k] = (a&(1<<k))>>k, или bit[k] = (a>>k)&1

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

Пример 2.13Вывод восьми бит числа а.

for (int i=7; i <=0; i--) printf( a>>i & 1)