Перевод из шестнадцатеричного числа в десятичное ассемблер. Перевод десятичных чисел в шестнадцатиричное - Assembler. Резервация и инициализация переменных в памяти

1. Базовые системы счисления. Объявления данных в Ассемблере

Цель работы: ознакомление студентов с системами счисления – двоичной, восьмеричной, шестнадцатеричной; представлением данных в памяти компьютера, директивами выделения памяти.

Теоретическая часть

Наименьшая единица информации, которую можно сохранить в компьютере – это бит (eng. bit - bi nary digit ), т.е. 0 или 1. Бит – это атом информации, он не может быть разделен. Биты группируются по 8 и образуют байт. Информация, которой манипулирует компьютер – это строка бинарных чисел. Из 8 битов можно сформировать 256 комбинаций. Эти комбинации используются для того, чтобы закодировать большие и малые буквы, цифры, специальные символы.

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

1 Килобайт = 1 Кбайт = 2 10 байтов = 1024 байтам;

1 Мегабайт = 1 Мбайт = 2 20 байтов = 1024 Кбайтам;

1 Гигабайт = 1 Гбайт = 2 30 байтов = 1024 Мбайтам.

Системы счисления

Система счисления – это множество правил и цифр представления чисел. Для любой позиционной системы счисления число цифр для представления равно основанию системы счисления, например, для двоичной системы основанием является число 2, следовательно, для представления чисел нужны две цифры 0 и 1, для шестнадцатеричной системы счисления это 0, 1, 2, …, 9, A, B, C, D, E, F, где буквы соответствуют значениям 10, 11, 12, 13, 14 и 15 соответственно.

Чтобы различать системы счисления, в конце числа ставится буква: B – для двоичного числа, Q – для восьмеричного числа, D – для десятеричного числа и H – для шестнадцатеричного. Для десятеричного числа указывать D не обязательно.

Если число записано в b–ричной системе счисления в виде

Nr(b) = C n C n-1 C n-2 … C 2 C 1 C 0 , D 1 D 2 D 3 … ,

то в десятеричной системе счисления его значение можно представить в виде суммы цифр, умноженных на основание системы счисления в степени равной номеру позиции цифры в числе (нумерация начинается с 0, справа налево):

Nr(10) = C n *b n +C n-1 *b n-1 +…+C 2 *b 2 +C 1 *b 1 +C 0 *b 0 +D 1 *b -1 +D 2 *b –2 +D 3 *b –3 +...

Например:

Пусть даны два бинарных числа 11b, 1100011b. Переведем эти числа в десятеричную систему счисления:

11b =1*2 1 +1*2 0 =3;

11100011b = 1*2 7 +1*2 6 +1*2 5 +0*2 4 +0*2 3 +0*2 2 +1*2 1 +1*2 0 = 227.

Рассмотрим примеры перевода восьмеричного числа в десятичную систему счисления:

11q = 1*8 1 +1*8 0 = 9;

210q =2*8 2 +1*8 1 +0*8 0 =136.

Пример перевода шестнадцатеричных чисел в десятичные:

11h = 1*16 1 +1*16 0 =17;

CA0h= C*16 2 +A*16 1 +0*16 0 = 3232

Для перевода чисел из десятичной системы в двоичную или шестнадцатеричную применяется целое деление. Число делится на основание системы счисления пока не получится неделимый остаток. Полученное от деления частное снова делится и процесс завершается, когда частное тоже становится неделимым. Полученные при делении остатки записываются в обратном порядке. На схеме показан перевод числа 25 в двоичную систему счисления, в результате которого получаем число 11001b, а также перевод числа 418 в шестнадцатеричную систему счисления, в результате которого получаем число 1A2h, учитывая, что цифра десять - это A.

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

Таблица соответствия шестнадцатеричных цифр и двоичных чисел.

Например, переведем число 1FDh в двоичное представление:

1FDh = 0001-1111-1101b = 111111101b

