Вопрос или проблема
Мне нужна программа, которая считывает два числа от пользователя (ввод). Первое число (x) должно быть в диапазоне 0 – 65535. Второе число (y) должно быть в диапазоне 0-255. Затем программа должна разделить эти числа z = x/y. Она должна проверить, находятся ли вводимые числа в диапазоне (первое 0-65535, второе 0-255).
Сейчас я на том этапе, когда хочу считывать ввод от пользователя, но после отображения сообщения программа принимает только 1 символ, и я не могу ввести свое первое число, например 345. Мне нужно вводить эти числа с помощью RST 2 (или, если это невозможно, и у вас есть лучшая идея, вводить другими способами). Также, если сможете, объясните, почему вы сделали операцию X вместо Y. Потому что я только начал изучать ассемблер и пока не очень хорошо в этом, как вы можете увидеть ниже :D.
Ниже мой код:
ORG 800H
JMP MAIN
MSG_PRINT
LXI H,US_INP1
CALL DISPLAY
DISPLAY
MOV A,M
CPI '$'
JZ DISPLAY_END
CALL DISPLAY_CHAR
INX H
JMP DISPLAY
DISPLAY_END
RET
DISPLAY_CHAR
RST 1
RET
INPUT_NUMBER
RST 2
RET
VALID_FIRST
MOV A,D
CPI 255
JC VALID_16BIT
JMP ERROR
VALID_16BIT
RET
VALID_SECOND
MOV A,B
CPI 255
JC VALID_8BIT
JMP ERROR
VALID_8BIT
RET
ERROR
LXI H,US_INPE
CALL DISPLAY
JMP MAIN
SUCCESS
LXI H,US_INPOK
CALL DISPLAY
RET
MAIN
LXI H,US_INP1
CALL DISPLAY
CALL INPUT_NUMBER
CALL VALID_FIRST
CALL SUCCESS
LXI H,US_INP2
CALL DISPLAY
CALL INPUT_NUMBER
CALL VALID_SECOND
CALL SUCCESS
HLT
US_INP1 DB 'Введите число (0-65535): $'
US_INP2 DB 'Введите число (0-255): $'
US_INPE DB 'Неправильное число.$'
US_INPOK DB 'Правильное число.$'
Ответ или решение
Для решения задачи деления двух чисел на ассемблере Intel 8080 с учетом заданных условий, необходимо организовать корректный ввод, обработку и проверку значений. Я постараюсь объяснить каждую часть кода и его логику, чтобы вы могли понять, как происходит реализация.
1. Ввод чисел
Ваша программа на данный момент принимает только один символ за раз из-за того, что команда RST 2
, используемая для ввода, не считывает последовательные цифры. Вам нужно будет реализовать возможность ввода более чем одной цифры.
Чтобы реализовать ввод чисел, каждую введенную цифру можно преобразовать в соответствующее число. Для этого можно создать цикл, который будет считывать каждую цифру, проверять, является ли она допустимой (от ‘0’ до ‘9’), и добавлять её к уже введенному числу, формируя полное 16-битное число для первого числа и 8-битное для второго.
2. Код программы
Ниже представлен скорректированный пример кода:
ORG 800H
JMP MAIN
MSG_PRINT
LXI H, US_INP1
CALL DISPLAY
DISPLAY
MOV A,M
CPI '$'
JZ DISPLAY_END
CALL DISPLAY_CHAR
INX H
JMP DISPLAY
DISPLAY_END
RET
DISPLAY_CHAR
RST 1
RET
INPUT_NUMBER
MOV B, 0 ; Счетчик для числа
MOV C, 0 ; Сохраним число здесь
READ_DIGIT:
RST 2 ; Ввод цифры
CPI '0' ; Проверка на '0'
JC INVALID_INPUT ; Если меньше '0', ошибка
CPI '9'
JC STORE_DIGIT ; Если меньше '9', это допустимо
JMP INVALID_INPUT ; Если больше, тоже ошибка
STORE_DIGIT:
SUB '0' ; Преобразование ASCII в число
MOV A, C
INX B ; Перевод в позицию
MOV D, A
MOV A, C
MVI A, 0
ADD D ; Слагаем
MOV C, A * 10 + B ; Получаем корректное число
JMP READ_DIGIT
INVALID_INPUT:
LXI H, US_INPE
CALL DISPLAY
JMP MAIN
VALID_FIRST
MOV A, C ; Получаем первое число
CPI 65536
JC VALID_16BIT
JMP ERROR
VALID_16BIT
RET
VALID_SECOND
MOV A, B ; Получаем второе число
CPI 256
JC VALID_8BIT
JMP ERROR
VALID_8BIT
RET
ERROR
LXI H, US_INPE
CALL DISPLAY
JMP MAIN
SUCCESS
LXI H, US_INPOK
CALL DISPLAY
RET
MAIN
LXI H, US_INP1
CALL DISPLAY
CALL INPUT_NUMBER
CALL VALID_FIRST
CALL SUCCESS
LXI H, US_INP2
CALL DISPLAY
CALL INPUT_NUMBER
CALL VALID_SECOND
CALL SUCCESS
HLT
US_INP1 DB 'Input number (0-65535): $'
US_INP2 DB 'Input number (0-255): $'
US_INPE DB 'Wrong number.$'
US_INPOK DB 'Correct number.$'
3. Объяснение кода
-
Ввод чисел: Используется цикл
READ_DIGIT
, который позволяет считывать одну цифру за раз. После считывания она проверяется на корректность. Если цифра корректная, она преобразуется из ASCII в число и добавляется к уже введенному числу. -
Проверка диапазонов: Функции
VALID_FIRST
иVALID_SECOND
отвечают за проверку на соответствие введенных чисел диапазонам (0-65535 и 0-255 соответственно). Здесь используются командыCPI
, которые сравнивают значения с границами. -
Ошибка: Если введенное число выходит за пределы, программа выводит сообщение об ошибке, используя указатель
US_INPE
.
4. Выводы
По всей видимости, причина, по которой ваша программа не обрабатывает последовательный ввод, заключается в недостаточной обработке ввода. Модифицированный код исправляет это, позволяя пользователю вводить многозначные числа, и добавляет обработку, чтобы убедиться, что они находятся в допустимых диапазонах.
При изучении программирования на ассемблере важно понимать, как работают базовые операции, такие как ввод/вывод, арифметические операции, и как правильно организовать цикл, что значительно облегчит понимание процесса.