Перейти к содержимому

Как перевести число в биты

  • автор:

ПЕРЕВОД ЧИСЕЛ ИЗ ДВОИЧНОЙ СИСТЕМЫ В ДЕСЯТИЧНУЮ

Задача перевода чисел из двоичной системы счисления в десятичную чаще всего возникает уже при обратном преобразовании вычисленных либо обработанных компьютером значений в более понятные пользователю десятичные цифры. Алгоритм перевода двоичных чисел в десятичные достаточно прост (его иногда называют алгоритмом замещения):

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

Например, требуется перевести двоичное число 10110110 в десятичное. В этом числе 8 цифр и 8 разрядов ( разряды считаются, начиная с нулевого, которому соответствует младший бит). В соответствии с уже известным нам правилом представим его в виде суммы степеней с основанием 2:

101101102 = (1·2 7 )+(0·2 6 )+(1·2 5 )+(1·2 4 )+(0·2 3 )+(1·2 2 )+(1·2 1 )+(0·2 0 ) = 128+32+16+4+2 = 18210

Из этого примера видно, в частности, что десятичная система счисления более компактно отображает числа — 3 цифры (т.е. бита) вместо 8 цифр в двоичной системе счисления. Для вычислений «вручную» и решения примеров и контрольных заданий вам могут пригодиться таблицы степеней оснований изучаемых систем счисления (2, 8, 10, 16), приведенные в Приложении.

Как перевести число в биты

На аппаратном уровне вся информация в компьютере представляет последовательность электрических сигналов. Например, в какой-то определенной ячейке памяти может быть иметься сильное напряжение, или оно может быть очень слабым. Для описания состояния сигнала информатике используется термина бит . По сути бит является наименьшей единицей информации в компьютере. Бит может иметь значение 1 (есть сигнал, что обычно соответствует напряжению от 2 до 5 V) или 0 (сигнал отсутствует или слабый — обычно от 0 до 2 V).

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

Один бит может принимать два значения: 0 и 1. Два бита вместе могут принимать четыре значения: 00, 01, 10 и 11. Три бита могут принимать восемь значений: 000, 001, 010, 011, 100, 101, 110 и 111. Обобщая, группа из n битов может принимать 2 n значений. Таким образом, группа из 8 бит или 1 байт может представлять 2 8 , то есть 256 уникальных значений. Таким образом, вся информация в компьютере фактически представляет последовательность бит.

Двоичная система

Поскольку бит может иметь только два значения — 1 и 0, то для записи битов применяют двоичную систему исчисления. Вообще система исчисления представляет способ записи чисел. Например, в поседневной жизни мы пользуемся десятичной системой исчисления . Это значит, что основанием этой системы является число 10, а каждый символ числа может иметь 10 вариантов значений — от 0 до 9. В десятичной системе каждое число можно представить как сумму цифер чисел, умноженных на 10 в степени, соответствующей порядковому номеру цифры в этом числе (нумерация начинается с нуля). Например, стандартное число 123 можно представить следующим образом:

12310 = 1 * 102 + 2 * 101 + 3 * 100 = 100 + 20 + 3

Или возьмем другое десятичное число — 123,45

123,4510 = 1 * 102 + 2 * 101 + 3 * 100 + 4 * 10-1 + 5 * 10-2 = 100 + 20 + 3 + 0,4 + 0,05

В двоичной системе каждый символ числа может иметь только два значения — 1 и 0, например, число 1101. Чтобы перевести число из двоичной системы в десятичную умножаем значение каждого бита (1 или 0) на число 2 в степени, равной номеру бита (нумерация битов идет от нуля):

// перевод двоичного числа 1101 в десятичную систему 1 * 23 + 1 * 22 + 0 * 21 + 1 * 20 = 1 * 8 + 1 * 4 + 0 * 2 + 1 * 1 = 8 + 4 + 0 + 1 = 13

Перевод десятичного числа в двоичную систему выглядит несколько сложнее. Стандартный алгоритм преобразования подразумевает деление числа и результатов последующих делений на 2 и помещение остатков от деления в результат. Например, переведем десятичное число 13 в двоичную систему:

