Учебная деятельность    

Двоичная арифметика

Современные процессоры семейства IA-32

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

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

Примеры:
00101110
2E
1000110100111001
8D39

hexdecoctbin
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

Обратный перевод выполняется аналогично.

В двоичной арифметике используются следующие операции:
  ПаскальСи
побитовое отрицание (НЕ) NOT~
побитовое "И" AND&
побитовое "ИЛИ" OR|
побитовое исключающее "ИЛИ" XOR^
сдвиг влево SHL<<
сдвиг вправо SHR>>

При побитовом отрицании в двоичном представлении числа каждый бит меняет значение на противоположное.

Примеры:
00101110
11010001
NOT $2E = $D1
1000110100111001
0111001011000110
NOT $8D39 = $72C6

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

Примеры:
00101110
00110111
00100110
$2E AND $37 = $26
1000110100111001
1010011001001100
1000010000001000
$8D39 AND $A64C = $8408

Побитовое "И" используется, чтобы определить значение определенного бита числа. В этом случае в качестве второго операнда (маски) выбирают число, в котором выставлен в 1 только интересующий разряд. В результате будет получен 0, если в исходном числе интересующий разряд был равен 0. Если интересующий разряд был равен 1, то результат выражения равен второму операнду.
xxxXxxxx
00010000
000X0000
a AND $10 = ?
xxxxXXXXxxxxxxxx
0000111100000000
0000XXXX00000000
b AND $0F00 = ?

Побитовое "И" используется, чтобы сбросить в 0 определенные биты числа, не меняя остальные. В этом случае в качестве второго операнда (маски) выбирают число, в котором все биты, кроме битов, соответствующих сбрасываемым, установлены в 1.
xxxxxXxx
11111011
xxxxx0xx
a := a AND $FD
xxxxxxxxXXxxxxxx
1111111100111111
xxxxxxxx00xxxxxx
b := b AND $FF3F

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

Примеры:
00101110
00110111
00111111
$2E OR $37 = $3F
1000110100111001
1010011001001100
1010111101111101
$8D39 OR $A64C = $AF7D

Побитовое "ИЛИ" используется, чтобы установить в 1 определенный бит числа, не меняя остальные. В этом случае в качестве второго операнда (маски) выбирают число, в котором выставлен в 1 только интересующий бит, а остальные сброшены.
Xxxxxxxx
10000000
1xxxxxxx
a := a OR $80
XXXxxxxxxxxxxxxx
1110000000000000
111xxxxxxxxxxxxx
b := b OR $E000

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

Примеры:
00101110
00110111
00011001
$2E XOR $37 = $19
1000110100111001
1010011001001100
0010101101110101
$8D39 XOR $A64C = $2D75

Побитовое исключающее "ИЛИ" используется, чтобы изменить определенный бит числа (инвертировать), не меняя остальные. В этом случае в качестве второго операнда (маски) выбирают число, в котором выставлен в 1 только интересующий бит, а остальные сброшены.
xxxxxxXx
00000010
xxxxxxYx
a := a XOR $02
xxxxxxxxxxxxXXXX
0000000000001111
xxxxxxxxxxxxYYYY
b := b XOR $000F

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

Примеры:
00101110
SHL 1
01011100
$2E SHL 1 = $5C
1000110100111001
SHL 3
0110100111001000
$8D39 SHL 3 = $69C8

Сдвиг влево используют, чтобы "собрать" многобайтное число из отдельных байтов. Например:
$78 + $56 SHL 8 + $34 SHL 16 + $12 SHL 24 = $12345678

Различают два типа побитовых сдвигов вправо: арифметический и логический. При арифметическом сдвиге вправо на 1 разряд в двоичной записи первого аргумента слева дублируется старший разряд (бит знака), а младший бит числа отбрасывается. При логическом сдвиге вправо на 1 разряд в двоичной записи первого аргумента слева добавляется 0, а младший бит числа отбрасывается. Второй аргумент операции сдвига задает, сколько раз необходимо проделать такую процедуру. Арифметический сдвиг вправо на n бит эквивалентен делению числа на 2n с учетом знака, а логический - беззнаковому делению. В Паскале используется логический сдвиг, а в Си - арифметический.

Примеры:
00101110
SHR 1
00010111
$2E SHR 1 = $17
1000110100111001
(логический) SHR 2
0010001101001110
$8D39 SHR 2 = $234E
1000110100111001
(арифметический) >> 2
1110001101001110
-29383 >> 2 = -7346

Совместно с побитовым "И" сдвиг вправо используют, чтобы "разобрать" многобайтное число на отдельные байты. Например:
$12345678 AND $000000FF = $78
$12345678 AND $0000FF00 SHR 8 = $56
$12345678 AND $00FF0000 SHR 16 = $34
$12345678 AND $FF000000 SHR 24 = $12