Переведем двоичное число 1110100101b в шестнадцатеричное представление: 0011-1010-0101b = 3A5.

Представление целых чисел в памяти компьютера

Для представления информации на компьютере используют двоичную систему счисления. Для хранения целых чисел используется строго фиксированное число битов: 8, 16, 32, 64. На n бинарных позиций можно записать целое число со знаком в диапазоне от -2 n-1 до 2 n-1 -1. Позиции нумеруются от 0 до n-1 справа налево. Например, число 67 в восьми двоичных позициях будет представлено как 01000011b. Числа без знака можно представить в диапазоне 0 до 2 n -1.

Целое число может храниться в виде прямого или дополнительного кода. Для представления знака числа используется бит, называемый знаковым. Он находится в позиции n-1 и является старшим битом числа. Для положительных чисел этот бит равен нулю, для отрицательных – единице.

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

Дополнительный код используется для хранения отрицательных чисел. Для получения представления числа в дополнительном коде сначала находится прямой код модуля числа, затем его обратный код. Обратный код получается инверсией каждого разряда в двоичном представлении числа: 0 преобразуется в 1, а 1 – в 0. На последнем шаге к обратному коду прибавляется 1.

Например, для представления числа -65 имеем:

01000001b прямой код числа +65

10111110b обратный код

10111111b дополнительный код числа -65

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

Типы данных

BYTE . Этот тип данных занимает 1 байт (8 битов). При помощи этого типа можно зашифровать целое число со знаком в диапазоне от -128 до +127 или без знака в диапазоне от 0 до 255, любой ASCII–символ, который также кодируется целым числом. Директива определения – DB (Define Byte).

WORD . Этот тип данных занимает 2 байта (16 битов). В переменную данного типа можно поместить целое число в диапазоне от -32768 до+32767 или от 0 до 65535, два ASCII–символа или относительный адрес памяти типа near. При этом запись в память производится следующим образом: младшая часть числа располагается по младшему адресу, а старшая – по старшему. Это справедливо и для других типов данных. Например, если целое шестнадцатеричное число 1234h расположено по адресу 1000h, то младшая часть 34h будет расположена по адресу 1000h, а 12h – по адресу 1001h. Директива определения – DW (Define word).

DWORD – 4 байта (2 слова) может вместить целое 32–битное число со знаком или без знака, число с плавающей точкой, 32–разрядный адрес памяти или 4 ASCII–символа. При хранении адреса адрес сегмента располагается в двух старших байтах, а смещение – в двух младших байтах памяти. Директива определения – DD (Define Double word).

QWORD – 8 байтов. Может быть целым знаковым или беззнаковым, числом или числом с плавающей точкой двойной точности. Директива определения – DQ (Define Quad).

T EN-BYTES – 10 байтов. Используется для хранения данных в основной памяти или в сопроцессоре. Может быть упакованным двоично–десятичным числом, расширенным целым числом или расширенным числом с плавающей точкой. Директива определения - DT (Define Ten bytes).

Общий синтаксис определения данных:

< имя > < тип > < список значений >

< имя > < тип > < число > dup (выражение ),

где имя – идентификатор, тип – одна из рассмотренных выше директив выделения памяти, список значений – список, который может содержать символьные или числовые константы. Он может также содержать символ ? , если значение не определено, или адрес – имя переменной или метку, строку ASCII–символов, заключенных в кавычки или апострофы. Директива dup предписывает повторение значений, определяемых выражением, заданное <число> раз. Выражение может быть константой, константами, объединенными знаками арифметических операций, списком значений или символом ? , если значение не определено.

Например,

var_a db 2 dup (0, 3 dup (1)) ; эквивалентно var_a db 0,1,1,1,0,1,1,1 var_b db 1, 2, 3, ?, ? adr_a dw var_a adr_b3 dd var_b+3

Определим размер памяти, выделенный под каждую из следующих переменных:

m1 db 4 , 5 , 1 , 6 ; 4*1=4 байта m2 db “xzyqw” ; 5*1=5 байтов m3 dw 12 dup(?) ; 12*2=24 байта m4 dd 345h , 234h ; 2*4=8 байтов