// перевод десятичного числа 13 в двоичную систему 13 / 2 = 6 // остаток 1 (13 - 6 *2 = 1) 6 / 2 = 3 // остаток 0 (6 - 3 *2 = 0) 3 / 2 = 1 // остаток 1 (3 - 1 *2 = 1) 1 / 2 = 0 // остаток 1 (1 - 0 *2 = 1)

Общий алгоритм состоит в последовательном делении числа и результатов деления на 2 и получение остатков, пока не дойдем до 0. Затем выстраиваем остатки в линию в обратном порядке и таким образом формируем двоичное представление числа. Конкретно в данном случае по шагам:

  1. Делим число 13 на 2. Результат деления — 6, остаток от деления — 1 (так как 13 — 6 *2 = 1)
  2. Далее делим результат предыдущей операции деления — число 6 на 2. Результат деления — 3, остаток от деления — 0
  3. Делим результат предыдущей операции деления — число 3 на 2. Результат деления — 1, остаток от деления — 1
  4. Делим результат предыдущей операции деления — число 1 на 2. Результат деления — 0, остаток от деления — 1
  5. Последний результат деления равен 0, поэтому завершаем процесс и выстраиваем остатки от операций делений, начиная с последнего — 1101

Шестнадцатиричная система

Если число большое, то запись двоичных чисел может быть довольно длинной и поэтому не очень удобной. Например, число 23410 в двоичной системе равно 111010102 . И для упрощения работы с двоичными числами применяется шестнадцатеричная система.

В шестнадцатеричной системе счисления двоичные числа разделены на группы по 4 бита. При 4 битах в группе количество возможных значений равно 24 или 16. Первым 10 из этих 16 чисел присваиваются цифры 0–9, а последним 6 — буквы A-F:

Двоичное число 11101010 можно представить более компактно, разбив его на две 4-битные группы (1110 и 1010) и записав их в виде шестнадцатеричных цифр EA .

Алгоритм перевода из шестнадцатеричной системы в десятичную и обратно тот же, что и для двоичной, только вместо 2 используется число 16. Например, шестнадцатеричное число E6 можно представить следующим образом:

e6 = e * 161 + 6 * 160 = 14 * 16 + 6 = 23010 (десятичная система) = 1110 01102 (двоичная система)

А чтобы получить из 10-тичного числа 16-ричное, делим число на 16 и получаем остатки:

// перевод десятичного числа 230 в шестнадцатеричную систему 230 / 16 = 14 // остаток 6 (230 - 16 * 14 = 230 - 224) 14 / 16 = 0 // остаток 14 или E в 16-й системе // результат 0xE6

Чтобы указать, что число шестнадцатеричное, перед ним указываются символы 0X или 0x , например, 0xE6

Стоит отметить, что 4 бита, которые соответствуют одной шестнадцатеричной цифре, называется nibble или полубайт(слог, тертрада)

При работе с разными системами счисления легко запутаться. Например, какую систему в реальности представляет число 1010 ? Оно может равным образом представлять и десятичную, и двоичную, и шестнадцатеричную. И чтобы указать, что число относится к определенной системе счисления, используют различные обозначения. Так, для указания, что число является двоичным, перед число обычно ставится префикс 0b :

0b1010 - двоичное число (в десятичной системе равно 10, а в шестнадцатеричной - A)

Чтобы указать, что число является шестнадцатеричным, перед число обычно ставится префикс 0x :

0x1010 - шестнадцатеричное число (в десятичной системе равно 4112, а в двоичной - 1000000010000)

Представление отрицательных чисел

Для представления отрицательных чисел обычно применяется two’s complement ( дополнение до 2 ). С точки зрения математики чтобы получить отрицательный аналог числа надо от 0 (нуля) вычесть это число. Например, для получения -1 надо произвести операцию 0 — 1 = -1 . С точки зрения архитектуры компьютера в качестве 0 выступает число 2 N . В данном случае степень N представляет количество битов в числе.

Например, наше число состоит из 8 бит (1 байт), наподобие 0000 0001 (1 в десятичной системе). И мы хотим получить число -1. Для этого выполняем следующую операцию:

28 - 1 = 256 - 1 = 255

Но 255 — это в десятичной системе. А как это будет выглядеть в двоичной системе:

28 - 1 = 10000 0000 - 0000 0001 = 1111 1111

Таким образом, для 8 битное отрицательное число -1 в двоичной системе будет представлять 1111 1111

Аналогичная операция в шестнадцатеричной системе:

28 - 1 = 0x100 - 1 = 0xFF

Если же мы выполним обратную операцию — к 1111 1111 прибавим изначальное число 0000 0001 , то мы получим степень двойки. Поэтому подобное представление отрицательных чисел и называется дополнение до 2-х.

Простой способ получить из положительного числа отрицательного и наборот (то есть фактически умножение на -1) заключается в том, чтобы инвертировать биты — биты 0 поменять на 1, а 1 на 0, и затем прибавить 1. Например, получим число -3. Для этого сначала возьмем двоичное представление числа 3:

310 = 0000 00112 
~0000 0011 = 1111 1100
1111 1100 + 1 = 1111 1101

Таким образом, число 1111 1101 является двоичным представлением числа -3, что в шестнадцатеричной системе аналогично 0xFD

Другой пример, число 1 в двоичной системе равно 0b0000001 . Чтобы получить число -1, сначала инвертируем биты:

~0000 0001 = 1111 1110

Далее прибавляем 1:

1111 1110 + 1 = 1111 1111

То есть число -1 в двоичной системе равно 1111 1111 или 0xFF (в шестнадцатеричной системе)

Подобным образом можно получить обратно число 1:

~1111 1111 = 0000 0000 0000 0000 + 1 = 0000 0001

Соответственно, в зависимости от того, какое именно это число — положительное или отрицательно, интерпретировать это число можно по разному. Например, если число 1111 1111 рассматривается как положительное, то в десятичной системе оно равно 255. Если же оно рассматривается как отрицательное, то в десятичной системе оно равно -1.

Таким образом, 8-битные числа со знаком охватывают диапазон от -128 до 127, а 8-битные числа без знака — от 0 до 255.

Инструкции

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

Код операции — это один байт, определяющий основную операцию инструкции. Например, инструкция, которая копирует в регистр RAX число 1, имеет опкод C7 в шестнадцатеричной форме или 11000111 в двоичной форме. В зависимости от инструкции, ее операндов опкод меняется. Например, инструкция, которая копирует в регистр EAX число 1, имеет опкод B8 в шестнадцатеричной форме или 10111000 в двоичной форме. К опкодам инструкций следует добавить коды/значения операндов — регистра и чисел.

Написание машинного кода вручную возможно, но излишне громоздко. На практике вместо опкодов применяются так называемые мнемоники — человекочитаемые названия инструкций. Например, инструкция, которая копирует в регистр некоторое значение, имеет мнемонику mov (от слова «move» — помещать, поместить). А чтобы скопировать в регистр RAX число 1, нам достаточно написано команду

mov rax, 1

А чтобы скопировать в регистр EAX число 1, нам достаточно написано команду

mov eax, 1

Это довольно удобнее, чем в бинарной форме вводить команды.

Программа состоит из набора подобных инструкций. Процессор запускает программы через цикл выборки-выполнения (fetch-execute cycle). Компьютер считывает по одной инструкции за раз. Для этого процессор обращается к специальному регистру — указателю команд (или регистр IP), который также называется программным счетчиком (или PC) и который хранит адрес инструкции для выполнения. По сути, компьютер выполняет бесконечный цикл следующих операций:

  1. Считывает инструкцию с адреса памяти, указанного указателем инструкции — регистром IP/PC
  2. Декодирует инструкцию (т. е. выясняет, что означает инструкция)
  3. Перемещает указатель инструкций (регистр IP/PC) к следующей инструкции
  4. Выполняет указанную инструкцию

Двоичная система счисления. Бит и байт. Сегментация памяти.

Вообще, как компьютер может хранить, например, слово «диск»? Главный принцип — намагничивание и размагничивание одной дорожки (назовем ее так). Одна микросхема памяти — это, грубо говоря, огромное количество дорожек. Сейчас попробуем разобраться. Например:

