Простая задача на вывод чисел на Ассемблер NASM intel x86: Задание во вложении , приложите к ответу небольшую блок схему с описанием алгоритма и дерево подпрограмм, а так же исходные файлы программы (.asm и .com) с загрузочным модулем !


Простая задача на вывод чисел на Ассемблер NASM intel x86: Задание во вложении , приложите к ответу

kondakovvasenk kondakovvasenk    1   09.01.2022 21:03    0

Ответы
yulyatigayali yulyatigayali  09.01.2022 22:00

.model tiny

.code

.startup

call GetString  ;вводим строку с числами

call GetNumbers  ;разбираем строку и выводим числа в виде hex и в обратном порядке

lea  dx, sPress  ;сообщение нажать любую клавишу

mov  ah, 9   ;функция вывода строки

int  21h

mov  ah, 0   ;ждем нажатие на клавишу

int  16h

 

.exit 0    ;выход из программы (эквивалентно mov ax, 4c00h / int 21h)

 

;ввод строки с консоли

GetString proc

lea  dx, sNumbers ;сообщение 'Enter Numbers: '

mov  ah,9

int  21h

lea  dx, InputString ;адрес параметра функции ввода строки (формат описан ниже)

mov  ah, 0ah   ;номер функции ввода строки

int  21h

ret

GetString endp

;разбор строки и вывод результата

;числа будем хранить в стеке, чтобы вывести их в обратном порядке!

GetNumbers proc

mov  bp, 10  ;будем умножать на 10 (при преобразовании строки в число)

xor  cx, cx  ;счетчик введенных чисел (хранятся в стеке)

 

lea  si, InputString+2 ;адрес самой строки  

     ;+2, т.к. в первых двух байтах длина строки и число введенных символов

     ;длину строки не используем, строку будем анализировать до кода конца строки (0dh)

num_loop:    ;цикл формирования очередного числа

xor  bx, bx  ;здесь будем накапливать число

xor  di, di  ;счетчик цифр очередного числа,  

     ; т.о. если =0, то числа нет (для контроля лишних пробелов)

sym_loop:    ;цикл преобразования числовой строки в число

lodsb    ;читаем очередной байт в регистр al из ds:[si], автоинкремент si

;анализируем байт

до конца строки?

je  cmp_last ;да, учтем последнее число из строки

cmp  al, ' '  ;пробел?

je  space_found ;или конец введенного числа, или дополнительные разделители,  

     ; которые проигнорируем

 

     ;ждем только цифры '0' <= al <= '9'

cmp  al, '0'  ;проверим на цифру

jb  sym_loop ;нецифры игнорируем

cmp  al, '9'

ja  sym_loop

inc  di   ;есть очередная цифра, считаем, чтобы знать, что что-то есть

     ;вдвинем в формируемое число введенный десятичный разряд

     ;для этого предыдущие разряды умнодим на 10 и сложим с введенным

xchg ax, bx  ;ax = предыдущим разрядам, bx = введенной цифре

mul  bp   ;dx:ax = предыдущим старшим разрядам * 10

and  bx, 000fh ;превратим символ цифры 30h-39h в число 0-9

add  bx, ax  ;bx = введенному числу (на данный момент)

jmp  sym_loop ;повторяем анализ символов строки

space_found:   ;встретили пробел

test di, di  ;есть число?

jz  sym_loop ;нет - дополнительные пробелы игнорируем

 

push bx   ;число сохраняем в стеке!

inc  cx   ;считаем

 

jmp  num_loop ;на формирование следующего числа

cmp_last:    ;встретили 0dh-конец строки

test di, di  ;проверим, было ли у нас сформировано число

jz  output_hex ;если в конце строки есть пробелы, то счетчик di=0

     ;если строка заканчивается цифрой, то di не равен 0

     ;и тогда это последнее число также надо сохранить в стеке

push bx   ;в стек!

inc  cx   ;считаем

 

output_hex:    ;выводим результат

lea  dx, sHex ;сообщение 'Hex values: '

mov  ah,9

int  21h

mov  si, cx  ;счетчик введенных чисел в si

hex_loop:    ;цикл вывода hex-значений

test si, si  ;проверим на 0  

jnz  hex_continue

ret     ;все выведено или не было ни одного - выходим!

 

hex_continue:   ;продолжаем вывод

pop  bp   ;извлекаем из стека очередного числа  

     ;(в обратном порядке! так работает стек!)

mov  cx, 4  ;счетчик hex-цифр

form_hex_loop:   ;цикл вывода hex-цифр, начиная со старшей

rol  bp, 1  ;циклически сдвигаем 4 раза, чтобы старшие 4 бита

rol  bp, 1  ;(старшая hex-цифра) попали на мели младших бит

rol  bp, 1

rol  bp, 1

mov  bx, bp  ;получаем код очередной цифры в младших битах

and  bx, 0fh  ;маскируем все остальные биты

mov  dl, byte ptr Hex[bx] ;получаем символ hex-цифры из строки Hex

mov  ah, 2  ;и выводим на экран

int  21h

loop form_hex_loop ;по всем 4 цифрам

mov  dl, ' '  ;разделим числа пробелом

mov  ah, 2

int  21h

dec  si   ;уменьшим счетчик чисел

jmp  hex_loop ;и на повтор

GetNumbers endp

 

;

Hex   db '0123456789ABCDEF'

sNumbers db 0dh,0ah,"Enter numbers: $"

sHex  db 0dh,0ah,"Hex values: $"

sPress  db 0dh,0ah,"Press any key$"

InputString db 128,0,128 dup(?)

end

ПОКАЗАТЬ ОТВЕТЫ
Другие вопросы по теме Информатика