Вывод последовательности чисел в обратном порядке - Assembler
Формулировка задачи:
Приветствую всех форумчан! Работая над контрольной работой зашел в тупик, поэтому прошу помощи.
Задание следующее - ввести с клавы последовательность трехзначных dec чисел разделенных пробелом, программа должна вывести ее на экран в обратном порядке в hex числах.
Внизу приведу код, который смог составить.
Код дает ошибки при вводе, затем переполнение при делении. В связи с этим подскажите, пожалуйста,
1. При вводе чисел пробелы не печатаются, пытался исправить, не вышло.
2. После ввода третьего числа и нажатия пробела ввожу следующие 3 числа, печатает только 2 из них, почему, не знаю.
3. С переполнением пытался бороться предварительным обнулением dx, безрезультатно.
За любой ответ буду крайне признателен, так как хочется все же разобраться да и без кода сессии мне не видать.
[org 100h] jmp start mess0 db 13,10,' ВВЕДИТЕ ЧИСЛА В ДЕСЯТИЧНОЙ СИСТЕМЕ (ENTER-ЗАКОНЧИТЬ) $' mess1 db 13,10,' В ШЕСТНАДЦАТЕРИЧНОЙ СИСТЕМЕ В ОБРАТНОМ ПОРЯДКЕ $' start: mov dx,mess0 ; печать текста 'ВВЕДИТЕ ... (ENTER-ЗАКОНЧИТЬ)' call MESSAGE xor bp,bp vvod: call ASC2HEX ; вызов процедуры, преобразующей ascII код в hex числа push cx ; в стеке первые 3 числа hex inc bp ; счетчик стека увеличивается на единицу mov ah,8 ; ввод ,БЕЗ ЭХА средствами DOS int 21h ; cmp al,13 ; это 'enter'? jne vvod ; если нет, вводим следующее число mov dx,mess1 ; печать текста 'В ШЕСТНАДЦАТЕРИЧНОЙ СИСТЕМЕ В ОБРАТНОМ ПОРЯДКЕ' call MESSAGE vivod: pop ax ; вытащили из стека последние 3 числа mov bx,10 v.1: ; переворот числа в ах задом наперед div bx ; делим ax на 10, в остатке в dx сохраняется последняя цифра shl dx,4 ; сдвигаем эту цифру влево на один полубайт or ax,ax ; проверяем, в ах после деления что-нибудь осталось? jnz v.1 ; если да, цикл повторяется снова mov ax,dx ; в итоге в dx должно накопится число, обратное ax по порядку dec bp ; счетчик стека уменьшился на единицу mov bx,16 ; BX=16 call HEX2ASC ; вызов процедуры преобразования hex в ascII код и их печать or bp,bp ; счетчик стеков равен нулю? jnz vivod ; если нет, вытаскиваем предпоследние 3 числа exit: xor ax, ax int 16h int 20h ;============== ВЫВОД НА ЭКРАН СРЕДСТВАМИ DOS ================================| MESSAGE: mov ah,9 ; строки int 21h ret ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ;============== ПРОЦЕДУРА СОХРАНЕНИЯ ВВОДА В HEX-ФОРМАТЕ =====================| ASC2HEX: XOR CX,CX @0: ; MOV AH,8 ; ввод ,БЕЗ ЭХА средствами DOS INT 21h ; CMP AL,20h ; это пробел - выход из цикла JE stop ; MOV DL,AL ; скидываем введенное число в DL CMP AL,30h ; введенное число asc2 JB @0 ; меньше 30? значит в начало CMP AL,39h ; может больше 39? да - направляем в начало JA @0 ; SUB AL,30h ; меньше/равно 39, вычитаем 30h @2: ; SHL CX,4 ; сдвигаем мл.полубайт (CL), в старший OR CL,AL ; в мл.полубайте (CL) запишем наше число @1: MOV AH,2 ; печать средствами DOS INT 21h JMP @0 ; читаем следующий символ.. stop: ; Если нажал ENTER, то результат у нас в CX. RET ; ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ;============== ФУНКЦИЯ ВЫВОДИТ НА ЭКРАН В РАЗЛИЧНЫХ СС =======================| HEX2ASC: ; XOR CX,CX ; На входе: BX = система счисления, AX = число isDiv: ; XOR DX,DX ; очистим место под остаток DIV BX ; разделим AX на фактор системы счисления PUSH DX ; сохраняем остаток от деления INC CX ; увеличим счётчик разрядности цифры OR AX,AX ; это последняя цифра?! JNZ isDiv ; нет - читаем следующую.. isOut: ; <-- в СХ у нас кол-во пуш'ей (для LOOP) POP AX ; снимаем со-стека остаток в обратном порядке CMP AL,9 ; проверка на десятичную цифру JLE noHex ; меньше/равно? значит не HEX-цифра ADD AL,7 ; иначе: коррекция для HEX noHex: ; ADD AL,30h ; переводим цифру в символ INT 29h ; выводим её на экран LOOP isOut ; мотаем цикл CX-раз.. RET ; ;
Решение задачи: «Вывод последовательности чисел в обратном порядке»
textual
Листинг программы
org 100h jmp start mess0 db 13,10,' ВВЕДИТЕ ЧИСЛА В ДЕСЯТИЧНОЙ СИСТЕМЕ (ENTER-ЗАКОНЧИТЬ) $' mess1 db 13,10,' В ШЕСТНАДЦАТЕРИЧНОЙ СИСТЕМЕ В ОБРАТНОМ ПОРЯДКЕ $' start: mov dx,mess0 ; печать текста 'ВВЕДИТЕ ... (ENTER-ЗАКОНЧИТЬ)' call MESSAGE xor bp,bp mov bx,10 vvod: call ASC2HEX ; вызов процедуры, преобразующей ascII код в hex числа push cx ; в стеке первые 3 числа hex inc bp ; счетчик стека увеличивается на единицу cmp al,13 ; это 'enter'? jne vvod ; если нет, вводим следующее число mov dx,mess1 ; печать текста 'В ШЕСТНАДЦАТЕРИЧНОЙ СИСТЕМЕ В ОБРАТНОМ ПОРЯДКЕ' call MESSAGE mov bx,16 vivod: pop ax ; вытащили из стека последние 3 числа call HEX2ASC ; вызов процедуры преобразования hex в ascII код и их печать dec bp;,bp ; счетчик стеков равен нулю? jnz vivod ; если нет, вытаскиваем предпоследние 3 числа exit: xor ax, ax int 16h int 20h ;============== ВЫВОД НА ЭКРАН СРЕДСТВАМИ DOS ================================| MESSAGE: mov ah,9 ; строки int 21h ret ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ;============== ПРОЦЕДУРА СОХРАНЕНИЯ ВВОДА В HEX-ФОРМАТЕ =====================| ASC2HEX: XOR CX,CX @0: ; MOV AH,8 ; ввод ,БЕЗ ЭХА средствами DOS INT 21h ; cmp al,13 jz stop mov dl,al CMP AL,20h ; это пробел - выход из цикла JE @1 CMP AL,30h ; введенное число asc2 JB @0 ; меньше 30? значит в начало CMP AL,39h ; может больше 39? да - направляем в начало JA @0 push dx and ax,0fh xchg cx,ax xor dx,dx mul bx add cx,ax pop dx @1: MOV AH,2 ; печать средствами DOS INT 21h cmp dl,' ' ; читаем следующий символ.. jnz @0 stop: ; Если нажал ENTER, то результат у нас в CX. RET ; ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ;============== ФУНКЦИЯ ВЫВОДИТ НА ЭКРАН В РАЗЛИЧНЫХ СС =======================| HEX2ASC: ; XOR CX,CX ; На входе: BX = система счисления, AX = число isDiv: ; XOR DX,DX ; очистим место под остаток DIV BX ; разделим AX на фактор системы счисления PUSH DX ; сохраняем остаток от деления INC CX ; увеличим счётчик разрядности цифры OR AX,AX ; это последняя цифра?! JNZ isDiv ; нет - читаем следующую.. isOut: ; <-- в СХ у нас кол-во пуш'ей (для LOOP) POP AX ; снимаем со-стека остаток в обратном порядке CMP AL,9 ; проверка на десятичную цифру JLE noHex ; меньше/равно? значит не HEX-цифра ADD AL,7 ; иначе: коррекция для HEX noHex: ; ADD AL,30h ; переводим цифру в символ INT 29h ; выводим её на экран LOOP isOut ; мотаем цикл CX-раз.. mov al,' ' int 29h RET ;
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д