нуль будет обозначаться как 0000 (четыре нуля),

один 0001, два 0010,

(т.е. правую единицу заменяем на 0 и вторую устанавливаем в 1).

три 0011 четыре 0100 пять 0101 шесть 0110 семь 0111 восемь 1000 девять 1001

Уловили принцип? «0» и «1» — это т.н. биты. Один бит, как вы уже заметили, может быть нулем или единицей, т.е. размагничена или намагничена та или иная дорожка («0» и «1» это условное обозначение). Если еще присмотреться, то можно заметить, что каждый следующий установленный бит (начиная справа) увеличивает число в два раза: 0001 в нашем примере = 1; 0010 два; 0100 четыре; 1000 восемь и т.д. Это и есть т.н. двоичная форма представления данных.

Т.о. чтобы обозначить числа от 0 до 9 нам нужно четыре бита (хоть они и не до конца использованы. Можно было бы продолжить: десять 1010, одиннадцать 1011 , пятнадцать 1111).

Компьютер хранит данные в памяти именно так. Для обозначения какого-нибудь символа (цифры, буквы, запятой, точки. ) в компьютере используется определенное количество бит. Компьютер «распознает» 256 (от 0 до 255) различных символов по их коду. Этого достаточно, чтобы вместить все цифры (0 — 9), буквы латинского алфавита (a — z, A — Z), русского (а — я, А — Я), а также другие символы. Для представления символа с максимально возможным кодом (255) нужно 8 бит. Эти 8 бит называются байтом. Т.о. один любой символ — это всегда 1 байт (см. рис. 1).

0 1 0 1 1 0 1 0
р н р н н р н р

Рис. 1. Один байт с кодом буквы Z

(буквы н и р обозначают: намагничено или размагничено соответственно)

Можно элементарно проверить. Создайте в текстовом редакторе файл с любым именем и запишите в нем один символ, например, «М» (но не нажимайте Enter!). Если вы посмотрите его размер, то файл будет равен 1 байту. Если ваш редактор позволяет смотреть файлы в шестнадцатеричном формате, то вы сможете узнать и код сохраненного вами символа. В данном случае буква «М» имеет код 4Dh в шестнадцатеричной системе, которую мы уже знаем или 1001101 в двоичной.

Т.о. слово «диск» будет занимать 4 байта или 4*8 = 32 бита. Как вы уже поняли, компьютер хранит в памяти не сами буквы этого слова, а последовательность «единичек» и «ноликов». «Почему же тогда на экране мы видим текст, а не «единички-нолики»? — спросите вы. Чтобы удовлетворить ваше любопытство, я забегу немного вперед и скажу, что всю работу по выводу самого символа на экран (а не битов) выполняет видеокарта (видеоадаптер), которая находится в вашем компьютере. И если бы ее не было, то мы, естественно, ничего бы не видели, что у нас творится на экране.

В Ассемблере после двоичного числа всегда должна стоять буква «b». Это нужно для того, чтобы при ассемблировании нашей программы Ассемблер смог отличать десятичные, шестнадцатеричные и двоичные числа. Например: 10 — это «десять», 10h — это «шестнадцать» а 10b — это «два» в десятичной системе.

Т.о. в регистры можно загружать двоичные, десятичные и шестнадцатеричные числа.

mov ax,20 mov bh,10100b mov cl,14h 

В результате в регистрах AX, BH и CL будет находится одно и тоже число, только загружаем мы его в разных системах. Компьютер же будет хранить его в двоичном формате (как в регистре BH).

Итак, подведем итог. В компьютере вся информация хранится в двоичном формате (двоичной системе) примерно в таком виде: 10101110 10010010 01111010 11100101 (естественно, без пробелов. Для удобства я разделили биты по группам). Восемь бит — это один байт. Один символ занимает один байт, т.е. восемь бит. По-моему, ничего сложного. Очень важно уяснить данную тему, так как мы будем постоянно пользоваться двоичной системой, и вам необходимо знать ее на «отлично».

Как перевести двоичное число в десятичное:

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

Возьмем число 20. В двоичной системе оно имеет следующий вид: 10100b

Итак (начнем слева направо, считая от 4 до 0; число в нулевой степени всегда равно единице (вспоминаем школьную программу по математике)):

10100b = 1*24 + 0*23 + 1*22 + 0*21 + 0*20 = 20 --------------------------------------------- 16+0+4+0+0 = 20

Как перевести десятичное число в двоичное:

Можно делить его на два, записывая остаток справа налево:

20/2 = 10, остаток 0 10/2=5, остаток 0 5/2=2, остаток 1 2/2=1, остаток 0 1/2=0, остаток 1

В результате получаем: 10100b = 20

Как перевести шестнадцатеричное число в десятичное:

В шестнадцатеричной системе номер позиции цифры в числе соответствует степени, в которую надо возвести число 16:

8Ah = 8*16 + 10 (0Ah) = 138

В настоящий момент есть множество калькуляторов, которые могут считать и переводить числа в разных системах счисления. Например, калькулятор Windows, который должен быть в инженерном виде. Очень удобен калькулятор и в DOS Navigator’е. Если у вас есть он, то отпадает необходимость в ручном переводе одной системы в другую, что, естественно, упростит вам работу. Однако, знать этот принцип крайне важно!

Сегментация памяти в DOS.

Возьмем следующее предложение: «Изучаем сегменты памяти». Теперь давайте посчитаем, на каком месте стоит буква «ы» в слове «сегменты» от начала предложения включая пробелы. На шестнадцатом. Подчеркну, что мы считали слово от начала предложения.

Теперь немного усложним задачу и разобьем предложение следующим образом (символом «_» обозначен пробел):

Пример N 1: 0000: Изучаем_ 0010: сегменты_ 0020: памяти 0030:

В слове «Изучаем» символ «И» стоит на нулевом месте; символ «з» на первом, «у» на втором и т.д. В данном случае мы считаем буквы начиная с нулевой позиции, используя два числа. Назовем их сегмент и смещение. Тогда, символ «ч» будет иметь следующий адрес: 0000:0003, т.е. сегмент 0000, смещение 0003. Проверьте.

В слове «сегменты» будем считать буквы начиная с десятой позиции, но с нулевого смещения. Тогда символ «н» будет иметь следующий адрес: 0010:0005, т.е. пятый символ начиная с десятой позиции. 0010 — сегмент, 0005 смещение. Тоже проверьте.

В слове «память» считаем буквы начиная с 0020 сегмента и также с нулевой позиции. Т.о. символ «а» будет иметь аодрес 0020:0001, т.е. сегмент 0020, смещение 0001. Опять проверим.

Итак, мы выяснили, что для того, чтобы найти адрес нужного символа необходимо два числа: сегмент и смещение внутри этого сегмента. В Ассемблере сегменты хранятся в сегментных регистрах: CS, DS, ES, SS (см. предыдущий выпуск ), а смещения могут храниться в других (но не во всех).

Регистр CS служит для хранения сегмента кода программы (Code Segment — сегмент кода);

Регистр DS для хранения сегмента данных (Data Segment — сегмент данных);

Регистр SS для хранения сегмента стека (Stack Segment — сегмент стека);

Регистр ES дополнительный сегментный регистр, который может хранить любой другой сегмент (например, сегмент видеобуфера).

Пример N 2:

Давайте попробуем загрузить в пару регистров ES:DI сегмент и смещение буквы «м» в слове «памяти» из примера N 1 (см. выше). Вот как это запишется на Ассемблере:

(1) mov ax,0020 (2) mov es,ax (3) mov di,2

Теперь в регистре ES находится сегмент с номером 20, а регистре DI смещение к букве «м» в слове «памяти». Проверьте, пожалуйста.

Здесь стоит отметить, что загрузка числа (т.е. какого-нибудь сегмента) напрямую в сегментый регистр запрещена. Поэтому мы в строке (1) загрузили сегмент в AX, а в строке (2) загрузили в регистр ES число 20, которое находилось в регистре AX:

mov ds,15 ---> ошибка! mov ss,34h ---> ошибка!