m1 db 4, 5, 1, 6 ; 4*1=4 байта m2 db “xzyqw” ; 5*1=5 байтов m3 dw 12 dup(?) ; 12*2=24 байта m4 dd 345h, 234h ; 2*4=8 байтов

Общее количество байтов, выделенных данными директивами, равно 41 байту. Переменная m1 располагается по относительному адресу 00h, m2 – 04h, m3 – 09h, а m4 – 021h.

Индивидуальные задания:

1. Перевести в двоичную, шестнадцатеричную и восьмеричную системы счисления десятеричные числа:

1)42;31;113 5 )46;35;119 9 ) 49;30;103 13 )29;37;97
2 )45;81;89 6)66;25;110 10 )19;53;101 14 )21;87;98
3 )12;38;118 7 )17;63; 96 11)34;50;107 1 5) 28;45;130
4 )11;43;67 8 )13;69;88 1 2 )14;70;99 16)15;72;100

2. Перевести в двоичную систему счисления шестнадцатеричные числа:

1)A45;12;56B 5)7C;72EB;31DB 9)34A;6AB;9AD 13)2B9;6F1;81B
2)1EF3;5AB;46F 6)3EB;4D8;A61 10)5AB;79F;AB8 14)7CD;2A1;B53
3)A56;5E9;CDE 7)6A3;9D0;8BE 11)9A;4DE;EF7 15)10B;87F;CD9
4)3B8;DE1;BAE 8)BC;7F9;78A 12)AB;8E4;C17 16)38E;9C7;B89

3. Перевести в восьмеричную и шестнадцатеричную системы счисления бинарные числа:

1) 00101011; 00100110;
01110011
5 ) 11110010; 01101010;
11111100;
9 ) 10000101; 11100010;
11001011
13 ) 00011101; 11111001;
00111101
2 ) 01100001; 01101110;
11110011
6) 00110110; 00111011;
10001100
10 ) 00011101; 01010110;
10110010
14 ) 00011100; 01001100;
01101110
3) 11100100; 01011100; 11000001 7 ) 11010010; 01001100; 11000111 11) 11100010; 10100001; 10001110 1 5 ) 10101001; 11010101; 111001100
4 ) 00001111; 10100101; 10010001 8 ) 11100000 11111000; 01000011 1 2 ) 10100101; 01101100; 11100001 16) 11100111; 01100101; 10110010;

4. Представить в дополнительном коде следующие числа:

1)-42;-31;-96 5)-46;-35;-94 9) -49;-30;-103 13)-29;-37;-97
2)-52;-41;-93 6)-66;-25;-85 10)-19;-53 ; -101 14)-21;-87;-98
3)-12;-38;-93 7)-17;-63;-99 11)-34;-50;-94 15)-28;-45;-95
4)-11;-43;-67 8)-13;-69;-88 12)-14;-70;-99 16)-15;-72;-89

5. Даны следующие определения переменных:

1) a db 45,16,76,-6
b db “abcd”
c dw 15 dup(0),3,3
d dd 345h
2) a dd 2,24
b db “aaa”,-8,23h,11101b
c db 6 dup(0), 45, 6
d dw -7,4Dh,8 dup(0)
3) a db “Salut”,10,13
b db -16,-20,13h,2 dup(0)
c dw 62,34,-15
d dd 456C9h,4567
4) a dd 92,45h,90,-54,-67
b db 10 dup(‘$’),10,13
c db “amdto”,10,13,’$’
d dw 5 dup(?),7,-80h
5) a db “lucrarea_1”,10,13
b db 2 dup(0)
c dw 38,-15,78,41,12
d dd 678EFh,3489,456
6) a db 12,24,”sss”
b db “ab”,-8,23h
c dd 6 dup(0),45
d dw -7,5 dup(0)
7) a db 35,53
b db 10 dup(‘ ’),10,13,“$”
c dw 5 dup(0)
d dd 555h
8) a db 34,6,3,-8,-2
b db “Hello”,‘$’
c dw 6 dup(0),‘$’,10,13
d dw -68,46h,7 dup(0)
9) a db 45,16
b db 5 dup(?),10,13,“$”
c dw 55 dup(0)
d dd 34567h
10) a db 76,87,92,45h
b db 20 dup(‘$’),10,13
c db “qwert”
d dw 10 dup(0)
11) a dd 78,34,67
b db “Rezultat”,‘$’
c db 16 dup(0),‘$’,10,13
12) a db 73,74,75,77,78,-67
b db 15 dup(‘?’),10,13
c dd 777h
13) a db 24,76,-56
b db “abc”,11101b
c dd 45,4 dup(?)
d dw 4 dup(0),8,3
14) a db “testul_nr_2”,13,10
b db -18,-22,18h,2 dup(0)
c dw 81,-16,44,18
d dd 568ABh
15) a dd 87,45h,-9
b db 10 dup(?)
c db “test_1$”
d dw 4 dup(0),2,7
16) a db “Matematica”,10,13
b db 10,20h,2 dup(0)
c dw 60,30,-10,-20,-50
d dd 56789Bh

a) определить, сколько байтов выделено данными директивами;
b) определить адреса, по которым располагается каждая из переменных.


Двоичная, восьмеричная, десятичная, шестнадцатеричная системы счисления относятся к позиционным. Позиционная система счисления - такая, в которой значение цифры зависит от ее положения в числе, положения цифр в числе называют порядками или разрядами. Основанием позиционной системы счисления является счет, при достижении которого заполняется следующий порядок числа. Иначе, основание системы счисления равно числу цифр, включая ноль, которыми записываются числа в этой системе.

Ассемблер допускает возможность использования чисел в двоичной, восьмеричной, десятичной или шестнадцатеричной системе. По умолчанию ассемблер считает все числа, встречающиеся в программе, десятичными. Явно указать на основание числа можно при помощи тэгов (для MASM32 11 версии): b или y - для двоичных чисел; o или q - для восьмеричных; d или t - для десятичных чисел; h - для шестнадцатеричных чисел. Тэг записывается в конце числа, слитно с числом. Если в числе используются буквенные символы (шестнадцатеричные числа), в начале записывают ноль - по правилам ассемблера обозначения чисел должны начинаться с цифры. Например:

.data var1 byte 00001111b ; 15 в двоичном представлении var2 byte 00001111y ; 15 в двоичном представлении var3 byte 17o ; 15 в восьмеричном представлении var4 byte 17q ; 15 в восьмеричном представлении var5 byte 15d ; 15 в десятичном представлении var6 byte 15t ; 15 в десятичном представлении var7 byte 0Fh ; 15 в шестнадцатеричном представлении

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

.RADIX (основание)

в которой основание счисления указывается десятичным числом. Например, по инструкции

.RADIX 16

Существование двух вариантов тэгов для двоичных и десятичных чисел вызвано соображениями совместимости ранних версий MASM32, в которых возможности записи чисел в шестнадцатеричном формате не было, с более поздними версиями. Для шестнадцатеричных чисел арабских цифр не хватает, поэтому цифровой ряд дополнен буквами:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

Легко видеть, что тэги из ранних версий MASM32 - b и d - совпадают с цифрами шестнадцатеричного числа, что делает невозможным их использование при директиве .RADIX 16 . Тег o дублирован тэгом q из-за схожести первого с нулем. По указанным причинам предпочтительными являются тэги y , q , t .

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

Перевод машинного числа в заданную систему счисления осуществляется последовательным делением этого числа и получающегося результата на основание искомой системы счисления. Остаток от деления заносится в младший разряд, частное снова делится на основание системы счисления, остаток заносится в следующий разряд - и так до достижения в результате деления нуля. Допустим, требуется перевести десятичное число 250 в шестнадцатеричное представление:
250 / 16 = 15 , остаток = A (10),
15 / 16 = 0, остаток = F (15),
таким образом, 250 (десятичное) = FA (шестнадцатеричное).

Максимальной число, которое может быть записано в байт, составляет 255. Если по результатам работы программы необходимо вывести на экран число в десятичном формате из однобайтовой переменной, следует это число делить на 10 не более, чем три раза - в 255 три десятичных порядка. В переменных типа word (два байта) максимальное значение составляет 65 535, в переменных типа double word (четыре байта) - 4 294 967 295. Соответственно, числа word для перевода в десятичный формат делим на 10 не более пяти раз, double word -не более десяти раз.

Кодами символов-цифр являются: "0" - 48; "1" - 49; "2" - 50; "3" - 51; "4" - 52; "5" - 53; "6" - 54; "7" - 55; "8" - 56; "9" - 57. Очевидно, что для перевода значения цифры в символьный вид достаточно прибавить к нему 48.

Фрагмент программы, который переводит байтовую переменную в десятичный символьный вид:

.data divider byte 10 ; делитель buffer_dec byte 3 dup (?) parametr byte 255 ... .code start: ... ; получим значения байта parametr в десятичном символьном виде mov AH, 0 ; обнуляем AH mov AL, parametr ; копируем байтовую переменную в AL DIV divider ; делим AX на 10 mov buffer_dec, AH ; копируем остаток от деления в buffer_dec mov AH, 0 ; обнуляем AH DIV divider ; делим AX на 10 mov buffer_dec, AH ; копируем остаток от деления в buffer_dec mov buffer_dec, AL ; копируем частное в buffer_dec ADD buffer_dec, 48 ; добавляем 48 - получаем символ цифры "2" ADD buffer_dec, 48 ; добавляем 48 - получаем символ цифры "5" ADD buffer_dec, 48 ; добавляем 48 - получаем символ цифры "5"

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

Шестнадцатеричная система счисления (также — шестнадцатеричный код) является позиционной системой счисления с целочисленным основанием 16. Иногда в литературе также используется термин hex (произносится «хекс», сокращение от англ. hexadecimal). Цифрами данной системы счисления принято использовать арабские цифры 0—9, а также первые символы латинского алфавита A—F. Буквы соответствуют следующим десятичным значениями:

  • * A —10;
  • * B —11;
  • * C —12;
  • * D —13;
  • * E — 14;
  • * F — 15.

Таким образом, десять арабских цифр вкупе с шестью латинскими буквами и составляют шестнадцать цифр системы.

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

Применение . Шестнадцатеричный код широко применяется в низкоуровневом программировании, а также в различных компьютерных справочных документах. Популярность системы обоснована архитектурными решениями современных компьютеров: в них в качестве минимальной единицы информации установлен байт (состоящий из восьми бит) — а значение байта удобно записывать с помощью двух шестнадцатеричных цифр. Значение байта может ранжироваться с #00 до #FF (от 0 до 255 в десятичной записи) — другими словами, используя шестнадцатеричный код , можно записать любое состояние байта, при этом не остаётся «лишних» не используемых в записи цифр.

В кодировке Юникод для записи номера символа используется четыре шестнадцатеричных цифры. Запись цвета стандарта RGB (Red, Green, Blue — красный, зелёный, синий) также часто использует шестнадцатеричный код (например, #FF0000 — запись ярко-красного цвета).

Способ записи шестнадцатеричного кода.

Математический способ записи . В математической записи основание системы записывают в десятичном виде в нижнем индексе справа от числа. Десятичную запись числа 3032 можно записать как 3032 10 , в шестнадцатеричной системе данное число будет иметь запись BD8 16 .

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

* В синтаксисе некоторых разновидностей языка ассемблера используется латинская буква «h», которая ставится справа от числа, например: 20Dh. Если число начинается с латинской буквы, то перед ним ставится ноль, например: 0A0Bh. Это сделано для того, чтобы отличать от констант значения, использующие шестнадцатеричный код ;

* В прочих разновидностях ассемблера, а также в Pascal (и его разновидностях, таких как Delphi) и некоторых диалектах Basic, применяют префикс «$»: $A15;

* В языке разметки HTML, а также в каскадных файлах CSS, для указания цвета в формате RGB с шестнадцатеричной системой записи, используется префикс «#»: #00DC00.

Как перевести шестнадцатеричный код в другую систему?

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

Двоичная СС

шестнадцатеричная СС

Например, требуется выполнить перевод шестнадцатеричного числа A14: в нём три цифры. Используя правило, запишем его в виде суммы степеней с основанием 16:

A14 16 = 10.16 2 + 1.16 1 + 4.16 0 = 10.256 + 1.16 + 4.1 = 2560 + 16 + 4 = 2580 10

Перевод чисел из двоичной в шестнадцатеричную систему и наоборот.

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

Таблица тетрад для перевода.

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

Двоичная СС

Восьмеричная СС

Пример перевода из шестнадцатеричной системы в двоичную : A5E 16 = 1010 0101 1110 = 101001011110 2

Пример перевода из двоичной системы в шестнадцатеричную : 111100111 2 = 0001 1110 0111 = 1E7 16

В этом примере количество цифр в исходном двоичном числе не было равным четырём (9), поэтому были добавлены незначащие нули — общее число цифр стало 12.

Автоматический перевод . Быстрый перевод из шестнадцатеричной системы счисления в одну из трёх популярных систем (двоичную, восьмеричную и десятичную), как и обратный перевод, можно выполнить, используя стандартный калькулятор из комплекта поставки ОС Windows. Откройте калькулятор, выберите в меню Вид -> Программист. В данном режиме можно устанавливать систему счисления, используемую в данный момент (см. меню слева: Hex, Dec, Oct, Bin). При этом изменение текущей системы счисления автоматически производит перевод.

Здравствуйте! Имеется такая строка:

Var BD 2,2,3,3,4,4; 223344 десятичное 6-ти значное число в распакованном формате с повышенной точностью (ASCII формат)

Как это число 223344 перевести в шестнадцатиричное число? Я нашел такой код, который переводит из однозначного и двузначного десятичного числа в шестнадцатизначное:

; Вар. 17. Зад. 1. Написать подпрограмму для преобразования некоторого массива десятичных; ASCII байтов. в массив BCD байтов. С помощью этой подпрограммы обработать два массива; Для передачи параметров использовать стек. Name Program ; Описание констант;Описание переменных Data segment x1 db 2h db 1h db 3h db 1h db 4h db 1h ; числа в ASCII-формате y1 db 3 dup (?) ; массив в BCD-формате x2 db 8h ;98 db 9h db 5h ;95 db 9h db 7h ;87 db 8h db 2h ;92 db 9h ; массив десятич. ASCII-байтов Y2 db 4 dup (?) ; массив десятич. BCD-байтов Data ends Stack SEGMENT DW 16 dup(?) StkTOp LABEL word Stack ends Code SEGMENT ASSUME CS: Code, DS: Data, ES: Data, SS: Stack ; Здесь описываются подпрограммы abc proc push bp mov bp, sp ; привязка к верхушке стека mov cx, ; чтение параметров из стека (кол-во чисел) mov di, ; адрес переменной Y1 mov si, ; адрес переменной Х1 M1: mov al, +1 ; загружаем первое число в ASCII-формате shl ax, 1 ; сдвигаем на 4 разряда в право shl ax, 1 shl ax ,1 shl ax, 1 or al, ;востонавливаем число которое запомнили mov , al ; записываем число в BCD-формате inc si ; переходим на другое число inc si inc di ; модифицируем адрес BCD - числа dec cx ; уменьшаем кол-во чисел jnz M1 ; если они не кончились то идем на M1 pop BP ret 6 abc endp ; Основная программа Start: mov AX, Data mov DS, AX mov ES, AX mov Ax, Stack mov SS, AX mov SP, offset StkTop ; загружаем параметры в стек по условию задачи mov ax, offset x1 ; загружаем адрес первого массива push ax mov ax, offset Y1 ; загружаем адрес результата push ax mov ax, 3 ; кол-во чисел push ax call abc ; вызов подпрограммы mov ax, offset x2 ; загружаем адрес второго массива push ax mov ax, offset Y2 ; загружаем адрес результата push ax mov ax, 4 ; кол-во чисел push ax call abc ; вызов подпрограммы code ends end start

Эта статья по большей части для совсем начинающих. Если вы хорошо разбираетесь в системах счисления, можете обратить внимание лишь на особенности синтаксиса ассемблера FASM в конце статьи.

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

Немного теории

Прежде всего разберёмся, в чём различие между системами счисления. Любое десятичное число можно представить в таком виде:

123 10 = 1·10 2 + 2·10 1 + 3·10 0

Индекс внизу обозначает, что это десятичное число. Цифра каждого разряда умножается на 10 в степени, равной номеру разряда, если считать с нуля справа налево. В более общем виде:

abc r = a·r 2 + b·r 1 + c·r 0 ,

где a, b и с — какие-то цифры, а r — основание системы счисления. Для десятичной системы r = 10, для двоичной — r = 2, для троичной r = 3 и т.д. Например, то же самое число в других системах:

443 5 = 4·5 2 + 4·5 1 + 3·5 0 = 4·25 + 4·5 + 3·1 = 123 10 (пятеричная система)

173 8 = 1·8 2 + 7·8 1 + 3·8 0 = 1·64 + 7·8 + 3·1 = 123 10 (восьмеричная система)

1111011 2 = 1·2 6 + 1·2 5 + 1·2 4 + 1·2 3 + 0·2 2 + 1·2 1 + 1·2 0 = 1·64 + 1·32 + 1·16 + 1·8 + 0·4 + 1·2 + 1·1 = 123 10 (двоичная система)

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

В шестнадцатеричной системе для обозначения цифр больше 9 используются буквы A = 10, B = 11, C = 12, D = 13, E = 14, F = 15. Например:

C7 16 = 12·16 1 + 7·16 0 = 12·16 + 7·1 = 199 10

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

Двоичная
тетрада
Шестнадцатеричная
цифра
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F

Для записи одного байта требуется всего 2 шестнадцатеричные цифры:

0101 1011 2 = 5B 16

0110 0000 2 = 60 16

1111 1111 2 = FF 16

Восьмеричная система

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

Двоичная
триада
Восьмеричная
цифра
000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7

Например: 001 110 101 2 = 165 8

Синтаксис ассемблера FASM

По умолчанию, число в программе воспринимается ассемблером как десятичное. Чтобы обозначить двоичное число, необходимо к нему в конце добавить символ ’b’ . Восьмеричное число обозначается аналогично с помощью символа ’o’ . Для записи шестнадцатеричного числа FASM поддерживает 3 формы записи:

  • перед числом записываются символы ’0x’ (как в C/C++);
  • перед числом записывается символ ’$’ (как в Pascal);
  • после числа записывается символ ’h’ . Если шестнадцатеричное число начинается с буквы, необходимо добавить в начале ноль (иначе непонятно, число это или имя метки).

Этот синтаксис используется как при объявлении данных, так и в командах. Вот примеры записи чисел во всех четырёх системах:

mov ax , 537 ;Десятичная система mov bl , 11010001b ;Двоичная система mov ch , 57o ;Восьмеричная система mov dl , $ C2 ;\ mov si , 0x013A ; \ mov ah , 18h ; / Шестнадцатеричная система mov al , 0FFh ;/ mov al , FFh ;Ошибка!

mov ax,537 ;Десятичная система mov bl,11010001b ;Двоичная система mov ch,57o ;Восьмеричная система mov dl,$C2 ;\ mov si,0x013A ; \ mov ah,18h ; / Шестнадцатеричная система mov al,0FFh ;/ mov al,FFh ;Ошибка!