3c780c88 (kx 2024-12-29 12:21:01 +0300 1) .\" Copyright 2024 Andrew V.Kosteltsev (kx@radix-linux.su)
3c780c88 (kx 2024-12-29 12:21:01 +0300 2) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300 3) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300 4) .TH shifts 3 "December 27, 2024" "libmpu" "LibMPU Programmer's Manual"
3c780c88 (kx 2024-12-29 12:21:01 +0300 5) .SH NAME
3c780c88 (kx 2024-12-29 12:21:01 +0300 6) \fBishl\fP, \fBishr\fP, \fBisal\fP, \fBisar\fP \- операции сдвига на один бит
3c780c88 (kx 2024-12-29 12:21:01 +0300 7) .SH SYNOPSIS
3c780c88 (kx 2024-12-29 12:21:01 +0300 8) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 9) .B #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 10) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 11) .BI "void ishl( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 12) .BI "void ishr( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 13) .BI "void isal( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 14) .BI "void isar( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 15) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 16) .SH DESCRIPTION
3c780c88 (kx 2024-12-29 12:21:01 +0300 17) Для операций сдвигов на один бит входным операндом служит переменная размером \fBnb\fP байт,
3c780c88 (kx 2024-12-29 12:21:01 +0300 18) находящаяся по адресу \fBa\fP, результат помещается в переменную того же размера,
3c780c88 (kx 2024-12-29 12:21:01 +0300 19) расположенную по адресу \fBc\fP. Пространства, занимаемые входной и выходной переменной
3c780c88 (kx 2024-12-29 12:21:01 +0300 20) в памяти могут пересекаться, как частично, так и полностью, что не влияет на правильность
3c780c88 (kx 2024-12-29 12:21:01 +0300 21) получаемого результата. Содержимое переменной, расположенной по адресу \fBa\fP останется
7ee94ee9 (kx 2024-12-30 20:56:27 +0300 22) неизменным, после выполнения операции, если занимаемое ею пространство не пересекается
3c780c88 (kx 2024-12-29 12:21:01 +0300 23) с пространством, занимаемым переменной \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300 24) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 25) При выполнениии операций сдвига, флаг переноса \fBC\fP всегда содержит значение последнего
3c780c88 (kx 2024-12-29 12:21:01 +0300 26) выдвинутого бита. Существуют следующие виды операций сдвига:
3c780c88 (kx 2024-12-29 12:21:01 +0300 27) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 28) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 29) SHL \- логический беззнаковый сдвиг влево на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300 30) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 31) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 32) SHR \- логический беззнаковый сдвиг вправо на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300 33) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 34) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 35) SAL \- арифметический сдвиг влево на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300 36) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 37) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 38) SAR \- арифметический сдвиг вправо на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300 39) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 40) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 41) Следующие таблицы иллюстрируют выполнение операций \fBishl\fP, \fBishr\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300 42) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 43) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 44) ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 45) │ SHL(<<): │ C │ значение операнда │ заполнение │
3c780c88 (kx 2024-12-29 12:21:01 +0300 46) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 47) │ до операции │ │ 10110111 │ 0 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 48) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 49) │ после операции │ 1 │ 01101110 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 50) └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 51)
3c780c88 (kx 2024-12-29 12:21:01 +0300 52) ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 53) │ SHR(>>): │ заполнение │ значение операнда │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300 54) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 55) │ до операции │ 0 │ 10110111 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 56) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 57) │ после операции │ │ 01011011 │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 58) └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 59) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 60) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 61) Из таблиц видно, что при любом логическом сдвиге на освободившееся место всегда задвигается 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300 62) Флаг переполнения \fBO\fP выставляется, если в результате операции операнд изменил знак.
3c780c88 (kx 2024-12-29 12:21:01 +0300 63) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 64) Операция арифметического сдвига влево \fBisal\fP действует аналогично операции \fBishl\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300 65) (также на пустое место справа задвигается 0). Операция арифметического сдвига вправо действует
3c780c88 (kx 2024-12-29 12:21:01 +0300 66) иначе: в освобождающуюся позицию слева копируется знаковый бит исходного операнда.
3c780c88 (kx 2024-12-29 12:21:01 +0300 67) Действие операций \fBisal\fP и \fBisar\fP показано с помощью следующих таблиц.
3c780c88 (kx 2024-12-29 12:21:01 +0300 68) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 69) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 70) ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 71) │ SAL(<<): │ C │ значение операнда │ заполнение │
3c780c88 (kx 2024-12-29 12:21:01 +0300 72) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 73) │ до операции │ │ 10110111 │ 0 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 74) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 75) │ после операции │ 1 │ 01101110 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 76) └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 77)
3c780c88 (kx 2024-12-29 12:21:01 +0300 78) ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 79) │ SAR(>>): │ заполнение │ значение операнда │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300 80) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 81) │ до операции │ sign(1) │ 10110111 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 82) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 83) │ после операции │ │ 11011011 │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 84) └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 85) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 86) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 87) Флаг переполнения при выполнении операции \fBisal\fP выставляется таким же образом, как
3c780c88 (kx 2024-12-29 12:21:01 +0300 88) и при операции \fBishl\fP. При выполнении операции \fBisar\fP, операнд не может изменить
3c780c88 (kx 2024-12-29 12:21:01 +0300 89) свой знак. Многократный сдвиг \fBisar\fP может, в конце концов, привести к потере значения,
3c780c88 (kx 2024-12-29 12:21:01 +0300 90) и положительное число задвинется в 0, а отрицательное в -1. По этому флаг переполнения \fBO\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300 91) для операции \fBisar\fP сбрасывается в 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300 92) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 93) При выполнении операций \fBisal\fP, \fBisar\fP, \fBishl\fP, \fBishr\fP, так же выставляются
3c780c88 (kx 2024-12-29 12:21:01 +0300 94) флаги четности \fBP\fP, знака \fBS\fP и нуля \fBZ\fP. Флаг переноса из младшей тетрады \fBA\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300 95) не определяется и просто сбрасывается в 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300 96) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 97) Сдвиг влево можно применять для удваивания чисел, а сдвиг вправо \- для деления на 2. Эти операции
3c780c88 (kx 2024-12-29 12:21:01 +0300 98) выполняются значительно быстрее, чем операции умножения и деления. Деление пополам нечетных чисел
3c780c88 (kx 2024-12-29 12:21:01 +0300 99) (например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливает флаг
3c780c88 (kx 2024-12-29 12:21:01 +0300 100) переноса \fBC\fP в 1. При этом \fBC\fP, фактически, содержит остаток от деления. Такое использование
3c780c88 (kx 2024-12-29 12:21:01 +0300 101) операций сдвига требует контроля за флагом переполнения \fBO\fP. Для простоты, рассмотрим контроль
3c780c88 (kx 2024-12-29 12:21:01 +0300 102) флагов на 4\-битных знаковых переменных:
3c780c88 (kx 2024-12-29 12:21:01 +0300 103) .SS Примеры с 4\-битными операндами:
3c780c88 (kx 2024-12-29 12:21:01 +0300 104) \fBУмножение на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 105) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 106) SAL(0111) = 7; результат = 1110 = -2, ошибка, должно быть 14, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 107) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 108) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 109) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 110) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 111) SHR(1000) = -8; результат = 0100 = 4, ошибка, должно быть -4, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 112) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 113) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 114) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 115) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 116) SAR(1000) = -8; результат = 1100 = -4, абсолютно точно, CF = 0, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 117) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 118) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 119) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 120) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 121) SAR(0111) = 7; результат = 0011 = 3, остаток 1 (см. флаг C), абсолютно точно, CF = 1, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 122) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 123) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 124) .SH EXAMPLES
3c780c88 (kx 2024-12-29 12:21:01 +0300 125) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 126) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 127) #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 128) #include <stdio.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 129)
3c780c88 (kx 2024-12-29 12:21:01 +0300 130) int main( void )
3c780c88 (kx 2024-12-29 12:21:01 +0300 131) {
3c780c88 (kx 2024-12-29 12:21:01 +0300 132) int rc = 0;
3c780c88 (kx 2024-12-29 12:21:01 +0300 133)
3c780c88 (kx 2024-12-29 12:21:01 +0300 134) __mpu_init();
3c780c88 (kx 2024-12-29 12:21:01 +0300 135) __mpu_extra_warnings = 1;
3c780c88 (kx 2024-12-29 12:21:01 +0300 136)
3c780c88 (kx 2024-12-29 12:21:01 +0300 137) {
1ca800d6 (kx 2024-12-29 20:12:16 +0300 138) mpu_int8_t c, a;
3c780c88 (kx 2024-12-29 12:21:01 +0300 139) int nb = NB_I8;
3c780c88 (kx 2024-12-29 12:21:01 +0300 140) __mpu_char8_t sc[32], sa[32];
3c780c88 (kx 2024-12-29 12:21:01 +0300 141)
3c780c88 (kx 2024-12-29 12:21:01 +0300 142) iatoi( a, "0b10110111", nb ); /* evaluate the A variable */
3c780c88 (kx 2024-12-29 12:21:01 +0300 143)
3c780c88 (kx 2024-12-29 12:21:01 +0300 144) ishl( c, a, nb );
3c780c88 (kx 2024-12-29 12:21:01 +0300 145) iitoa( sa, a, RADIX_BIN, LOWERCASE, nb ); /* convert A value to ASCII string SA */
3c780c88 (kx 2024-12-29 12:21:01 +0300 146) iitoa( sc, c, RADIX_BIN, LOWERCASE, nb ); /* convert C value to ASCII string SC */
e3f8685d (kx 2024-12-30 18:22:24 +0300 147) printf( "a = %s;\\n", sa ); /* c = 0b10110111; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 148) printf( "c = %s;\\n", sc ); /* c = 0b01101110; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 149) printf( "carry = %d;\\n", __mpu_gtc() ); /* Carry Flag */
e3f8685d (kx 2024-12-30 18:22:24 +0300 150) printf( "overflow = %d;\\n", __mpu_gto() ); /* Overflow Flag */
3c780c88 (kx 2024-12-29 12:21:01 +0300 151) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 152)
3c780c88 (kx 2024-12-29 12:21:01 +0300 153) __mpu_free_context();
3c780c88 (kx 2024-12-29 12:21:01 +0300 154)
3c780c88 (kx 2024-12-29 12:21:01 +0300 155) return( rc );
3c780c88 (kx 2024-12-29 12:21:01 +0300 156) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 157) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 158) .SH SEE ALSO
3c780c88 (kx 2024-12-29 12:21:01 +0300 159) .BR iadd(3),
3c780c88 (kx 2024-12-29 12:21:01 +0300 160) .BR isub(3),
41c271da (kx 2025-01-05 15:42:39 +0300 161) .BR iadc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 162) .BR isbb(3),
41c271da (kx 2025-01-05 15:42:39 +0300 163) .BR irol(3),
41c271da (kx 2025-01-05 15:42:39 +0300 164) .BR iror(3),
41c271da (kx 2025-01-05 15:42:39 +0300 165) .BR ircl(3),
41c271da (kx 2025-01-05 15:42:39 +0300 166) .BR ircr(3),
41c271da (kx 2025-01-05 15:42:39 +0300 167) .BR ishln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 168) .BR ishrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 169) .BR isaln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 170) .BR isarn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 171) .BR iroln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 172) .BR irorn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 173) .BR ircln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 174) .BR ircrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 175) .BR ineg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 176) .BR inot(3),
41c271da (kx 2025-01-05 15:42:39 +0300 177) .BR iand(3),
41c271da (kx 2025-01-05 15:42:39 +0300 178) .BR itest(3),
41c271da (kx 2025-01-05 15:42:39 +0300 179) .BR icmp(3),
41c271da (kx 2025-01-05 15:42:39 +0300 180) .BR ior(3),
41c271da (kx 2025-01-05 15:42:39 +0300 181) .BR ixor(3),
41c271da (kx 2025-01-05 15:42:39 +0300 182) .BR iinc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 183) .BR idec(3),
41c271da (kx 2025-01-05 15:42:39 +0300 184) .BR ixchg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 185) .BR icpy(3),
41c271da (kx 2025-01-05 15:42:39 +0300 186) .BR icvt(3),
41c271da (kx 2025-01-05 15:42:39 +0300 187) .BR imul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 188) .BR ismul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 189) .BR idiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 190) .BR isdiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 191) .BR iatoi(3),
41c271da (kx 2025-01-05 15:42:39 +0300 192) .BR iatoui(3),
41c271da (kx 2025-01-05 15:42:39 +0300 193) .BR iitoa(3),
41c271da (kx 2025-01-05 15:42:39 +0300 194) .BR iuitoa(3).