Когда мы загружаем программу в память, она автоматически располагается в первом свободном сегменте. В файлах типа *.com все сегментные регистры автоматически инициализируются для этого сегмента (устанавливаются значения равные тому сегменту, в который загружена программа). Это можно проверить при помощи отладчика. Если, например, мы загружаем программу типа *.com в память, и компьютер находит первый свободный сегмент с номером 5674h, то сегментные регистры будут иметь следующие значения:

CS = 5674h DS = 5674h SS = 5674h ES = 5674h

Код программы типа *.com должны начинаться со смещения 100h. Для этого мы, собственно, и ставили в наших прошлых примерах программ оператор org 100h, указывая Ассемблеру при ассемблировании использовать смещение 100h от начала сегмента, в который загружена наша программа (позже мы рассмотрим для чего это нужно). Сегментные же регистры, как я уже говорил, автоматически принимают значение того сегмента, в который загрузилась наша программа.

Пара регистров CS:IP задает текущий адрес кода. Теперь рассмотрим, как все это происходит на конкретном примере:

Пример N 3.

(1) CSEG segment (2) org 100h (3) _start: (4) mov ah,9 (5) mov dx,offset My_name (6) int 21h (7) int 20h (8) My_name db 'Oleg$' (9) CSEG ends (10) end _start

Итак, строки (1) и (8) описывают сегмент: CSEG (даем имя сегменту) segment (оператор Ассемблера, указывающий, что имя CSEG — это название сегмента); CSEG ends (end segment — конец сегмента) указывает Ассемблеру на конец сегмента.

Строка (2) сообщает, что код программы (как и смещения внутри сегмента CSEG) необходимо отсчитывать с 100h. По этому адресу в память всегда загружаются программы типа *.com.

Запускаем программу из Примера N 3 в отладчике. Допустим, она загрузилась в свободный сегмент 1234h. Первая команда в строке (4) будет располагаться по такому адресу:

1234h:0100h (т.е. CS = 1234h, а IP = 0100h) (посмотрите в отладчике на регистры CS и IP).

Перейдем к следующей команде (в отладчике CodeView нажмите клавишу F8, в другом посмотрите какая клавиша нужна; будет написано что-то вроде «F8-Step»). Теперь вы видите, что изменились следующие регистры:

AX = 0900h (точнее, AH = 09h, а AL = 0, т.к. мы загрузили командой mov ah,9 число 9 в регистр AH, при этом не трогая AL. Если бы AL был равен, скажем, 15h, то после выполнения данной команды AX бы равнялся 0915h)

IP = 102h (т.е. указывает на адрес следующей команды. Из этого можно сделать вывод, что команда mov ah,9 занимает 2 байта: 102h — 100h = 2).

Следующая команда (нажимаем клавишу F8) изменяет регистры DX и IP. Теперь DX указывает на смещение нашей строки («Oleg$») относительно начала сегмента, т.е. 109h, а IP равняется 105h, т.е. адрес следующей команды. Нетрудно посчитать, что команда mov dx,offset My_name занимает 3 байта (105h — 102h = 3).

Обратите внимание, что в Ассемблере мы пишем:

mov dx,offset My_name

а в отладчике видим следующее:

mov dx,109 (109 — шестнадцатеричное число, но CodeView символ ‘h’ не ставит. Это надо иметь в виду).

Почему так происходит? Дело в том, что при ассемблировании программы, Ассемблер подставляет вместо offset My_name реальный адрес строки с именем My_name в памяти. Можно, конечно, записать сразу

mov dx,109h

Программа будет работать нормально. Но для этого нам нужно высчитать самим этот адрес. Попробуйте вставить следующие команды, начиная со строки (7) в примере N 3:

(7) int 20h (8) int 20h (9) My_name db 'Oleg$' (10) CSEG ends (11) end _start

Просто продублируем команду int 20h (хотя, как вы уже знаете, до строки (8) программа не дойдет).

Теперь ассемблируйте программу заново. Запускайте ее под отладчиком. Вы увидите, что в DX загружается не 109h, а другое число. Подумайте, почему так происходит. Это просто!

В окне «Memory» («Память») вы должны увидеть примерно такое:

1234:0000 CD 20 00 A0 00 9A F0 FE = .a. |N1_|_N2_| |_________N3__________| |N4_|

Позиция N1 (1234) — сегмент, в который загрузилась наша программа (может быть любым).

Позиция N2 (0000) — смещение в данном сегменте (сегмент и смещение отделяются двоеточием (:)).

Позиция N3 (CD 20 00 . F0 FE) — код в шестнадцатеричной системе, который располагается с адреса 1234:0000.

Позиция N4 (= .a.) — код в ASCII (ниже рассмотрим), соответствующий шестнадцатеричным числам с правой стороны.

В Позиции N2 (смещение) введите значение, которое находится в регистре DX после выполнения строки (5). После этого в Позиции N4 вы увидите строку «Oleg$», а в Позиции N3 — код символов «Oleg$» в шестнадцатеричной системе. Вот что загружается в DX! Это не что иное, как АДРЕС (смещенеие) нашей строки в сегменте!

Но вернемся. Итак, мы загрузили в DX адрес строки в сегменте, который мы назвали CSEG (строки (1) и (9) в Прмере N 3). Теперь переходим к следующей команде: int 21h. Вызываем прерывание DOS с функцией 9 (mov ah,9) и адресом строки в DX (mov dx,offset My_name).

Как я уже говорил раньше, для использования прерываний в программах, в AH заносится номер функции. Номера функций нужно запоминать.

Наше первое прерывание.

Функция 09h прерывания 21h выводит строку на экран, адрес которой указан в регистре DX.

Вообще, любая строка, состоящая из ASCII символов, называется ASCII-строка. ASCII символы — это символы от 0 до 255 в DOS, куда входят буквы русского и латинского алфавитов, цифры, знаки препинания и пр.

Изобразим это в таблице (так всегда теперь будем делать):

Функция 09h прерывания 21h — вывод строки символов на экран в текущую позицию курсора:

Вход: AH = 09h, DX = адрес ASCII-строки символов, заканчивающийся ‘$’

Выход: ничего

В поле «Вход» мы указываем, в какие регистры что загружать, а в поле «Выход» — что возвращает функция. Сравните эту таблицу с Примером N 3.

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

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

(1) CSEG segment (2) org 100h (3) _beg: (4) mov ax,0B800h (5) mov es,ax (6) mov di,0 (7) (8) mov ah,31 (9) mov al,1 (10) mov es:[di],ax (11) (12) mov ah,10h (13) int 16h (14) (15) int 20h (16) (17) CSEG ends (18) end _beg

Многие операторы вы уже знаете. Поэтому я буду объяснять только новые.

В данном примере мы используем вывод символа прямым отображением в видеобуфер.

В строках (4) и (5) загружаем в сегментный регистр ES число 0B800h, которое соответствует сегменту дисплея в текстовом режиме (запомните его!). В строке (6) загружаем в регистр DI нуль. Это будет смещение относительно сегмента 0B800h. В строках (8) и (9) в регистр AH заносится атрибут символа (31 — ярко-белый символ на синем фоне) и в AL — ASCII-код символа (01 — это рожица) соответственно.

В строке (10) заносим по адресу 0B800:0000h (т.е. первый символ в первой строке дисплея — верхний левый угол) атрибут и ASCII-код символа (31 и 01 соответственно) (сможете разобраться?).

Обратите внимание на запись регистров в строке (10). Скобки ( [ ] ) указывают на то, что надо загрузить число не в регистр, а по адресу, который содержится в регистре (в данном случае, как уже отмечалось, — это 0B800:0000h).

Можете поэксперементировать с данным примером. Только не меняйте строки (4) и (5). Сегментный регистр должен быть ES (можно, конечно, и DS, но тогда надо быть осторожным). Более подробно данный метод рассмотрим позже. Сейчас нам из него нужно понять принцип сегментации на практике.

Следует отметить, что вывод символа прямым отображением в видеобуфер является самым быстрым. Выполнение команды в строке (10) занимает 3 — 5 тактов. Т.о. на Pentium-100Mhz можно за секунду вывести 20 миллионов(!) символов или чуть меньше точек на экран! Если бы все программисты (а особенно Microsoft) выводили бы символы или точки на экран методом прямого отображения в видеобуфер на Ассемблере, то программы бы работали чрезвычайно быстро. Я думаю, вы представляете.

