8 / 8 / 0
Регистрация: 03.10.2009
Сообщений: 3
|
|
1 | |
Ввод и вывод чисел в различных системах счисления06.10.2009, 14:14. Показов 263532. Ответов 11
Метки 64-битные числа, fbstp, fpu, inttostr, большие числа, вывод числа, преобразование числа в строку, целые числа (Все метки)
Нужно выполнить перевод чисел из десятичной в двоичную систему счисления. Дать их внутреннее (машинное) представление в соответствии с диапазоном в знаковых и беззнаковых форматах типов Shortlnt (signed char), Byte (unsigned char), Integer (int), Word (unsigned int). Машинное представление данных должно быть дано в двоичной и шестнадцатеричной системах счисления. Создать программу на языке Ассемблер обеспечивающих хранение данных в регистрах микропроцессора и операции пересылки данных.
люди помогите пожалуйста
8
|
|
06.10.2009, 14:14 | |
Ответы с готовыми решениями:
11
Ввод и вывод чисел в различных системах счисления Ввод и вывод чисел в различных системах счисления, исправить код
Организовать ввод значений в различных системах счисления |
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
|
||||||||||||||||||||||||||
08.10.2009, 21:42 | 2 | |||||||||||||||||||||||||
Вывод целого знакового, либо беззнакового числа.
Число для вывода должно находиться в ax. Изменяя число - основание сс можно выводить числа в двоичной, троичной и т.п. системах счисления
Число для вывода должно находиться в ax.
Число для вывода должно находиться в ax. Результат помещяется в es:di.
Число для вывода должно находиться в ax.
Введенное число будет находиться в ax Изменяя число - основание сс, можно вводить числа в различных системах до десятеричной.
78
|
2014 / 1286 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
|
||||||
12.12.2010, 14:48 | 3 | |||||
В дополнение к теме:
Вывод вещественного числа Число для вывода должно находиться на вершине стека сопроцессора, функции должен передаваться через стек параметр - число цифр после запятой(из-за ошибок округления его обычно нельзя посчитать заранее)
46
|
Ушел с форума
![]() 16213 / 7544 / 1047
Регистрация: 11.11.2010
Сообщений: 13,550
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
14.03.2013, 04:57 | 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||
вывод числа из сопроцессора на экран
преобразование строки в число
1
|
Модератор
![]() |
|||||||||||||||||||||||||||||||||||||||||
05.01.2017, 19:29 | 5 | ||||||||||||||||||||||||||||||||||||||||
Вывод чисел в DOS Добавлю и "свои" способы ввода и вывода. Они ничем не лучше, но и не хуже приведённых выше. Причина публикации в том, что новички, заглядывая в данную тему, не могут понять, как пользоваться приведёнными фрагментами кода. Вывод целого беззнакового 16-разрядного числа (DOS) Подпрограмма в основном повторяет аналогичный код Goodwin98, отличие лишь в именовании меток. При желании разобраться в алгоритме - можно построчно сравнивать с кодом Goodwin98 - и разбираться с комментариями. Алгоритм состоит в делении исходного числа на основание системы счисления, т.е. на 10 и печати остатков от этого деления - цифр. Единственно, при делении получаются цифры младших разрядов числа. Чтобы изменить порядок вывода цифр, в цикле деления на 10 остатки не выводятся на экран, а сохраняются в стек, после этого в дополнительном цикле цифры извлекаются из стека и выводятся на экран.
Assembler mov ax, 12345 ;или иначе, поместив отображаемое число в ax call ShowUInt16 Вывод целого 16-разрядного числа со знаком (DOS) Как справедливо отметил в комментариях Goodwin98, вывод знакового и беззнакового чисел фактически одинаковы. Только перед выводом знакового, нужно один раз выполнить некоторые действия (взять абсолютное значение выводимого числа), а потом вывести обычное беззнаковое число (ведь после взятия абсолютного значения у нас - беззнаковое число). Что нужно добавить перед выводом: - проверить знак выводимого числа - если число отрицательное - вывести на экран символ "минус" и взять абсолютное значение числа Итак, в итоге получим почти идентичную подпрограмму
Assembler mov ax, -12345 ;или иначе, поместив отображаемое число в ax call ShowInt16 Вывод шестнадцатеричного числа (DOS) При выводе по основанию системы счисления являющемуся степенью 2 деление и умножение выполняются при помощи битовых операций (сдвиг, И, ИЛИ), также можно отказаться от хранения остатков в стеке и преобразование вести не от младших цифр к старшим, а наоборот, т.к. выводимое число легко разделяется на независимые битовые поля (служащие остатками от деления на основание системы счисления). Но принцип преобразования остаётся неизменным. 1. Табличный метод с применением команды xlat Как видно, сначала выполняется преобразование в строку (в переменную asHex), а потом эта строка выводится на экран. По хорошему, эту переменную бы объявить как локальную на стеке, а таблицу HexTabl - в сегменте данных. Но при обучении - достаточно преренести строки с объявлениями этих переменных в сегмент данных.
Assembler mov ax, 1234h xchg al, ah call ShowHex xchg al, ah call ShowHex
Assembler mov ax, 1234h call ShowHex Воспользовавшись тем, что вывод в 16 системе счисления это "особый случай" (основание есть степень 2) и возможностью использовать флаг переноса (заёма) CY совместно с командами сложения и вычитания с этим флагом (ADC, SBB), сверхоптимизаторы придумали такой код
Assembler mov ax, 1A2Fh call ShowHex К слову, в https://www.cyberforum.ru/post5356776.html в подразделе "Применение команды SBB" приводятся аналогичные примеры оптимизации. Также, будет интересна подборка 27 (sic!) способов вывода чисел в шестнадцатеричном виде, подготовленная Mikl___: Написать программу перевода двухбайтового целого числа в массив символов Вывод двоичного 16-разрядного числа (DOS) Приведённый код почти соответствует примеру Goodwin98 (OutBin), различие в способе преобразования выделенного бита в код цифры. Т.к. за кодом цифры '0' следует код цифры '1', то можно без ветвления и переходов сложить код символа '0' с числом 0 и значением флага переноса CY (после сдвига в этом флаге находится очередной бит выводимого числа).
Assembler mov ax, 12345 ;или иначе, поместив отображаемое число в ax call ShowBin Вывод восьмеричного 16-разрядного числа (DOS) Как видно, эта процедура почти полная копия варианта 2 вывода шестнадцатеричного представления числа.
Assembler mov ax, 123456o ;или иначе, поместив отображаемое число в ax call ShowOct
0
|
Прощай, Мир!
1672 / 830 / 253
Регистрация: 26.05.2012
Сообщений: 3,056
|
||||||
05.01.2017, 21:20 | 6 | |||||
мой "подарок" форуму, перевод числа из 8-ой в 2-ую систему счисления. при запуске программы вводится число в 8-ой системе счисления, затем программа переводит это число в бинарную систему счисления и выводит
1
|
Модератор
![]() |
|||||||||||||||||||||||||||||||||||||||||
05.01.2017, 22:33 | 7 | ||||||||||||||||||||||||||||||||||||||||
Ввод чисел несколько сложнее вывода по причине возможности ошибочности входных данных (в строке присутствуют не только цифры или число в строке превышает разрядность выделяемой для него ячейки памяти).
При вводе чисел возможны несколько подходов - ввод символов совмещён с преобразованием и ввод символов осуществляется отдельно, преобразование строки в число отдельно. У каждого подхода свои достоинства и недостатки. Ввод числа без знака в почти произвольной (не более 10) системе счисления Это не совсем ввод числа, это преобразование строки в число. Непосредственно ввод строки нужно выполнить отдельной процедурой. На вход в процедуру Str2Num передаётся указатель на строку Pascal типа - т.е. по смещению 0 в строке находится её длина. Это достаточно удобно при работе в DOS, т.к. функция получения строки (ah=0Ah int 21h) возвращает не только строку но и её длину, причём сразу в нужной ячейке памяти.Процедура преобразует строку в число предполагая 10 систему счисления. Чтобы изменить на другую систему, требуется закомментировать строку 24, а в регистре bx передать на вход предполагаемую систему счисления. Кроме того, для обеспечения корректности символов во входной строке требуется изменить в строке 36 верхний допустимый символ. Опять же, как на одинаковые вопросы Природа даёт похожие ответы, так и эта процедура очень похожа на процедуру Goodwin98 InputInt. Разница в некоторых деталях: у меня не ввод числа, а преобразование строки, признак окончания строки в InputInt - специальный символ, а в моём случае, длина строки известна. Само же преобразование и проверки - близнецы-братья.
Пример применения получился сложнее, т.к. требовалось показать обработку ошибок преобразования строки в число в самой программе. Поэтому здесь приведу ссылку на пример из именно этих процедур. https://www.cyberforum.ru/post9972970.html Ввод числа со знаком в почти произвольной (не более 10) системе счисления К этой процедуре относятся все замечания, что и к процедуре для беззнакового преобразования.Т.к. эта процедура лишь усложнение предыдущей, упомяну лишь отличия. При обработке строки символов, содержащей знаковое число, первым обрабатывается возможный символ минус ('-'). Если он присутствует, то пока пропустим его. Далее - ввод положительного числа. Теперь, когда число введено, ещё раз посмотрим первый символ строки - признак отрицательного числа - на предмет наличия символа "минус". Если символ минус присутствует - инвертируем число. Ко всем предыдущим проверкам добавляется ещё одна - после получения модуля вводимого числа, проверим модуль числа на неотрицательное значение, для исключения некорректного ввода числа +3276810=1000'0000''0000'00002=-3276810 Причём, выполнять её нужно лишь для положительных чисел, т.к. для отрицательных после neg ax результат будет вполне корректный.Эта же проверка дублируется в ходе преобразования - cmp ax, 8000h / ja @@Error .Причина дублирования в несимметричности диапазона знаковых чисел (-32768...32767) - при вводе -32768 число корректное, а при вводе +32768 - уже нет. Поэтому в тексте присутствуют почти одинаковые проверки.
Из-за размеров, пример уберу под спойлер. Это не полноценная программа, а только фрагмент. Кликните здесь для просмотра всего текста
Полный пример ввода и контрольного вывода введённого числа. При ошибке ввода числа программа повторяет ввод. Кликните здесь для просмотра всего текста
Ввод числа со знаком в десятичной системе счисления (с фильтрацией ввода) Ввод числа не обязательно выполнять в два этапа - ввод строки и её обработка. Возможен вариант ввода по одному символу с фильтрацией только цифр и знака "минус". В остальном, алгоритм повторяет действия при обработке строки.Из недостатков нужно отметить:
Ввод числа без знака в десятичной системе счисления (с фильтрацией ввода) автор Constantin Cat, взято с сокращениями здесь
2
|
Asm♥/C++/Delphi/Py/PHP/Go
|
|||||||||||
04.02.2017, 21:01 | 8 | ||||||||||
Преобразование 64-битного знакового числа в строку с использованием FPU (с помощью инструкции
fbstp )Написал несколько процедур для преобразования 64-битных знаковых чисел в строку с использованием FPU. Работа процедур основана на инструкции fbstp , которая записывает число в память в BCD-формате.Для работы достаточно инструкций 286 процессора (или даже 8086, если удалить строку .286 , однако я не рекомендую этого делать, т.к. код в этом случае неоправданно удлинится).Привожу здесь 2 варианта процедур вывода 64-битного числа на стандартный вывод (обычно на экран) с помощью функции DOS ah=2/int 21h .Итак, вариант вывода чисел размером не более 18 десятичных знаков (таковы ограничения работы инструкции fbstp ), что примерно соответствует 61 биту (60 бит + знак) + пример использования:
fbstp ликвидируются предварительным вычислением старшей 19-й цифры с привидением числа к 18-знаковому) + пример использования:
int 29h и преобразование числа в строку без вывода на экран.Всё это вы можете найти в прикреплённых исходниках, а также по ссылке: Преобразование 64-битных знаковых чисел в строку с использованием FPU .
1
|
Модератор
![]() |
|||||||||||
01.07.2017, 22:07 | 9 | ||||||||||
Вывод целого беззнакового 32-разрядного числа
Вывод (или преобразование в строку) 32-разрядного числа алгоритмически несколько сложнее вывода 16-разрядного числа, т.к. формально в 16-разрядной DOS недоступны 32-разрядные регистры и выполнить деление на 10 затруднительно. Поясню - пусть нужно разделить число 123456789 на 10. "На бумаге" всё получается очень просто 123456789/10=12345678 (остаток 9). Помещая делимое в регистровую пару dx:ax, а делитель в bx после команды div bx получаем переполнение и аварийный останов программы, т.к. частное 12345678 не "умещается" в регистре ax. Но любой школьник легко сможет выполнить подобное деление - "в столбик" на листе бумаги. Значит и нам ничто не мешает поступить подобным образом. Т.е. мы можем взять не всё исходное число, а только его старшее слово и разделить на 10. В результате получим в ax частное, а в dx - остаток. Частное можно сохранить для будущих вычислений, а в регистр ax можно загрузить следующее слово исходного делимого. Опять получается регистровая пара dx:ax, которую можно делить на 10. Причём при делении не возникнет переполнения, т.к. это частное будет меньше слова. Деление можно проиллюстрировать изображением Т.к. первоначальное число можно сохранить во временной переменной, и исходное значение этой переменной нигде больше не нужно, то в этой же переменной можно по мере деления на 10 сохранять и частичные частные для получения следующей цифры исходного числа. Достаточно удобно организовать обращение к составляющим исходного числа как к массиву слов, организовав индексацию через регистр si. Весь остальной код по смыслу напоминает предыдущие примеры - сохранение остатков в стеке и дальнейший их вывод в порядке, обратном получению. Добавлю, что для визуального упрощения исходного кода используется усложнённый синтаксис директивы (макроса) proc , что приводит к необходимости объявления в начале программы не только модели памяти программы, но и модели соглашения о вызове процедур и передачи им параметров .model small, Pascal . В данном случае я выбрал Pascal .
P. P. S. Также, будет интересна подборка способов ввода и вывода 32 и 64 разрядных чисел в десятичном виде, подготовленная Mikl___: Остаток от деления на 10 32-битного числа в dx:ax https://www.cyberforum.ru/post6454877.html
2
|
Модератор
![]() |
||||||||||||||||||||||||||||||||||||
19.01.2019, 17:54 | 10 | |||||||||||||||||||||||||||||||||||
Вывод результата деления целых 16-разрядных чисел в виде десятичной дроби Сразу отмечу — в статье рассмотрю только вывод на экран результата деления, а не преобразование числа в другой формат с сохранением в ячейках памяти. Это означает, что при помощи кода из статьи невозможно, к примеру, сложить две рациональные дроби путём получения двух десятичных дробей и выполнения их сложения. Результатом деления двух целых чисел инструкциями div и idiv является частное и остаток. При необходимости вывода результата в виде десятичной дроби потребуется дополнительная обработка.Пусть необходимо вывести результат деления двух чисел A и B. Проведём преобразования D — остаток от деления, сразу отметим, что справедливо D<B. Получается, что на экран нужно вывести число C, десятичный разделитель и цифры дробной части. Вывод частного не должен вызывать затруднений, т.к. уже тщательно рассмотрен в статьях топика. Рассмотрим алгоритм на примере деления числа 4987 на 123. При обычном делении в столбик получим После получения целой части результата - имеем частное 40 и остаток 67. Продолжим деление: к результату дописываем десятичный разделитель (запятую), к остатку (теперь это новое делимое) справа дописываем цифру ноль (умножаем на 10) и пробуем разделить на делитель. Получаем первую цифру дробной части результата (цифру 5) и новый остаток (число 55). Продолжая по такому же принципу получим ещё три цифры в десятичной части результата. Сформулируем алгоритм: 1. Делением получаем частное и выводим его любым известным способом. 2. Выводим символ десятичного разделителя (запятую). 3. В цикле, требуемое число раз, выводим по одному символу цифры: 3.1 Остаток умножаем на 10. 3.2 Результат умножения делим на делитель 3.3 Новое частное (это всегда одна цифра) выводим на экран Для демонстрации, рассмотрим реализацию этого алгоритма на языках Pascal и C. Реализация по сравнению с алгоритмом немного усложняется: нет смысла выводить цифры десятичной части при нулевом остатке, да и саму дробную часть при делении исходных чисел без остатка. Реализация алгоритма на Pascal
Реализация алгоритма на C
Реализуем на языке ассемблера, оформив в виде процедуры. Рассмотрим два случая, деление беззнаковых чисел и деление чисел со знаком. Для беззнаковых чисел. В процедуре используется вызов подпрограммы ShowUInt16 для вывода содержимого регистра ax, т.к. вывод частного всё равно будет полностью повторять её и нет смысла дублировать код, тем более, что в реальной программе вывод числа всё равно используется в другом участке кода. При выводе каждой цифры дроби можно было бы уже не вызывать ShowUInt16 и воспользоваться упрощённым кодом, т.к. выводится будет всего одна цифра. Я решил в обоих случаях вызывать ShowUInt16 для наглядности.
Пример использования
Для чисел со знаком изменится: 1. В строки 11-13 будут
3. В строке 30 вызывать процедуру ShowSInt16. И в результате получится:
Пример использования
Код, представленный здесь, рабочий, но предназначен для пояснения алгоритма, а не к сокращению размера и высокой эффективности. Кроме того, желание оставаться в рамках совместимости с эмулятором emu8086, не поддерживающим множество функций DOS (например, int 29h) тоже не позволяет уменьшить размер. Примеры других реализаций алгоритма https://www.cyberforum.ru/post13252664.html Вычислить значение выражения https://www.cyberforum.ru/post10592976.html Вычислите значение кусочной функции
1
|
Модератор
![]() |
||||||||||||||||
12.06.2020, 18:47 | 11 | |||||||||||||||
Как пользоваться процедурами ввода и вывода чисел Исходное состояние программы Программа пользователя, в которой требуется применение процедур ввода или вывода, имеет примерно следующий вид Предположим, вычисление по формуле Y=X+Z
В сегмент кода копируем процедуру ShowInt16, а сразу после вычислений вызываем её. Чтобы сократить объём текста в сообщении, а также предоставить возможность потренироваться в копировании процедуры, в исходнике не буду показывать содержимое процедуры ShowInt16, только обозначу её месторасположение.
Точно также выполняется копирование и вставка процедур ввода числа. К некоторым процедурам ввода приводятся примеры ввода. Копируем их вместе с процедурой. Так, для Str2Num получаем
Помимо описания, для многих процедур показаны примеры их использования.
2
|
Модератор
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
04.10.2020, 17:35 | 12 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вывод целых чисел для 32-разрядных программ на NASM Введение Ввод и вывод чисел для программ, написанных для NASM, рассмотрим отдельно из-за разнообразия возможных способов. Возможные способы:
Вывод целых чисел Преобразование в строку с последующим выводом строки средствами операционной системы Преобразование выполняется по следующему алгоритму — число делится на 10 (основание системы счисления), остаток преобразуется в символ цифры (путём сложения с кодом символа «0»), затем остаток сохраняется в стеке, после того, как частное становится равным нулю, деление превращается и извлекаем из стека цифры, которые помещаем в строку. Для числа со знаком вначале ещё выполняется проверка знака числа, и для отрицательного — в строку помещается символ «-», а выводимое число заменяется его абсолютным значением. Вывод 32-разрядного числа без знака (для Linux)
проверено в онлайн компиляторе https://www.tutorialspoint.com... online.php компиляция командной строкой
Кликните здесь для просмотра всего текста
Макросы IDE SASM Для вывода чисел библиотека "io.inc" предлагает макросы PRINT_UDEC, PRINT_DEC, PRINT_HEX.
Пример использования Кликните здесь для просмотра всего текста
Использование библиотеки libc Для вывода применяется функция форматного вывода _printf. Спецификаторы в форматной строке соответствуют аналогичным из языка C. С более полной спецификацией можно ознакомиться по ссылкам https://learnc.info/c/formatted_input_output.html https://ru.wikipedia.org/wiki/Printf https://en.wikipedia.org/wiki/Printf_format_string В стек помещаются значения чисел, адрес форматной строки и вызывается внешняя подпрограмма _printf, после вызова требуется самостоятельно очистить стек от передаваемых параметров.
Пример использования из IDE SASM компиляция командной строкой
Кликните здесь для просмотра всего текста
Вывод средствами WinAPI wsprintf и WriteConsole (Windows) Функция WinAPI wsprintf работает с форматной строкой, в которой указаны спецификаторы преобразования. Описание https://docs.microsoft.com/en-... -wsprintfa http://www.vsokovikov.narod.ru... printf.htm Как видно из описания, преобразование выполняется для строк и целых чисел — вещественные числа (single, double, extended) этой функцией не преобразовываются. Также, для вывода потребуется описатель вывода консоли — его можно получить перед использованием WriteConsole при помощи WinAPI функции GetStdHandle.
компиляция командной строкой
https://sourceforge.net/projec... alink/1.6/ Кликните здесь для просмотра всего текста
Вывод средствами msvcrt (Windows) Библиотека msvcrt содержит функцию printf для вывода в консоль. Функция позволяет выводить строки, целые числа (в восьмеричном, десятичном и шестнадцатеричном виде), вещественные числа двойной точности (double). https://docs.microsoft.com/en-... ew=vs-2019 Для использования библиотеки msvcrt.dll необходимо объявить функцию printf внешней и указать источник импорта.
компиляция командной строкой
https://sourceforge.net/projec... alink/1.6/ Кликните здесь для просмотра всего текста
И то же самое, но с применением пакета nasmx (https://sourceforge.net/projects/nasmx/) Взял код Jin X из сообщения [NASM] Вывод на экран компиляция командной строкой (в оригинале Jin X предлагает чуть более сложный пакетный файл)
1
|
04.10.2020, 17:35 | |
04.10.2020, 17:35 | |
Помогаю со студенческими работами здесь
12
Сложение чисел в различных системах счисления
Программа для преобразования чисел в различных системах счисления Сгенерировать калькулятор целых и вещественных чисел в различных системах счисления Программа для расчета выражения. Ввод/вывод в разных системах счисления Калькулятор в различных системах счисления Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |