Когда и как был создан ассемблер?
Это произошло ещё в сороковых годах прошлого века. Ассемблер был создан для первых ЭВМ на электронных лампах, программы для которых писали на машинном языке. А так как памяти у компьютеров было мало, то команды вводили, переключая тумблеры и нажимая кнопки. Даже несложные вычисления занимали много времени.
Проблему решили, когда ЭВМ научились хранить программы в памяти. Уже в 1950 году была разработана первая программа-транслятор, которая переводила в машинный код программы, написанные на понятном человеку языке. Эту программу назвали программой-сборщиком, а язык — языком ассемблера (от англ. assembler — сборщик).
ASCII-представление
В ASCII-представлении десятичные числа хранятся в виде строки ASCII-символов. Есть 4 инструкции для обработки чисел в ASCII-представлении:
AAA (англ. «Adjust After Addition») — настроить после добавления;
AAS (англ. «Adjust After Subtraction») — настроить после вычитания;
AAM (англ. «Adjust After Multiplication») — настроить после умножения;
AAD (англ. «Adjust After Division») — настроить после деления.
Эти инструкции не принимают никаких операндов и предполагают, что требуемый операнд находится в регистре AL .
В следующем примере мы будем использовать инструкцию AAS:
Результат выполнения программы:
The Result is: 6
ЗАДАЧА 1
Пусть в сегменте данных под символическим именем N хранится беззнаковое десятичное число (от 0 до 255). Необходимо записать по адресу KOD цифры (как символы) из десятичной записи числа.
РЕШЕНИЕ
Пусть N = abc , где a , b , c — десятичные цифры числа N .
Для получения правой цифры c надо взять остаток от деления N на 10. Неполное частное от деления — это число ab , ели его разделить на 10, то неполное частное даст цифру а, а остаток — цифру b .
Чтобы получить эти цифры как символы (их затем можно будет вывести на экран), следует к цифре прибавить код ‘0’ (30 h ).
mov ah ,0 ; расширение N в ax до слова (беззнаковое)
div bl ; ah=c, al=ab
mov KOD +2, ah ; записали последнюю цифру
mov ah ,0 ; al = ab , расширение ab до слова (беззнаковое)
div bl ; ah=b, al=a
add ax,’00’ ; ah=b+’0’, al=a+’0’
mov KOD +1, ah ; записали среднюю цифру
mov KOD , al ; записали первую цифру
РЕШЕНИЕ
По очереди вводим цифры и формируем число по схеме Горнера.
Пусть уже введены первые цифры числа, например, 2 и 1, и по ним сформировано число 21. Пусть следующей введена цифра 3. Тогда умножаем предыдущее число на 10 и прибавляем к нему новую цифру: 21*10+3=213. И так для каждой новой цифры.
Замечание. Будем предполагать, что пользователь вводит число в диапазоне 0-255 корректно и ввод завершается нажатием клавиши Enter .
int 21 h ; в al — первый символ
sub al ,30 h ; теперь первая цифра
mov ah ,0 ; расширение до слова
mov cx , ax ; в cx — первая цифра
int 21 h ; в al следующий символ
cmp al ,0 dh ; сравнение с символом Enter
je End ; конец ввода
sub al ,30 h ; в al — следующая цифра
cbw ; расширение до слова
xchg ax , cx ; теперь в ax — предыдущее число, в cx — следующая
Источник
Директивы для упрощенного указания сегментов
Директива .MODEL
.MODEL memory-model
Задает модель памяти для упрощенных директив определения сегментов.
Параметры:
memory-model — модель памяти. Возможные значения:
TINY | Код, данные и стек объединены в одну группу с именем DGROUP и размером до 64 Кб. Используется для создания программ формата .com. Некоторые языки эту модель не поддерживают. СS=DS=SS=DGROUP |
SMALL | Код занимает один сегмент, данные и стек объединены в одну группу с именем DGROUP (хотя для описания могут использоваться разные сегменты). Эту модель обычно используют для большинства программ на ассемблере. CS=_text DS=SS=DGROUP |
MEDIUM | Код занимает несколько сегментов, по одному на каждый объединяемый программный модуль. Все ссылки на передачу управления — типа far (вызов подпрограмм). Данные и стек объединены в одной группе DGROUP; все ссылки на них — типа near (для доступа к данным используется только смещение). CS=<модуль>_text DS=SS=DGROUP |
COMPACT | Код находится в одном сегменте, данные и стек в группе DGROUP и могут занимать несколько сегментов, так что для обращения к данным требуется указывать сегмент и смещение (ссылка на данные — типа far). CS=_text DS=SS=DGROUP |
LARGE | Код может занимать несколько сегментов, по одному на каждый объединяемый программный модуль. Стек и данные находятся в группе DGROUP. Для ссылки на данные используются дальние указатели -far. CS=<модуль>_text DS=SS=DGROUP |
HUGE | То же, что модель LARGE |
FLAT | То же, что и модель TINY, но для 32-битных сегментов |
language-type — тип языка программирования. Возможные значения:
C | Аргументы передаются через стек, справа налево. Стек очищает вызывающая программа. |
PASCAL, BASIC | Аргументы передаются через стек, слева направо. Стек очищает вызываемая подпрограмма. |
STDCALL | Аргументы передаются через стек, справа налево. Стек очищает вызываемая подпрограмма. |
stack-option — организация стека. Возможные значения для 16 бит: NEARSTACK, FARSTACK. Для 32 бит не используется. Указание NEARSTACK группирует сегменты стека в один физический сегмент (DGROUP) вместе с данными. Регистр сегмента стека SS назначается на тот же адрес что и регистр сегмента данных DS. FARSTACK не группирует стек с сегментом данных DGROUP; таким образом регистр SS не будет равен регистру DS.
Директива .CODE или CODESEG
.CODE
Определяет начало сегмента кода. Если задали среднюю или большую модель памяти, то за директивой может следовать необязательное имя, которое указывает имя сегмента. По-умолчанию имя сегмента _TEXT.
Директива .DATA или DATASEG
.DATA
Определяет начало инициализированного сегмента данных.
Директива .DATA?
.DATA?
Определяет в модуле начало неинициализированного сегмента данных.
Директива .CONST
.CONST
Определяет начало сегмента данных-констант.
Сегменты .DATA, .DATA?, .CONST помещаются в одну группу с именем DGROUP
Директива .STACK или STACK
.STACK
Определяет начало сегмента стека, выделяя количество байт, заданное параметром. Если размер не указывается, выделяется 1024 байт.
Пример кода:
.model small,stdcall .stack 100h .data str db 'Hello, world!',0 .code start: mov ax,4C00h int 21h end start
Использование команды ввода с клавиатуры
Для ввода массива с клавиатуры на ассемблере мы будем использовать команду с подкодом . Эта команда позволяет считывать символы с клавиатуры.
Для успешного ввода массива с клавиатуры необходимо сначала подготовить регистры для работы с командой . В регистре нужно установить подкод , а в регистре нужно указать, куда сохранять считанные символы.
После подготовки регистров можно вызывать команду . Считанный символ будет сохранен в памяти по адресу, указанному в регистре .
Процесс считывания символов может быть организован с помощью цикла. В каждой итерации цикла можно сохранять считанный символ в памяти и изменять адрес памяти, указанный в регистре .
Например, можно использовать таблицу символов в памяти или выделить отдельную область памяти под массив для сохранения считанных символов.
Регистр | Описание |
AH | Подкод команды |
DX | Адрес памяти для сохранения считанного символа |
Пример программы на ассемблере для ввода массива с клавиатуры:
.data array db 10 dup(?) ; массив для сохранения считанных символов .code start: mov ah, 01h ; установка подкода команды ввода lea dx, array ; адрес памяти для сохранения символов xor cx, cx ; счетчик символов read_loop: int 21h ; считывание символа с клавиатуры mov , al ; сохранение считанного символа в памяти inc dx ; изменение адреса памяти inc cx ; увеличение счетчика символов cmp cx, 10 ; проверка количества считанных символов jne read_loop ; если не считаны все символы, то повторить цикл ; остальной код программы...
В этом примере массив размером 10 символов считывается с клавиатуры с помощью команды и сохраняется в памяти по адресам, начиная с . Цикл продолжается, пока не будут считаны все символы.
Запуск программы
А сейчас я покажу вам как все это реализовать на практике, после написания кода. Я создал файл fifth.asm и поместил его в папку BIN. Затем я открываю командную строку, и перехожу в папку BIN с помощью команды cd C:\Users\Никита\BIN (у вас будет другой путь, скорее всего) Далее компилирую наш файл, прописывая команду amake.bat fifth, если код правильный, то будет как на фото:
Как мы видим, все скомпилировалось без ошибок, но ничего не вывелось на экран. Для того, чтобы наша программа выполнилась, нужно после компиляции запустить файл с расширением .exe(он создается автоматически после правильной компиляции). Прописываем в командной строке fifth.exe, у вас должно получится нечто подобное:
Инструкции на языке ассемблера
Для микропроцессора Intel 8086 доступно в общей сложности 116 инструкций. Все эти инструкции с соответствующими примерами приведены по этой ссылке.
В этой статье я остановлюсь только на нескольких инструкциях, необходимых для понимания последующих частей.
Копирование данных (MOV): Эта инструкция копирует байт (8-битный) или слово (16-битное) из источника в место назначения. Оба операнда должны быть одного типа (байт или слово). Синтаксис этой инструкции следующий:
Войти в полноэкранный режимВыйти из полноэкранного режима
Операндом может быть любой регистр или область памяти, в то время как операндом может быть регистр, адрес памяти или постоянное/промежуточное значение.
Сложение (ADD) и вычитание (SUB): ADD складывает данные операндов destination и source и сохраняет результат в destination. Оба операнда должны быть одного типа (слова или байты), иначе ассемблер выдаст ошибку. Инструкция вычитания вычитает source из destination и сохраняет результат в destination.
Вход в полноэкранный режимВыход из полноэкранного режима
-
Метка: Метка — это символическое имя адреса команды, которое указывается сразу после объявления метки. Она может быть помещена в начало оператора и служить операндом инструкции. Использованный ранее является меткой. Метки бывают двух типов.
- Символьные метки: Символьная метка состоит из идентификатора или символа, за которым следует двоеточие (). Они должны быть определены только один раз, так как имеют глобальную область применения и отображаются в таблице символов объектного файла.
- Числовые метки: Числовая метка состоит из одной цифры в диапазоне от нуля () до девяти (), за которой следует двоеточие (). Они используются только для локальных ссылок и исключены из таблицы символов объектного файла. Следовательно, они имеют ограниченную область применения и могут быть многократно переопределены.
Вход в полноэкранный режимВыход из полноэкранного режима
Compare (CMP): эта инструкция берет два операнда и вычитает один из другого, затем устанавливает флаги OF, SF, ZF, AF, PF и CF соответственно. Результат нигде не хранится.
Вход в полноэкранный режимВыход из полноэкранного режима
Операнд может быть адресом регистра или памяти, а может быть регистром, памятью или непосредственным значением.
- Инструкции перехода: Инструкции перехода передают управление программой на новый набор инструкций, на который указывает метка, представленная в качестве операнда. Существует два типа инструкций перехода.
- Безусловный переход (JMP): непосредственно переходит к предоставленной метке.
- Условный переход: Эти инструкции используются для перехода только при выполнении условия и вызываются после инструкции . Эта инструкция сначала оценивает, удовлетворяется ли условие с помощью флагов, а затем переходит на метку, заданную в качестве операнда. Это очень похоже на операторы в других языках программирования. В языке ассемблера 8086 доступна 31 инструкция условного перехода.
О программе
В SASM Вы можете легко разрабатывать и выполнять программы, написанные на языках ассемблера NASM, MASM, GAS, FASM.
Вводите код в форму и запускайте приложение. В Windows также возможен запуск приложения в отдельном окне. Входные данные указывайте в поле «Ввод». В поле «Вывод» Вы сможете увидеть результат работы программы. При этом все сообщения и ошибки компиляции будут выводиться в форму снизу. Вы можете сохранять исходный или скомпилированный (exe) код программы в файл, а также загружать свои программы из файла.
Программа поддерживает работу с несколькими проектами – новые файлы открываются и создаются в новых вкладках. При выходе из программы текущий набор открытых файлов сохраняется. При следующем запуске Вы сможете восстановить предыдущую сессию. В параметрах настраивается шрифт, цветовая схема и текст, отображающийся при создании нового файла. Интерфейс программы доступен на восьми языках (русский, английский, турецкий (спасибо Ali Goren), китайский (спасибо Ahmed Zetao Yang), немецкий (спасибо Sebastian Fischer), итальянский (спасибо Carlo Dapor), польский (спасибо Krzysztof Rossa), иврит (спасибо Elian Kamal)). Все окна в программе плавающие, с возможностью закрепления в одной из множества позиций. Имеется возможность переназначения горячих клавиш.
Стандартное меню «Правка» дополнено возможностью комментирования/раскомментирования выделенного куска кода и создания/удаления отступа в 4 пробела (Tab/Shift+Tab).
В SASM вы можете находить ошибки в своих программах с помощью интерфейса к отладчику gdb. В программе можно просматривать значения регистров и переменных, а также устанавливать точки останова и перемещаться по отлаживаемой программе. Дополнительно имеется возможность выполнять произвольные команды отладчика gdb, результаты которых будут отображаться в логе.
SASM полностью поддерживает работу с четырьмя ассемблерами NASM, MASM, GAS, FASM в двух режимах — x64 и x86, переключаться между которыми можно в настройках на вкладке «Построение». Там же можно изменить опции ассемблера и компоновщика и выбрать, какие программы будут использоваться для ассемблирования и компоновки.
Синтаксис FASM
Обозначать привычные нам десятичные числа в коде программы можно с использованием знака минус «-», например:
Однако не только десятичные числа конвертируются в отрицательные с прибавлением «минуса», также такой приём проходит с числами других систем счисления и со строчными символами:
ydb—25h zdb—77o kdb—101b sdb—‘a’ |
Как было написано выше, процессор не делит числа не положительные и отрицательное. Поэтому эта роль программиста определять, какими числами он оперирует в своей программе. Ведь от того интерпретируется байт как число без знака или как число со знаком, зависит его значение. Например, число со знаком -7 соответствует число без знака 249:
Циклы и команда LOOP — i8086
Статья основана на материале xrnd с сайта asmworld (из учебного курса по программированию на ассемблер 16-битного процессора 8086 под DOS).
До этой части все наши программы выполнялись последовательно — в них не было ветвлений и переходов. Сегодня мы научимся делать простейшие циклы. Циклом называется повторяющееся выполнение последовательности команд. Но для начала нужно научиться объявлять метки.
Синтаксис объявления меток
Метка представляет собой символическое имя, вместо которого компилятор подставляет адрес. В программе на ассемблере можно присвоить имя любому адресу в коде или данных. Обычно метки используются для организации переходов, циклов или каких-то манипуляций с данными. По сути имена переменных, объявленных с помощью директив объявления данных, тоже являются метками. Но с ними компилятор дополнительно связывает размер переменной. Метка объявляется очень просто: достаточно в начале строки написать имя и поставить двоеточие. Например:
Теперь вместо имени m1 компилятор везде будет подставлять адрес комады mov ax,4C00h. Можно объявлять метку на пустой строке перед командой:
Имя метки может состоять из латинских букв, цифр и символов подчёркивания, но должно начинаться с буквы. Имя метки должно быть уникальным. В качестве имени метки нельзя использовать директивы и ключевые слова компилятора, названия команд и регистров (в этом случае FASM покажет сообщение об ошибке). FASM различает регистр символов в именах меток. Можно также объявлять несколько меток на один адрес. Например:
Подробнее о синтаксисе объявления меток рассказывается в части 25.
Команда LOOP
Для организации цикла предназначена команда LOOP. У этой команды один операнд — имя метки, на которую осуществляется переход. В качестве счётчика цикла используется регистр CX. Команда LOOP выполняет декремент CX, а затем проверяет его значение. Если содержимое CX не равно нулю, то осуществляется переход на метку, иначе управление переходит к следующей после LOOP команде.
Содержимое CX интерпретируется командой как число без знака. В CX нужно помещать число, равное требуемому количеству повторений цикла. Понятно, что максимально может быть 65535 повторений. Ещё одно ограничение связано с дальность перехода. Метка должна находиться в диапазоне -127…+128 байт от команды LOOP (если это не так, FASM сообщит об ошибке).
Пример цикла
В качестве примера я приведу простую программу, которая будет печатать все буквы английского алфавита. ASCII-коды этих символов расположены последовательно, поэтому можно выводить их в цикле. Для вывода символа на экран используется функция DOS 02h (выводимый байт должен находиться в регистре DL).
Команды «int 21h» и «inc dl» (строки 8 и 9) будут выполняться в цикле 26 раз. Для того, чтобы программа не закрылась сразу, используется функция DOS 08h — ввод символа с клавиатуры без эха, то есть вводимый символ не отображается. Перед этим выводится предложение нажать любую кнопку (но Reset лучше не нажимать). Для примера адрес строки объявлен с помощью метки. Символы с кодами 13 и 10 обозначают переход на следующую строку (символ 13(0Dh) называется CR — Carriage Return — возврат каретки, а символ 10(0Ah) LF — Line Feed — перевод строки . Эти символы унаследованы со времён древних телетайпов, когда текст печатался, как на печатной машинке). Так выглядит результат работы программы:
Вложенные циклы
Иногда требуется организовать вложенный цикл, то есть цикл внутри другого цикла. В этом случае необходимо сохранить значение CX перед началом вложенного цикла и восстановить после его завершения (перед командой LOOP внешнего цикла). Сохранить значение можно в другой регистр, во временную переменную или в стек. Следующая программа выводит все доступные ASCII-символы в виде таблицы 16×16. Значение счётчика внешнего цикла сохраняется в регистре BX.
Как видите, всё довольно просто. Результат работы программы выглядит вот так:
Упражнение
Напишите программу для вычисления степени числа 3 по формуле
Пример программы: числа Фибоначчи
Попробуем написать простую, но законченную программу. Наша программа (назовем
ее ) будет запрашивать у пользователя номер n и вычислять n-е число
Фибоначчи.
Наша программа не будет использовать никаких переменных в памяти, обходясь
одними регистрами.
Запросим у пользователя число n и поместим его в регистр EDX:
Проинициализируем рабочие регистры. Текущее число Фиббоначчи Fk
будем хранить на EAX, предыдущее Fk — на EBX. Само текущее k будем держать в ECX:
Если нас просят вычислить F1 или F2, ответ (единица) у
нас уже готов, прыгнем вперед на метку (команда , jump if below
or equal, переходит на указанную метку, если беззнаковое сравнение на меньше
или равно было истинным, т. е. EDX ≤ 2):
В основном цикле вычисления мы будем складывать два предыдущих члена
последовательности до тех пор, пока не доберемся до искомого n-го члена.
Если сложение вызовет перенос, прыгнем на метку , чтобы сообщить об
ошибке:
Если всё хорошо, выведем результат (EAX):
А если EAX переполнился, напечатаем сообщение об ошибке:
Слайд 6 Программаorg 100h .model tiny chislo dd 12345
;число для вывода
.code
convert:
mov ax, chislo
;число в AX
mov cx,0
; CX=0 – счетчик цифр
mov bx,10 ; BX=0 – основание системы
; счисления
.divide:
mov dx,0 ;DX = 0;
div bx ;деление AX на BX,
;частное в AX ;остаток в DX
add dx, ‘ 0’ ;добавление ASCII-код ; цифры 0 к остатку
push dx ;сохранение в стеке
inc cx ;счетчик +1 cmp ax,0 ;все? (Частное = 0?)
jnz .divide ;если нет
.reverse:
pop ax ;иначе число уже ;преобразовано, цифры
;сохранены в стеке,
; СХ содержит их
;количество
;выбор цифры из стека
mov ah,02h
mov dx,ax
int 21h
dec cx ;уменьшаем счетчик цифр,
; оставшихся в стеке
cmp cx,0 ;цифры кончились ?
jnz .reverse ;Нет? ret
Ввод чисел с клавиатуры в ассемблере с помощью MASM
В ассемблере с помощью Microsoft Macro Assembler (MASM) можно вводить числа с клавиатуры. Для этого необходимо использовать системный вызов , который позволяет считать данные с консоли.
Процесс ввода чисел с клавиатуры в ассемблере с помощью MASM может быть разделен на несколько шагов:
- Создание и инициализация буфера для хранения введенных данных.
- Вызов системной функции для считывания данных с клавиатуры.
- Обработка и преобразование введенных данных.
Пример кода на ассемблере с использованием MASM для ввода и вывода числа с клавиатуры:
.data inputBuffer BYTE 11 DUP(0) ; Буфер для хранения ввода bufferSize DWORD 10 ; Размер буфера bytesRead DWORD ? ; Количество считанных байт .code main PROC ; Ввод числа с клавиатуры invoke GetStdHandle, STD_INPUT_HANDLE ; Получить дескриптор стандартного ввода mov ebx, eax ; Сохранить дескриптор в ebx invoke ReadConsoleA, ebx, ADDR inputBuffer, bufferSize, ADDR bytesRead, 0 ; Преобразование введенного числа lea esi, inputBuffer ; Загрузить адрес буфера в esi xor eax, eax ; Очистить eax mov ecx, 10 ; Множитель для преобразования в число movzx edx, byte ptr ; Загрузить первый символ inc esi ; Увеличить указатель на следующий символ cmp edx, '-' ; Проверить знак числа je negative ; Если знак "-" (отрицательное число), перейти в negative jne positive ; Если знак "+" (положительное число), перейти в positive negative: movzx edx, byte ptr ; Загрузить следующий символ inc esi ; Увеличить указатель на следующий символ mov ebx, eax ; Сохранить текущее значение eax mov eax, ecx ; Загрузить ecx в eax mul ebx ; Умножить ecx на сохраненное значение eax sub edx, '0' ; Преобразовать символ в цифру add eax, edx ; Добавить текущую цифру к eax jmp convert ; Перейти к общему коду преобразования positive: sub edx, '0' ; Преобразовать символ в цифру add eax, edx ; Добавить текущую цифру к eax convert: movzx edx, byte ptr ; Загрузить следующий символ inc esi ; Увеличить указатель на следующий символ cmp edx, 0 ; Проверить конец строки je done ; Если конец строки, перейти в done xor ebx, ebx ; Очистить ebx mov bl, ; Загрузить следующий символ cmp bl, '-' ; Проверить знак числа je negative ; Если знак "-" (отрицательное число), перейти в negative jne positive ; Если знак "+" (положительное число), перейти в positive done: ; Вывод числа invoke MessageBoxA, 0, ADDR inputBuffer, ADDR inputBuffer, MB_OK invoke ExitProcess, 0 main ENDP END main
Вышеуказанный код считывает число, введенное пользователем с клавиатуры, и отображает его в диалоговом окне с помощью функции .
Это лишь пример того, как можно выполнять ввод чисел с клавиатуры в ассемблере с помощью MASM. Существует множество других способов и методов для реализации данной задачи, но данный код демонстрирует основные шаги, которые необходимо выполнить для успешного ввода чисел с клавиатуры с использованием MASM.
Слайд 3 Операции ввода/вывода по прерыванию INT 21H
функция возвращает значение в регистре AL. АН = 02: Вывод
символа. Для ввода символа на экран в текущую позицию курсора необходимо поместить код данного символа в регистр DL. АН = 06: Ввод/вывод данных. Может использоваться как для ввода, так и для вывода. Для вывода занесите в DL выводимый символ (но не FFH!) и прерывание 21Н. Для ввода в DL занесите FFH, выполните прерывание 21Н. Программа при этом не останавливается, продолжает выполняться. При нажатии клавишы символ вводится в AL. АН = 07: Прямой ввод с клавиатуры без эхоотображения. Данная функция работает аналогично функции 01. АН = 08: Ввод с клавиатуры без эхоотображения. Данная функция действует аналогично функции 01 с одним отличием: введенный символ не отображается на экране, т.е. нет эха. АН = 09: Вывод строки символов. Выводимая строка должна заканчиваться знаком доллара $. Адрес начала строки должен быть помещен в DX. AH=0AH: Ввод данных в буфер: Определяется максимальная длина вводимого текста. Это необходимо для предупреждения пользователя звуковым сигналом, если набран слишком длинный текст; символы, превышающие максимальную длину, не принимаются. Во второй байт буфера команда возвращает действительную длину введенного текста в байтах. Адрес буфера помещается в региcтр DX. АН = 0ВH: Проверка состояния клавиатуры. Данная функция возвращает шестнадцатеричное значение FF в регистре AL, если ввод с клавиатуры возможен, в противном случае — 00.
5.2.4. Ввод и вывод чисел
При работе с числами на ассемблере перед каждым программистом встает вопрос, как осуществлять ввод и вывод чисел в программе? Действительно, ввод осуществляется в ASCII-кодах, а вычисления нужно производить с обычными числами; результат вычислений на экран вновь нужно выводить в ASCII-кодах.
Таким образом, при работе с числами в программе на ассемблере необходимы две процедуры: первая должна преобразовывать введенные пользователем числа из ASCII-формата в бинарные числа, а вторая процедура должна наоборот преобразовывать результат вычислений в ASCII-коды для вывода на экран. К сожалению, стандартных команд, которое бы это делали, не существует. В листинге 5.1 вы можете видеть программу, которая запрашивает два числа, складывает их и выводит результат на экран.
В этой программе процедура str2int преобразовывает каждое число из буфера в ASCII-формате в соответствующие бинарное число.
Другая процедура int2str преобразовывает бинарное число (результат вычисления) в число в системе счисления base в ASCII-формате.
Обращаю ваше внимание, что авторство на данные процедуры принадлежит не мне (если авторы объявятся, я укажу их в переиздании этой книги). К настоящему времени весь код программы вы должны в состоянии понять самостоятельно, а комментарии вам в этом помогут
К настоящему времени весь код программы вы должны в состоянии понять самостоятельно, а комментарии вам в этом помогут.