Перевод чисел из одной системы счисления в любую другую онлайн

Вы ввели число:2710 в десятичной системе счисления и хотите перевести его в двоичную.

Переведем 2710 в двоичную систему вот так:

Целая часть числа находится делением на основание новой

27 2
-26 13 2
1 -12 6 2
1 -6 3 2
0 -2 1
1
Перевод чисел из одной системы счисления в другую

Постоянная ссылка на результат этого расчета

  1. Введите число которое надо перевести.
  2. Укажите его систему счисления.
  3. Укажите в какую систему счисления переводить.
  4. Нажмите кнопку «Перевести».

Калькулятор перевода чисел имеет одно поле для ввода. В это поле необходимо ввести число которое Вы хотите перевести.

После этого Вам обязательно нужно указать в какой системе счисления Вы его ввели. Для этого под полем ввода есть графа «Его система счисления».

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

После нажмите кнопку «ПЕРЕВЕСТИ» и результат появится в соответствующем поле. Если Вы хотите получить подробный ход решения, то нажмите на соответствующую ссылку.

Научиться переводить число из одной системы счисления в другую очень просто.

Любое число может быть легко переведено в десятичную систему по следующему алгоритму:

Каждая цифра числа должна быть умножена на основание системы счисления этого числа возведенное в степень равное позиции текущей цифры в числе справа налево, причём счёт начинается с 0.

Последние 20 расчетов на этом калькуляторе

  1. Перевод 0.E66 из шестнадцатиричной в десятичную CC Выполнен: 2024-01-07 01:07 МСК
  2. Перевод 0.E14 из шестнадцатиричной в десятичную CC Выполнен: 2023-12-28 19:35 МСК
  3. Перевод 0.000 из десятичной в двоичную CC Выполнен: 2023-12-25 23:30 МСК
  4. Перевод 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101 из двоичной в десятичную CC Выполнен: 2023-12-22 11:38 МСК
  5. Перевод 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101 из двоичной в десятичную CC Выполнен: 2023-12-22 11:35 МСК
  6. Перевод 0.E00000 из шестнадцатиричной в двоичную CC Выполнен: 2023-12-13 10:55 МСК
  7. Перевод 0.0 из 1-ричной в десятичную CC Выполнен: 2023-12-12 20:35 МСК
  8. Перевод 0.E08 из шестнадцатиричной в десятичную CC Выполнен: 2023-12-09 18:08 МСК
  9. Перевод 0.0E16 из шестнадцатиричной в десятичную CC Выполнен: 2023-12-06 14:21 МСК
  10. Перевод 0. из восьмеричной в двоичную CC Выполнен: 2023-11-29 02:42 МСК
  11. Перевод 0.E07 из шестнадцатиричной в 5-ричную CC Выполнен: 2023-11-27 13:17 МСК
  12. Перевод 0.0 из шестнадцатиричной в двоичную CC Выполнен: 2023-11-24 12:03 МСК
  13. Перевод 0.e10 из шестнадцатиричной в десятичную CC Выполнен: 2023-11-19 14:46 МСК
  14. Перевод 0.0E17 из шестнадцатиричной в двоичную CC Выполнен: 2023-11-13 14:38 МСК
  15. Перевод 0.000 из десятичной в восьмеричную CC Выполнен: 2023-11-06 20:48 МСК
  16. Перевод 0.E16 из шестнадцатиричной в десятичную CC Выполнен: 2023-11-01 21:36 МСК
  17. Перевод 0.00000000000000000 из двоичной в десятичную CC Выполнен: 2023-10-30 15:34 МСК
  18. Перевод 0.0E56042 из шестнадцатиричной в двоичную CC Выполнен: 2023-10-30 08:25 МСК
  19. Перевод 0.0000000 из двоичной в десятичную CC Выполнен: 2023-10-27 11:48 МСК
  20. Перевод 0000000.0 из двоичной в десятичную CC Выполнен: 2023-10-20 20:46 МСК

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *