Основы языка ассемблер. Операции ввода/вывода
Похожие презентации:
Основы разработки программы на ассемблере
Организация прерываний. Аппаратные прерывания
Язык Ассемблер
Архитектура ЭВМ и язык ассемблера
Основные компоненты языка Ассемблер
Программирование на Ассемблере
Программирование на языке ассемблер
Основы языка ассемблера
Программная модель микропроцессора INTEL 8080, регистры, форматы и системы команд, методы адресации
Лекции по программированию на ассемблере
1. Основы языка ассемблер
2. Операции ввода/вывода
23. Операции ввода/вывода по прерыванию INT 21H
АН = 01: Ввод с клавиатуры с эхоотображением. Данная функция возвращает значение в регистре 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.
3
4. Работа со стеком
pushdx
;поместить значение
;регистра dx в стек
pop
dx
;записать в dx число
;из стека
4
5. Задача
Вывести значение переменной на экран.1
начало
да
да
Число=0?
cx = 0 ?
нет
Извлечение цифры из
стека
нет
Деление на 10
Вывести число
на экран
Преобразование
остатка в символ
Помещение цифры в
стек
1
конец
5
6. Программа
67. Задача
1. Найти сумму двух чисел введенных с клавиатуры, если сумма < 10.2. Найти сумму двух чисел введенных с клавиатуры для любой суммы.
7
8. Программа
89. ВВОД С КЛАВИАТУРЫ ПО КОМАНДЕ BIOS INT 16H
Команда BIOS INT 16H выполняет специальную операцию, которая в соответствии с кодом в регистреАН обеспечивает следующие три функции ввода с клавиатуры.
АН
= 00: Чтение символа. Данная функция помещает в регистр AL очередной ASCII-символ,
введенный с клавиатуры, и устанавливает скэн-код в регистре АН. Если на клавиатуре нажата одна из
специальных клавиш, например, Home или F1, то в регистр AL заносится ОО. Автоматическое эхо
символа на экран не происходит.
АН
= 01: Определение наличия введенного символа. Данная функция сбрасывает флаг нуля (ZF=0),
если имеется символ для чтения с клавиатуры; очередной символ и скэн-код будут помещены в
регистры AL и АН соответственно и данный элемент останется в буфере.
АН
= 02: Определение текущего состояния клавиатуры. Данная функция возвращает в регистре AL
состояние клавиатуры из адреса памяти 417Н:\
7 Состояние вставки активно (Ins)
3 Нажата комбинация клавиш Alt/Shft
6 Состояние фиксации верхнего регистра (Caps Lock) включено
2 Нажата комбинация клавиш Ctrl/Shft
5 Состояние фиксации цифровой клавиатуры (Num Lock)
включено
1 Нажата левая клавиша Shift
4 Состояние фиксации прокрутки (Scroll Lock) включено
0 Нажата правая клавиша9 Shift
10.
Задания •В цикле ввести символ с клавиатуры и вывести его двоичное представление на экран. Если введен символ *,закончить работу программы.
•В цикле ввести десятичное число с клавиатуры (Функция AH=2 INT 21H). Число десятичных разрядов от 1 до 5.
Признак конца ввода — нажатие клавиши [Ввод] (код 13). Преобразовать число в двоичное и вывести его двоичное
представление на экран.
•В цикле ввести десятичное число с клавиатуры (Функция AH=0AH INT 21H).. Число десятичных разрядов от 1
двоичное представление на экран.
•Введите 8 битов с клавиатуры — последовательность 0 и 1. Выведите на экран преобразованную
последовательность в виде символа ASCII в заданной позиции экрана, которая вводится с клавиатуры (строка,
столбец).
10
English Русский Правила
Учебный курс. Часть 23. Ввод чисел с консоли
В прошлой части мы научились преобразовывать числа в строку и выводить на консоль. А в этой займёмся обратной задачей — вводом чисел с консоли и преобразованием строки в число. Поскольку ввод в двоичном и восьмеричном виде используется редко, я рассмотрю только примеры ввода чисел в десятичном виде (со знаком и без знака) и в шестнадцатеричном.
Вводить числа сложнее, чем выводить, так как помимо преобразования необходимо проверять корректность введённой пользователем строки. Хорошая программа должна устойчиво работать при любых входных данных (в том числе специально введённых так, чтобы нарушить её работу).
Ввод строки с консоли
Для ввода строки можно использовать функцию MS-DOS 0Ah. Функция позволяет ввести строку длиной от 1 до 254 символов. При вызове в DX передаётся адрес буфера, первый байт которого должен содержать максимально допустимую длину строки. Длина считается вместе с символом конца строки CR (0dh). В результате работы функции во второй байт буфера записывается фактическая длина введённой строки (не считая символа CR). Начиная с третьего байта в буфер записываются символы строки. Подробнее о работе функции можно узнать в раритетном справочнике по DOS 🙂
Чтобы удобнее было использовать эту функцию, можно написать небольшую процедуру. Например, такую:
;Процедура ввода строки c консоли ; вход: AL - максимальная длина (с символом CR) (1-254) ; выход: AL - длина введённой строки (не считая символа CR) ; DX - адрес строки, заканчивающейся символом CR(0Dh) input_str: push cx ;Сохранение СX mov cx,ax ;Сохранение AX в CX mov ah,0Ah ;Функция DOS 0Ah - ввод строки в буфер mov [buffer],al ;Запись максимальной длины в первый байт буфера mov byte[buffer+1],0 ;Обнуление второго байта (фактической длины) mov dx,buffer ;DX = aдрес буфера int 21h ;Обращение к функции DOS mov al,[buffer+1] ;AL = длина введённой строки add dx,2 ;DX = адрес строки mov ah,ch ;Восстановление AH pop cx ;Восстановление CX ret . .. buffer rb 256 |
Процедура использует отдельно объявленный буфер. В качестве единственного параметра ей передаётся максимальная длина строки в регистре AL. После возврата из процедуры в этот регистр записывается фактическая длина строки, а в регистр DX — адрес начала строки. Старшая часть AX сохраняется.
Ввод десятичных чисел без знака
Для преобразования числа в строку используется так называемая схема Горнера. Любое число в десятичной системе можно представить в следующем виде:
34710 = 3·102 + 4·101 + 7·100 = (3·10 + 4)·10 + 7
Это очень удобно запрограммировать в цикле: результат сначала умножается на 10, а потом к нему прибавляется очередная цифра и так далее для всех цифр. Кстати, это верно не только для десятичной системы счисления, но и для других, разница только в множителе, который должен быть равен основанию системы счисления.
Следующая процедура преобразует строку в слово в регистре AX. Адрес строки передаётся в DX, длина строки передаётся в AL. Если строка не корректна, процедура возвращает 0 и устанавливает флаг CF. Ошибка возвращается в следующих случаях:
- строка имеет нулевую длину, то есть пустая строка;
- строка содержит любые символы кроме десятичных цифр;
- число находится вне границ диапазона представления чисел (для слова без знака 0…65535).
;Процедура преобразования десятичной строки в слово без знака ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка str_to_udec_word: push cx ;Сохранение всех используемых регистров push dx push bx push si push di mov si,dx ;SI = адрес строки mov di,10 ;DI = множитель 10 (основание системы счисления) movzx cx,al ;CX = счётчик цикла = длина строки jcxz studw_error ;Если длина = 0, возвращаем ошибку xor ax,ax ;AX = 0 xor bx,bx ;BX = 0 studw_lp: mov bl,[si] ;Загрузка в BL очередного символа строки inc si ;Инкремент адреса cmp bl,'0' ;Если код символа меньше кода '0' jl studw_error ; возвращаем ошибку cmp bl,'9' ;Если код символа больше кода '9' jg studw_error ; возвращаем ошибку sub bl,'0' ;Преобразование символа-цифры в число mul di ;AX = AX * 10 jc studw_error ;Если результат больше 16 бит - ошибка add ax,bx ;Прибавляем цифру jc studw_error ;Если переполнение - ошибка loop studw_lp ;Команда цикла jmp studw_exit ;Успешное завершение (здесь всегда CF = 0) studw_error: xor ax,ax ;AX = 0 stc ;CF = 1 (Возвращаем ошибку) studw_exit: pop di ;Восстановление регистров pop si pop bx pop dx pop cx ret |
Для установки флага CF используется команда STC. Сбросить флаг CF можно командой CLC. В коде данной процедуры она не используется, так как в случае успешного завершения цикла флаг CF всегда будет равен 0.
На основе этой процедуры несложно написать ещё одну для ввода чисел размером 1 байт. Сначала строка преобразуется в слово без знака, а затем выполняется проверка старшей части на равенство нулю. Обратите внимание, что команда TEST всегда сбрасывает флаг CF.
;Процедура преобразования десятичной строки в байт без знака ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка str_to_udec_byte: push dx ;Сохранение регистров push ax call str_to_udec_word ;Преобразование строки в слово (без знака) jc studb_exit ;Если ошибка, то возвращаем ошибку test ah,ah ;Проверка старшего байта AX jz studb_exit ;Если 0, то выход из процедуры (здесь всегда CF = 0) xor al,al ;AL = 0 stc ;CF = 1 (Возвращаем ошибку) studb_exit: pop dx mov ah,dh ;Восстановление только старшей части AX pop dx ret |
Следующие две процедуры совмещают ввод строки с преобразованием строки в число. Для слова нужно ввести максимум 5 символов, а для байта — максимум 3.
;Процедура ввода слова с консоли в десятичном виде (без знака) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка input_udec_word: push dx ;Сохранение DX mov al,6 ;Ввод максимум 5 символов (65535) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_udec_word ;Преобразование строки в слово (без знака) pop dx ;Восстановление DX ret |
;Процедура ввода байта с консоли в десятичном виде (без знака) ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка input_udec_byte: push dx ;Сохранение DX mov al,4 ;Ввод максимум 3 символов (255) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_udec_byte ;Преобразование строки в байт (без знака) pop dx ;Восстановление DX ret |
Ввод десятичных чисел со знаком
Ввод чисел со знаком немного труднее. Необходимо проверить первый символ строки: если это символ ‘-‘, то число отрицательное. Кроме того, нужно внимательно проверить диапазон представления (для слова со знаком -32768…32767). Строку без символа ‘-‘ можно преобразовать процедурой для беззнакового числа.
;Процедура преобразования десятичной строки в слово со знаком ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка str_to_sdec_word: push bx ;Сохранение регистров push dx test al,al ;Проверка длины строки jz stsdw_error ;Если равно 0, возвращаем ошибку mov bx,dx ;BX = адрес строки mov bl,[bx] ;BL = первый символ строки cmp bl,'-' ;Сравнение первого символа с '-' jne stsdw_no_sign ;Если не равно, то преобразуем как число без знака inc dx ;Инкремент адреса строки dec al ;Декремент длины строки stsdw_no_sign: call str_to_udec_word ;Преобразуем строку в слово без знака jc stsdw_exit ;Если ошибка, то возвращаем ошибку cmp bl,'-' ;Снова проверяем знак jne stsdw_plus ;Если первый символ не '-', то число положительное cmp ax,32768 ;Модуль отрицательного числа должен быть не больше 32768 ja stsdw_error ;Если больше (без знака), возвращаем ошибку neg ax ;Инвертируем число jmp stsdw_ok ;Переход к нормальному завершению процедуры stsdw_plus: cmp ax,32767 ;Положительное число должно быть не больше 32767 ja stsdw_error ;Если больше (без знака), возвращаем ошибку stsdw_ok: clc ;CF = 0 jmp stsdw_exit ;Переход к выходу из процедуры stsdw_error: xor ax,ax ;AX = 0 stc ;CF = 1 (Возвращаем ошибку stsdw_exit: pop dx ;Восстановление регистров pop bx ret |
Обратите внимание, что для перехода после проверки диапазона используется команда JA (как для сравнения чисел без знака). Ввод байта со знаком реализуется с помощью той же процедуры и дополнительной проверки диапазона значения.
;Процедура преобразования десятичной строки в байт со знаком ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка str_to_sdec_byte: push dx ;Сохранение регистров push ax call str_to_sdec_word ;Преобразование строки в слово (со знаком) jc stsdb_exit ;Если ошибка, то возвращаем ошибку cmp ax,127 ;Сравнение результата с 127 jg stsdb_error ;Если больше - ошибка cmp ax,-128 ;Сравнение результата с -128 jl stsdb_error ;Если меньше - ошибка clc ;CF = 0 jmp studb_exit ;Переход к выходу из процедуры stsdb_error: xor al,al ;AL = 0 stc ;CF = 1 (Возвращаем ошибку) stsdb_exit: pop dx mov ah,dh ;Восстановление только старшей части AX pop dx ret |
Наконец, ещё две процедуры совмещают ввод строки с преобразованием её в слово и байт со знаком.
;Процедура ввода слова с консоли в десятичном виде (со знаком) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка input_sdec_word: push dx ;Сохранение DX mov al,7 ;Ввод максимум 7 символов (-32768) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_sdec_word ;Преобразование строки в слово (со знаком) pop dx ;Восстановление DX ret |
;Процедура ввода байта с консоли в десятичном виде (со знаком) ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка input_sdec_byte: push dx ;Сохранение DX mov al,5 ;Ввод максимум 3 символов (-128) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_sdec_byte ;Преобразование строки в байт (со знаком) pop dx ;Восстановление DX ret |
Полный исходный код примера вы можете скачать отсюда: inputdec. asm. В случае некорректной строки программа выводит сообщение об ошибке и повторяет запрос ввода числа:
Ввод шестнадцатеричных чисел
Преобразование шестнадцатеричной строки в число несколько проще. Удобно реализовать в виде отдельной процедуры преобразование одной цифры. Процедура воспринимает символы ‘A’-‘F’ независимо от регистра. Так как перед вычитанием выполняются проверки, флаг CF всегда будет равен нулю после успешного преобразования.
;Процедура преобразования шестнадцатеричной цифры в число ; вход: DL - символ-цифра ; выход: DL - значение цифры (0-15, в случае ошибки DL = 0) ; CF = 1 - ошибка convert_hex_digit: cmp dl,'0' ;Сравнение с символом '0' jl chd_error ;Если меньше, возвращаем ошибку cmp dl,'9' ;Сравнение с символом '9' jg chd_a_f ;Если больше, то возможно это буква a-f или A-F sub dl,'0' ;Преобразование цифры в число ret ;Возврат из процедуры (здесь всегда CF = 0) chd_a_f: and dl,11011111b ;Преобразование буквы в верхний регистр cmp dl,'A' ;Сравнение с символом 'A' jl chd_error ;Если меньше, возвращаем ошибку cmp dl,'F' ;Сравнение с символом 'F' jg chd_error ;Если больше, возвращаем ошибку sub dl,'A'-10 ;Преобразуем букву в число ret ;Возврат из процедуры (здесь тоже всегда CF = 0) chd_error: xor dl,dl ;DL = 0 stc ;CF = 1 ret ;Возврат из процедуры |
Теперь легко можно написать преобразование шестнадцатеричной строки в слово. Вместо умножения на 16 в процедуре используется сдвиг на 4 бита влево, а вместо сложения — операция ИЛИ. Проверки диапазона значения не нужны, достаточно проверить длину строки и преобразовать цифры.
;Процедура преобразования шестнадцатеричной строки в слово ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка str_to_hex_word: push cx ;Сохранение регистров push dx push si movzx cx,al ;CX = счётчик цикла = длина строки jcxz sthw_error ;Если длина строки = 0, возвращаем ошибку cmp cx,4 jg sthw_error ;Если длина строки больше 4, возвращаем ошибку xor ax,ax ;AX = 0 mov si,dx ;SI = адрес строки sthw_lp: mov dl,[si] ;Загрузка в DL очередного символа строки inc si ;Инкремент адреса строки call convert_hex_digit ;Преобразование шестнадцатеричной цифры в число jc sthw_error ;Если ошибка, то возвращаем ошибку shl ax,4 ;Сдвиг AX на 4 бита влево or al,dl ;Добавление преобразованной цифры loop sthw_lp ;Команда цикла jmp sthw_exit ;CF = 0 sthw_error: xor ax,ax ;AX = 0 stc ;CF = 1 sthw_exit: pop si ;Восстановление регистров pop dx pop cx ret |
Для ввода байта используется та же процедура, но дополнительно проверяется длина строки — она должна быть не больше 2.
;Процедура преобразования шестнадцатеричной строки в байт ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка str_to_hex_byte: push cx ;Сохранение CX mov cx,ax ;Сохранение AX в CX cmp al,2 ;Проверка длины строки jg sthb_error ;Если больше 2, возвращаем ошибку call str_to_hex_word ;Преобразование строки в слово jnc sthb_exit ;Если нет ошибки, то переход к выходу из процедуры sthb_error: stc ;CF = 1 sthb_exit: mov ah,ch ;Восстановление AH pop cx ;Восстановление CX ret |
Ещё две процедуры для ввода и преобразования строки, также как для десятичного ввода:
;Процедура ввода слова с консоли в шестнадцатеричном виде ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка input_hex_word: push dx ;Сохранение DX mov al,5 ;Ввод максимум 4 символов (FFFF) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_hex_word ;Преобразование строки в слово pop dx ;Восстановление DX ret |
;Процедура ввода байта с консоли в шестнадцатеричном виде ; выход: AL - байт (в случае ошибки AL = 0) ; CF = 1 - ошибка input_hex_byte: push dx ;Сохранение DX mov al,3 ;Ввод максимум 2 символов (FF) + конец строки call input_str ;Вызов процедуры ввода строки call str_to_hex_byte ;Преобразование строки в байт pop dx ;Восстановление DX ret |
Полный исходный код примера: inputhex. asm. Как и в примере с десятичными числами, программа повторяет запрос ввода, пока не будут введены корректные данные:
Упражнение
Напишите программу для ввода байта с консоли в двоичном виде. Желательно с проверкой корректности ввода 🙂 Результаты можете писать в комментариях.
Ещё раз ссылки на примеры:
- inputdec.asm — ввод десятичных чисел с консоли (со знаком и без)
- inputhex.asm — ввод шестнадцатеричных чисел с консоли
Следующая часть »
5.2.4. Ввод и вывод чисел
http://www.sklyaroff.ru | 92 |
Физически команда просто вычитает операнд из нуля (операнд = 0 – операнд). При этом выполняются все правила представления чисел со знаком, о которых мы говорили выше, т. е. числа конвертируются в двоичный дополнительный код.
Команда NEG изменяет состояние следующих флагов: CF (флаг переноса), ZF (флаг нуля), SF (флаг знака), OF (флаг переполнения), AF (флаг служебного переноса), PF (флаг четности). Эти флаги можно использовать для анализа полученного результата.
Команду NEG удобно использовать для получения абсолютного значения числа следующим образом:
Mark: neg AX jl Mark
Если знак числа отрицательный будет выполнен переход на первую команду еще раз.
При работе с числами на ассемблере перед каждым программистом встает вопрос, как осуществлять ввод и вывод чисел в программе? Действительно, ввод осуществляется в ASCII-кодах, а вычисления нужно производить с обычными числами; результат вычислений на экран вновь нужно выводить в ASCII-кодах.
Таким образом, при работе с числами в программе на ассемблере необходимы две процедуры: первая должна преобразовывать введенные пользователем числа из ASCII-формата в бинарные числа, а вторая процедура должна наоборот преобразовывать результат вычислений в ASCII-коды для вывода на экран. К сожалению, стандартных команд, которое бы это делали, не существует. В листинге 5.1 вы можете видеть программу, которая запрашивает два числа, складывает их и выводит результат на экран.
В этой программе процедура str2int преобразовывает каждое число из буфера в ASCII-формате в соответствующие бинарное число.
Другая процедура int2str преобразовывает бинарное число (результат вычисления) в число в системе счисления base в ASCII-формате.
Обращаю ваше внимание, что авторство на данные процедуры принадлежит не мне (если авторы объявятся, я укажу их в переиздании этой книги).
К настоящему времени весь код программы вы должны в состоянии понять самостоятельно, а комментарии вам в этом помогут.
Ассемблирование и линковка выполняется обычным образом: ml numascii.asm
Листинг 5.1. Программа, демонстрирующая ввод и вывод чисел (numascii.asm)
.model small
.stack 100h
| .data |
|
mess1 | db «Введите число #1: «,’$’ | |
mess2 | db «Введите число #2: «,’$’ | |
mess3 | db «Результат: «,’$’ |
|
mess4 | db «Ошибка ввода $» |
|
crlf | db 0Dh,0Ah,’$’ | ; перевод строки |
n | db 5 | ; максимальный размер буфера ввода |
nlength db 0 | ; здесь будет размер буфера после считывания | |
ncontents db 5 dup (?) | ; содержимое буфера | |
buff | db 100 dup(0),’$’ | ; размер буфера для преобразования числа |
table1 | db ‘0123456789ABCDEF’ | ; таблица соответствия |
base | dw 10 | ; указываем систему счисления в которой |
|
| ; желаем выводить числа |
|
| ; например: 10 — десятичная, 2 -двоичная, |
http://www. sklyaroff.ru | 93 | |
.code | ; 16 — шестнадцатеричная |
|
|
| |
; процедура вывода строки на экран |
| |
output PROC |
|
|
mov | ah,9 |
|
int | 21h |
|
ret |
|
|
output ENDP |
|
|
;процедура считывания введенной строки,
;которая помещается в буфер ncontents input PROC
mov | ah,0Ah |
int | 21h |
ret |
|
input ENDP |
|
;процедура преобразования числа в ASCII-формате
;из буфера ncontents в соответствующее бинарное число,
;результат преобразования помещается в AX
str2int PROC |
|
|
xor | di,di | ; DI указывает номер байта в буфере |
xor | ax,ax |
|
mov | cl,nlength |
|
xor | ch,ch |
|
xor | bx,bx |
|
mov | si,cx | ; в SI длина буфера |
mov | cl,10 | ; множитель для MUL |
next1: |
|
|
mov | bl,byte ptr ncontents[di] ; взять байт из буфера | |
sub | bl,’0′ | ; вычитаем ASCII-код символа ‘0’ |
jb | error1 | ; если код символа меньше, чем код ‘0’ |
cmp | bl,9 | ; или больше, чем ‘9’ |
ja | error1 | ; выходим из программы с сообщением об |
ошибке |
|
|
mul | cx | ; умножаем значение в AX на 10 |
add | ax,bx | ; добавляем к нему новую цифру |
inc | di | ; увеличиваем счетчик |
cmp | di,si |
|
jb | next1 |
|
ret |
|
|
error1: |
|
|
mov | dx,offset mess4 | |
mov | ah,9 |
|
int | 21h |
|
jmp | exit |
|
str2int ENDP |
|
|
;процедура вывода на экран числа в системе счисления base
;число передается в процедуру в регистре AX, а
;адрес результата помещается в DX
int2str PROC
http://www. sklyaroff.ru | 94 |
; сначала очищаем буфер (заполняем нулями)
xor | di,di |
mov | cx,99 |
zeroizing: |
|
mov | byte ptr buff[di],0 |
inc | di |
loop zeroizing |
|
;заносим в di адрес последнего байта буфера,
;т. к. буфер будет заполняться от конца к началу
xor | di,di |
mov | di,offset buff+99 |
;цикл получения цифр числа путем вычисления остатков
;от деления на основание системы
next2: xor | dx,dx |
|
|
div | base |
|
|
mov | si,offset table1 |
| |
add | si,dx |
|
|
mov | dl,[si] |
|
|
mov | [di],dl |
|
|
dec | di |
|
|
cmp | ax,0 | ; если AX не равно 0 повторяем цикл | |
jnz | next2 |
|
|
mov | dx,di | ; в DX заносим адрес результата | |
ret |
|
|
|
int2str ENDP |
|
|
|
start: mov | ax,@data |
|
|
mov | ds,ax |
|
|
mov | dx,offset mess1 | ; запрос первого числа | |
call | output |
|
|
mov | dx,offset n |
| ; принимаем ввод первого числа |
call | input |
|
|
mov | dx,offset crlf |
| ; перевод строки |
call | output |
|
|
call | str2int |
| ; преобразование ASCII-строки в число |
|
|
| ; (результат помещается в AX) |
push | ax |
| ; сохраняем первое число в стек |
mov | dx,offset mess2 | ; запрос второго числа | |
call | output |
|
|
mov | dx,offset n |
| ; принимаем ввод второго числа |
call | input |
|
|
http://www. sklyaroff.ru |
|
| 95 | |
call | str2int |
| ; преобразование ASCII-строки в число | |
|
|
| ; (результат помещается в AX) | |
pop | bx | ; восстанавливаем первое число из стека | ||
add | ax,bx | ; складываем числа | ||
push | ax | ; сохраняем результат в стек | ||
mov | dx,offset crlf |
| ; перевод строки | |
call | output |
|
|
|
mov | dx,offset mess3 | ; сообщение о выводе результата | ||
call | output |
|
|
|
pop | ax |
| ; восстанавливаем результат из стека | |
call | int2str |
| ; преобразовываем в ASCII-строку | |
call | output |
| ; выводим результат на экран | |
exit: |
|
| ; выходим из программы | |
mov | ax,4C00h |
|
|
|
int | 21h |
|
|
|
end | start |
|
|
|
5. 2.5. Команды, работающие с целыми BCDчислами
Выше я уже говорил, что команды целочисленных операций, предназначенные для работы с обычными двоичными числами, будут неправильно работать с BCDчислами и наоборот. Пример сложения двух неупакованных BCD-чисел 5 и 6 с помощью команды ADD:
5 = 0000 0101
6 = 0000 0110
11 = 0000 1011
Однако в BCD-формате число 11 должно быть представлено как 0000 0001 0000 0001.
Разработчики микропроцессоров решили не вводить специальные команды для работы с BCD-числами, а ввести только несколько корректировочных команд.
Для корректировки сложения и вычитания неупакованных BCD-чисел имеются две команды:
AAA (ASCII Adjust for Addition) — коррекция результата сложения для представления в символьном виде;
AAS (ASCII Adjust for Subtraction) — коррекция результата вычитания для представления в символьном виде.
Команды AAA и AAS преобразуют содержимое регистра AL в правильную неупакованную десятичную цифру. Если результат корректировки превышает 9, то эти команды добавляют (вычитают — AAS) к содержимому регистра AH и устанавливают флаги CF и OF. Данные корректирующие команды лучше сразу использовать после команды сложения (вычитания) чисел.
Пример корректировки сложения: mov ax,5
mov bx,6
Assembler Lab N4
Вывод на печатающее устройствотекст программы в редакторе
Цели работы:
1.Изучить систему прерываний МП фирмы Intel
2.Изучить основные функции прерываний BIOS (10h) и DOS (21h)
3.Набрать программу WWYDS.ASM,получить EXE-файл и проверить ее работоспособность
4.Исследовать подпрограмму WWOD ввода символов с клавиатуры в память с индикацией их на экране
5.Исследовать макроопределение WYD вывода на экран 16-разрядных двоичных чисел
Основные положения для отработки на занятии
——————————————-
1. Назначение системы прерываний,структура системы прерываний на базе МП фирмы Intel
2. Основные функции прерывания BIOS 10h,которые предназначены для управления монитором:
02h — установка курсора в требуемое место экрана
03h — определение положения курсора на экране
06h — прокрутка окна вверх
07h — прокрутка окна вниз
08h — чтение в текущем месте экрана символа и его
атрибута
0ah — вставка в текущее место экрана символ с его
атрибутом
0fh — прочитать параметры текущего видеорежима
3. Основные функции прерывания DOS 21h,которые предоставляют не которые услуги пользователю со стороны операционной системы:
01h — ввод символа с эхо на экране
02h — вывод символа на экран
05h — вывод символа на принтер
09h — вывод строки символов на экран
0ah — ввод строки символов с клавиатуры ?
3fh — ввод строки символов с клавиатуры
4. Изучить последовательность действий пользователя при использовании прерываний:
— поместить номер функции (они указаны в пп.2,3) в регистр AH
— поместить передаваемые параметры для функции
в заранее определенные системой регистры
— вызвать прерывание ассемблерными командами INT 10h или INT 21h
— извлечь результаты из определенных регистров
5. Получить ЕХЕ-файл программы с названием WWYDS.ASM и проверить его работу по вводу с клавиатуры символов(которые затем пре образуются в 16-разрядные двоичные числа) и выводу этих чисел на экран.
С Т Р О Г О С О Б Л Ю Д А Т Ь ПРАВИЛА
————————————
следующие правила при работе с программой:
——————————————
а). вводить только положительные 5-разрядные десятичные числа без знака в диапазоне
00000 — 65535
б). незначащие нули в начале числа вводить обязательно.
в). при отладке с помощью AFDPRO.EXE(или AFD.EXE) для пошагового исполнения команд INT следует использовать клавишу F2 (т.к. команда представляет собой процедуру).
Несоблюдение этих правил может привести к неверным результатам!
Программа WDWH.ASM
———————
; Программа с макроопределением вывода 16-разрядных чисел
; в 16-й системе счисления и подпрограммой ввода 5-разрядных
; десятичных чисел (файл wdwh.asm).
;—————————————————————-
.model small
;—————————————————————-
; Макроопределение вывода на экран слов в 16-й системе :
;—————————————————————-
wyh macro wt ; wt — слово в памяти или константа
local m10
push ax
push bx
push cx
push dx
push di
push bp
;. …………………………
mov
mov
mov
mov
;………………………….
m10: mov
and
mov
shr
dec
shl
;………………………….
shr
;………………………….
xlat
mov
mov
;………………………….
mov ah,02h
int 21h
;………………………….
dec di
dec di
cmp di,0
jnz m10
;………………………….
mov dx,offset spc
mov ah,9
int 21h
;………………………….
pop bp
pop di
pop dx
pop cx
pop bx
pop ax
;………………………………………………….
endm ; Конец макроопределения
;———————————————————-
.stack ; Сегмент стека
;———————————————————
.data? ; Сегмент данных
z dw ? ; (неопределенные данные)
x db 8 dup(?)
;———————————————————-
. data ; (определенные данные)
spc db 10,13,’$’ ; управляющие символы
; перевод строки 10
; возврат каретки 13
; конец текстовой строки $
;…………………………………
cw dw 0,000fh,00f0h ; константы для выреза-
dw 0f00h,0f000h ; ния 4-битных кодов
;…………………………………
tab db 30h,31h,32h,33h ; символы
db 34h,35h,36h,37h ; цифр
db 38h,39h,41h,42h ; шестнадцатиричной
db 43h,44h,45h,46h ; системы счисления
; ………………………………..
ct dw 10000 ; веса разрядов
dw 1000 ; 5-ти разрядных
dw 100 ; десятичных
dw 10 ; чисел
dw 1 ;
;———————————————————-
.code ; Сегмент кода(программа)
;__________________________________________________________
; Подпрограмма ввода с клавиатуры строки из 5 символов :
; Используются символы только десятичных цифр 0,1,2,..,9 :
;__________________________________________________________
wwod: push bx
push cx
push dx
push si
push di
mov ah,3fh
mov bx,00
mov cx,08h
mov dx,offset x
int 21h
mov bx,0
mov cx,5
mov si,offset ct
mov di,offset x
m1: mov al,[di]
and al,0fh
mov ah,0
mul word ptr [si]
add bx,ax
inc di
add si,2
loop m1
mov z,bx
pop di
pop si
pop dx
pop cx
pop bx
ret
;. ……………………………………………..
.startup ; Точка входа в программу
call wwod
wyh z
.exit
;………………………………………………
end
Программа WWDS.ASM
———————
; Программа ввода с клавиатуры 5-разрядных десятичных чисел
; и вывода на экран слов в двоичной системе
;———————————————————-
.model small
.stack
;————————————
.data?
z dw ?
x db 8 dup(?)
;————————————
.data
spc db 10,13,’$’
ct dw 10000
dw 1000
dw 100
dw 10
dw 1
;———————————————————-
; Макроопределение вывода двоичных слов на экран :
;———————————————————-
wyd macro wt ; слово в памяти или константа
local m11,m12
push ax
push cx
push dx
;. ……………………………..
mov cx,8000h
mov ax,wt
;………………………………
m11: push ax
mov dx,’1′
test ax,cx
jnz m12
mov dx,’0′
;………………………………
m12: mov ah,2h
int 21h
;………………………………
pop ax
shr cx,1
jnz m11
;………………………………
mov dx,offset spc
mov ah,9
int 21h
;………………………………
pop dx
pop cx
pop ax
;………………………………
endm
;———————————————————-
.code ; Начало кодового сегмента
;———————————————————-
; Подпрограмма ввода с клавиатуры строки символов :
;———————————————————-
wwod: push bx
push cx
push dx
mov ah,3fh
mov bx,00
mov cx,08h
mov dx,offset x
int 21h
pop dx
pop cx
pop bx
ret
;.. …………………………….
.startup
;………………………………
call wwod
mov dx,0
mov bx,0
mov cx,5
mov si,offset ct
mov di,offset x
m1: mov al,[di]
and al,0fh
mov ah,0
mul word ptr [si]
add bx,ax
inc di
add si,2
loop m1
mov z,bx
wyd z
.exit
;………………………………
end
Вывод на печатающее устройство
;…………………………………………………
; Программа вывода на принтер двоичного числа
; с макроопределением PRNT
;…………………………………………………
.model small
.stack
.data
x db 20
y db 30
z db 0
text db ‘z=……..’
db 0dh,0ah
;…Макроопределение вывода на принтер………………..
prnt macro mas ; заголовок макроопределения
mov ah,40h ; функция вывода строки
mov bx,04 ; номер устройства вывода
mov cx,12 ; количество выводимых символов
lea dx,mas ; начальный адрес выводимой строки
int 21h ; команда прерывания DOS
endm ; конец макроопределения
;. ………………………………………………..
;….Начало программного(кодового) сегмента….. ………
.code
.startup ; точка входа в программу
mov al,x
add al,y
mov z,al
lea bx,text+2
call zbyte
prnt text
.exit ; точка выхода в DOS
;….Подпрограмма формирования двоичных цифр…………..
zbyte: mov cx,8
m1: rol al,1
mov byte ptr[bx],30h
jnc m2
mov byte ptr[bx],31h
m2: inc bx
loop m1
ret ; конец подпрограммы
;…………..Конец программы……………………….
end
Word 97 *.doc
| ||||
|
Программа на языке Ассемблер.
Подпрограмма, преобразующую произвольное число из AX в формат упакованного BCDДругие предметы \ Объектно ориентированное програмирование
Страницы работы
5 страниц (Word-файл)
Посмотреть все страницы
Скачать файл
Содержание работы
Задание
Написать программу на языке Ассемблер, выполняющую следующие действия: программа принимает с клавиатуры целое число, введенное в одном из форматов: в двоичном, восьмеричном, десятичном, шестнадцатеричном или троичном. К этому числу она прибавляет некоторое заданное в тексте программы число и либо выводит результат на экран в одном из указанных форматов, либо преобразует его в формат BCD и затем выводит его десятичное представление. Предполагается, что все числа беззнаковые, и при выходе значения числа за пределы 0-65535 старшие разряды теряются.
Варианты
Ниже в клетках указаны номера вариантов. Вверху — формат числа, введенного с клавиатуры. Слева – формат вывода или формат, в который предварительно преобразовывается результат сложения.
Ввод |
2-ный |
8-ный |
10-ный |
16-ный |
3-ный |
|
Вывод |
||||||
Двоичный |
1 |
7 |
13 |
19 |
25 |
|
Восьмеричный |
2 |
8 |
14 |
20 |
26 |
|
Десятичный |
3 |
9 |
15 |
21 |
27 |
|
Шестнадцатеричный |
4 |
10 |
16 |
22 |
28 |
|
BCD-неупакованный |
5 |
11 |
17 |
23 |
29 |
|
BCD-упакованный |
6 |
12 |
18 |
24 |
30 |
Пример 1
Пусть с клавиатуры вводится пятеричное число, к которому надо прибавить число 129 и результат преобразовать в неупакованный BCD-формат. Ввод, преобразование и вывод чисел описаны в пп. 5.3. и 5.4. Введенное число не больше 65535 и, значит, состоит не более чем из семи пятеричных цифр. Поэтому для ввода числа надо организовать цикл, который будет выполняться не более семи раз. В этом цикле введенное число будет формироваться в регистре bx, а его значение с вводом цифр будет формироваться по формуле
bx = 5*bx + цифра
Для преобразования в неупакованный формат BCD число делится на 10 и остаток записывается в младший байт строки, представляющей неупакованный формат BCD. Затем вновь результат делится на 10 и остаток записывается в следующий байт строки. Эту операцию достаточно произвести 5 раз. После этого преобразования полученная строка выводится на экран. Ее символы выводятся в обратном порядке, ибо байты с меньшими адресами содержат младшие цифры полученного числа. Выход из программы – CTRL/C.
Программа
< 1 > title u5bcd. exe — from 5 to BCD unpacked
< 2 > code SEGMENT
< 3 > assume cs:code, ds:code
< 4 > main:
< 5 > mov ax,code
< 6 > mov ds,ax
< 7 > again:
< 8 > mov si,5 ;пятеричное число
< 9 > mov bx,0 ;формируем значение в BX
< 10 > mov dl,’?’ ;подсказка
< 11 > call display
< 12 > mov cx,7 ;семь цифр, не более
< 13 > next:
< 14 > call kbin ;ввод символа в AL
< 15 > cmp al,’ ‘ ;ввод до знака
< 16 > je back ;пробела
< 17 > mov ah,0
< 18 > and al,00001111b ;ASCII-код ->цифра
< 19 > mov di,ax
< 20 > mov ax,bx
< 21 > mul si
< 22 > add ax,di ;AX = 5*BX + цифра
< 23 > mov bx,ax
< 24 > loop next
< 25 > back:
< 26 > mov dl,’=’
< 27 > call display
< 28 > mov ax,bx
< 29 > add ax,129
< 30 > call pbcdn ;преобразование в BCD неупакованный
< 31 > call crlf ;с новой строки
< 32 > jmp again ;ввод нового числа
< 33 >
< 34 > pbcdn proc ;AX в BCD неупакованный
< 35 > mov di,0
< 36 > mov cx,5 ;пять цифр
< 37 > mov si,10 ;делитель
< 38 > a10:
< 39 > mov dx,0
< 40 > div si ;(DX:AX)/SI->AX, остаток в DX
< 41 > add dl,’0′
< 42 > mov [di+offset bcdn],dl ;запись цифры
< 43 > inc di
< 44 > loop a10
< 45 > lea bx,bcdn
< 46 > mov cx,10
< 47 > mov si,9 ;начиная со старших
< 48 > a20:
< 49 > mov dl,[bx+si] ;выводим цифры
< 50 > call display ;строки BCD
< 51 > dec si
< 52 > loop a20
< 53 > ret
< 54 > bcdn db 10 dup(‘0’)
< 55 > pbcdn endp
< 56 >
< 57 > display proc ;подпрограмма вывода
< 58 > mov ah,2 ;символа на экран
< 59 > int 21h ;из регистра DL
< 60 > ret
< 61 > display endp
< 62 >
< 63 > kbin proc ;подпрограмма ввода
< 64 > mov ah,1 ;символа в AL
< 65 > int 21h ;с клавиатуры
< 66 > ret
< 67 > kbin endp
< 68 >
Похожие материалы
Информация о работе
Скачать файл
Уроки по С++, Урок 6.
Чтение ввода с клавиатурыВ этой книге ваши программы использовали выходной поток cout для отображения вывода на экран. Из данного урока вы узнаете, что C++ обеспечивает входной поток с именем cin, из которого программы могут читать информацию, введенную пользователем с клавиатуры. При использовании cin для чтения ввода с клавиатуры вы указываете одну или несколько переменных, которым cin будет присваивать входные значения. К тому времени, когда вы закончите этот урок, вы освоите следующие основные концепции:
- Вы можете использовать входной поток cin для присваивания определенным переменным символов и чисел, введенных с клавиатуры.
- При применении cin для чтения и присваивания переменной значения, введенного с клавиатуры, можно использовать содержимое переменной так, как если бы ваша программа использовала оператор присваивания для сохранения значения в переменной.
- Когда ваша программа использует cin для выполнения ввода с клавиатуры, остерегайтесь ошибок переполнения и ошибок, возникающих при вводе пользователем значения неверного типа.
Как вы уже знаете, если ваши программы используют выходной поток cout, они помещают данные в поток с помощью оператора вставки (<<). Подобным образом, если ваши программы применяют cin для чтения ввода с клавиатуры, они будут использовать оператор извлечения (>>).
ПЕРВОЕ ЗНАКОМСТВО С cin
Точно так же как выходной поток cout позволяет вашим программам записать вывод на экран, входной поток cin позволяет программам читать ввод с клавиатуры. Когда программы используют cin для чтения ввода с клавиатуры, они должны указать переменную, в которую cin поместит данные. Следующая программа FIRSTCIN.CPP использует cin для чтения числа, введенного с клавиатуры. Программа присваивает введенное число переменной с именем number, а затем выводит значение переменной, используя выходной поток cout:
#include <iostream.h>
void main(void)
{
int number; II Число, читаемое с клавиатуры
cout << «Введите ваше любимое число и нажмите Enter: «;
cin >> number;
cout << «Ваше любимое число равно » << number << endl;
}
Когда вы откомпилируете и запустите эту программу, на вашем экране появится сообщение, предлагающее вам ввести ваше любимое число. Если вы введете число и нажмете ENTER, программа присвоит ввод переменной number. Затем, используя cout, программа выведет сообщение, отображающее ваше любимое число.
Следующая программа TWONBRS.CPP запрашивает у вас два числа. Программа присваивает числа переменным first и second. Затем программа выводит числа, используя cout:
#include <iostream.h>
void main(void)
{
int first, second; // Числа, введенные с клавиатуры
cout << «Введите два числа и нажмите Enter: «;
cin >> first >> second;
cout << «Были введены числа » << first << » и » << second << endl;
}
Обратите внимание на использование с cin двух операторов извлечения:
cin >> first >> second;
В этом случае cin присвоит первое введенное значение переменной first, a второе переменной second. Если для вашей программы требуется третье значение, вы можете использовать третий оператор извлечения, как показано ниже:
cin >> first >> second >> third;
Если вы применяете cin для чтения чисел с клавиатуры, cin использует левый пустой символ (пробел, табуляцию, возврат каретки), чтобы определить, где начинается одно значение, а где второе. Экспериментируйте с программой TWONBRS, разделяя числа табуляцией, пробелом и возвратом каретки.
Чтение ввода с клавиатуры с помощью cin
Для чтения ввода с клавиатуры программы могут использовать входной поток cin. При использовании cin вы должны указать переменную, в которую cin помещает данные. Затем используйте оператор извлечения (>>) для направления данных, как показано ниже:
cin >> some_variable;
Оператор извлечения называется так, потому что он извлекает (удаляет) данные из входного потока, присваивая значение указанной переменной.
Следите за ошибками переполнения
Если ваши программы выполняют ввод с использованием cin, остерегайтесь возможных ошибок, возникающих при вводе пользователем неверного числа. Например, запустите программу FIRSTCIN, которую вы только что создали. Когда программа запросит вас ввести ваше любимое число, введите число 1000000 и нажмите ENTER. При этом программа не сможет отобразить число 1000000 в качестве введенного значения. Вместо этого возникнет ошибка переполнения, так как 1000000 превышает наибольшее значение, которое может хранить тип int.
Если вы внимательно рассмотрите программу FIRSTCIN. CPP, то обратите внимание, что cin присваивает введенное число переменной типа int. Как вы узнали из урока 4, переменные типа int могут хранить значения только в диапазоне от -32768 до 32767. Поскольку переменная типа int не может вместить значение 1000000, возникает ошибка. Запустите программу еще несколько раз, вводя отрицательные и положительные числа. Обратите внимание на ошибки, которые возникают, если вы выходите за допустимые пределы значений для той переменной, в которую cin помещает ввод.
Следите за ошибками несовпадения типов
Как уже обсуждалось, программа FIRSTCIN. CPP предполагает, что пользователь вводит значение в диапазоне от -32768 до 32767. Если вместо ввода числа вне этого диапазона, пользователь вводит буквы или другие символы, то возникает другая ошибка — ошибка несовпадения типов. Другими словами, программа ожидала значение одного типа (int), а пользователь ввел значение другого типа (char). Для примера запустите программу второй раз. Когда программа запросит число, введите буквы АВС. Как и раньше, возникнет ошибка, поскольку программа ожидает целое число, а не буквы.
Выполните подобные эксперименты с программой TWONBRS, вводя бессмысленные значения или числа с плавающей точкой. Вы обнаружите, что программа наталкивается на те же ошибки. В последующих уроках вы научитесь выполнять операции ввода таким образом, чтобы уменьшить возможность подобных ошибок. А сейчас просто помните, что такие ошибки могут возникать.
Чтение символьных данных
Обе предыдущие программы использовали cin для чтения целых чисел в переменные типа int. Следующая программа CIN_CHAR.CPP использует входной поток cin для чтения символов с клавиатуры. Как видите, программа читает символ в переменную типа char.
#include <iostream.h>
void main(void)
{
char letter;
cout << «Введите любой символ и нажмите Enter: «;
cin >> letter;
cout << «Был введен символ » << letter << endl;
}
Откомпилируйте и поэкспериментируйте с данной программой, вводя более одного символа и наблюдая за реакцией программы. Вы обнаружите, что программа каждый раз работает только с одним символом.
Чтение слов с клавиатуры
Во второй части данной книги вы научитесь сохранять слова или даже строки текста в одной переменной. Там же вы узнаете, как использовать входной поток cin для чтения слов и целых строк. А сейчас можете создать свою собственную простую программу, которая читает значения типа float или long. Например, следующая программа CIN_LONG.CPP использует cin для чтения значения типа long:
#include <iostream.h>
void main(void)
{
long value;
cout << «Введите большое число и нажмите Enter: «;
cin >> value;
cout << «Было введено число » << value << endl;
}
Как и раньше, поэкспериментируйте с этой программой, вводя очень большие числа (и отрицательные тоже).
ЧТО ВАМ НЕОБХОДИМО ЗНАТЬПеренаправление В/В и входной поток cin
Как вы уже знаете из урока 3, если ваши программы используют выходной поток cout, пользователь может перенаправить вывод программы с экрана дисплея в файл или на принтер. Как уже обсуждалось, выходной поток cout соответствует стандартному выводу операционной системы. Подобным образом входной поток cin соответствует стандартному вводу операционной системы. В результате, если ваша программа использует cin для выполнения операций ввода, пользователь может перенаправить ввод программы с клавиатуры на файл. В последующих уроках вы научитесь писать программы, которые читают и обрабатывают перенаправленный ввод.
В этом уроке вы научились использовать входной поток cin для выполнения ввода с клавиатуры. Как вы уже знаете, если ваши программы используют cin для чтения ввода с клавиатуры, вам следует указать переменные, которым cin присваивает вводимые значения. В уроке 7 вы научитесь использовать оператор C++ if, чтобы позволить программам принимать собственные решения. Однако перед тем, как приступить к уроку 7, убедитесь, что вы освоили следующие основные концепции:
- C++ предоставляет входной поток cin, который ваши программы могут использовать для чтения ввода с клавиатуры.
- Если программы для чтения ввода используют cin, они должны указать одну или несколько переменных, в которые cin будет помещать данные.
- Чтобы направить ввод в переменную, вам следует использовать cin с оператором извлечения (>>).
- При применении cin для чтения нескольких значений, cin использует пустые символы (пробел, табуляция или возврат каретки), чтобы определить, где заканчивается одно значение и начинается другое.
- Если пользователь вводит неверные данные, могут возникать ошибки переполнения или несоответствия типов, а значения, присвоенные входным потоком cin переменным вашей программы, будут неверны.
Использование буферизованного ввода с клавиатуры DOS. Исходный код включен.
Использование буферизованного ввода с клавиатуры DOS. Исходный код включен.---------- > [....] Мой вопрос, [как] использовать функцию DOS для > ввод с клавиатуры (0Ah), затем напишите программу, позволяющую пользователю > ввести строку, а затем вывести строку обратно на экран > используя функцию (09h). > > Спасибо > > Билл > > Служба DOS int 21h 0Ah — одна из немногих, которые действительно являются службами. Это позволяет пользователю вводить строку символов, при этом он может использовать клавишу Backspace для исправления ошибок и других тонкостей как таковых. Во-первых, сервису 0Ah нужно немного информации, прежде чем он сможет начать работать. Ему нужен небольшой буфер для хранения строки после того, как пользователь нажал клавишу ввода. Эта служба также нуждается в другом байте информации. Рабочая длина этого буфера. т. е. допустимая длина строки. Давайте начнем. ; Этот листинг на ассемблере собран с использованием NBASM версии 00.22.8x. ; Чтобы получить NBASM, бесплатный ассемблер, перейдите по ссылке: ; https://www. fysnet.net/newbasic.htm .модель крошечная .код ; сначала давайте напечатаем строку на экране, позволяя ; пользователь нет, что мы хотим, чтобы он/она ввел строку ; Я обсужу услугу печати позже mov dx, смещение FirstS мов ах, 09час через 21 час ; Несмотря на то, что этой службе требуется местоположение (смещение) ; наш буфер в DX, нам нужен регистр BASE для доступа ; отдельные байты в этом буфере. Итак, давайте поместим смещение в ; БХ. (читайте ниже о том, какой размер буфера нам нужен) mov bx,offset ; Однако для меньшего кода поместим смещение ; также в DX. ; (mov dx,bx на один байт меньше, чем mov dx,offset OurBuff) мов дх, бх ; нам нужно сообщить сервису 0Ah, что мы хотим разрешить до ; 32 символа в нашей строке. Это делается путем ввода 33 в ; первый байт буфера. Почему 33? 32 символа плюс ; клавишу <Ввод>. байт перемещения [bx], 33 ; теперь мы можем вызвать службу (прерывание), поэтому DOS выполнит ; процедура пользовательского ввода. мов ах,0Ах через 21 час ; Как только пользователь вводит строку и нажимает, DOS ; возвращается к этому моменту. Теперь мы можем делать с этим что хотим ; нить. ; Поскольку вы упомянули, что хотите напечатать строку в ; скрин с помощью сервиса 09h, нам придется сделать некоторые манипуляции ; on являются недавно полученной строкой. ; Сначала напечатаем еще одну строку, обозначающую для пользователя, ; строка для печати. mov dx, смещение секунды мов ах, 09h через 21 час ; Службе 09h также требуется смещение буфера (строка) в DX. ; Но, как было сказано ранее, нам нужен базовый регистр для доступа к отдельным ; байт строки. mov bx,offset ; Также сервис 09h нужен «$» (знак доллара) в конце строки ; обозначая «конец строки», чтобы служба прекратила здесь печать. ; Куда мы поместим этот «$»? Ну, мы знаем, что сервис 0Ah выше ; возвращает фактическую длину строки в байтовой позиции два из ; рабочий буфер. переместить ал,[bx+1] ; AL теперь содержит фактическую длину строки. ; Помните, что смещения отсчитываются от нуля, а [bx+1] — это секунды. ; положение в буфере. ; Теперь мы хотим поместить «$» в конец строки, чтобы служба ; 09h перестанет печатать в конце нашей строки. ; Помните, что строка на самом деле не начинается в начале ; нашего буфера. Он начинается со смещения 02h или с третьей позиции. Так ; нам нужно добавить 2 к длине, чтобы добраться до конца строки. добавить al,02 ; Теперь, когда мы знаем смещение от начала буфера ; где поставить '$', мы должны поместить его туда. ; Помните, что с ассемблером 8086 мы не можем поставить 8-битный регистр ; в 16-битный регистр, поэтому мы должны сначала очистить AH ; Затем нам нужен еще один базовый (или индексный) регистр для хранения этого значения. хор ах, ах мов си, топор ; Просто примечание: в ассемблере есть много способов сделать простые элементы. ; как очистка AH. ; mov ah,00h (занимает 3 байта) ; xor ah,ah (занимает 2 байта и быстрее) ; cbw (занимает один байт, однако это очищает AH, только если бит 7 из ) ; (AL очищен (т.е. если AL < 128)) ; Теперь мы можем поместить «$» в эту позицию. mov байт [bx+si],'$' ; Теперь мы можем указать DX на начало строки и вызвать сервис ; (прерывать). Помните, что DX должен указывать на смещение 02h. mov dx, смещение добавить дх,02 мов ах, 09час через 21 час ; Таадаа. Это сработало? Теперь мы должны сказать DOS выйти из нашей программы или ; процессор попытается интерпретировать данные в OurBuff как код и может ; разбить машину. мов ах, 4Ч через 21 час ; Нам нужно, чтобы первый байт нашего буфера содержал рабочий ; размер буфера. Второй байт возвращается службой ; как количество введенных символов. Нам нужно 32 байта пространства ; потому что мы хотели до 32 символов. И, наконец, последний байт ; место для CR (0Dh), которое DOS добавляет к строке. OurBuff db 00h,00h ; рабочая и фактическая длины дубликат 32; строка (отрегулируйте длину так же, как код выше) дб 00ч ; CR (ascii 13d) ; Теперь две строки для печати для приятного пользовательского интерфейса. ; Обратите внимание на 13,10 в начале. Сервис 09h принимает 13 как ; возврат каретки (CR) и 10 как перевод строки (LF). FirstS db 13,10,'Пожалуйста, введите строку: $' SecndS db 13,10,' Введенная строка: $' .конец ******************************************************* **********************************
404 ошибка страницы
404 ошибка страницы404 ОШИБКА
Страница не найдена
Морда лося!
Когда не можешь что-то починить, корчи рожи.
Фильмы Криса
Здесь нет того, что вы ищете. Бывает, не волнуйся. Теперь вам нужно сделать выбор.
Вы можете перейти на нашу домашнюю страницу и продолжить поиск того, что искали, или вы можете сдаться и сыграть в игру.
ГЛАВНАЯ
Играть в игру
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
Название проекта
Используйте эту область страницы для описания вашего проекта. Значок выше является частью бесплатного набора значков Flat Icons. На их веб-сайте вы можете скачать их бесплатный набор из 16 иконок или приобрести весь набор из 146 иконок всего за 12 долларов!
- Клиент: Запустить начальную загрузку
- Дата: Апрель 2014 г.
- Служба: Веб-разработка
ключей (System.Windows.Forms) | Microsoft Learn
- Справочник
Определение
- Пространство имен:
- Система.Windows.Forms
- Сборка:
- System.Windows.Forms.dll
Важный
Некоторая информация относится к предварительной версии продукта, которая может быть существенно изменена до его выпуска. Microsoft не дает никаких явных или подразумеваемых гарантий в отношении представленной здесь информации.
Определяет коды клавиш и модификаторы.
Это перечисление поддерживает побитовую комбинацию значений своих членов.
общедоступный класс перечисления Keys
[System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.KeysConverter))] [Системные.Флаги] [System.Runtime.InteropServices.ComVisible(true)] открытые ключи перечисления
[System.ComponentModel.TypeConverter (typeof (System.Windows.Forms.KeysConverter))] [Системные.Флаги] открытые ключи перечисления
[] [<Системные.флаги>] [ ] введите ключи =
[] [<Системные.флаги>] type Keys =
Открытые ключи Enum
- Наследование
Объект
Тип значения
Перечисление
Ключи
- Атрибуты
ТипКонвертерАтрибуте ФлагиАтрибут Комвисиблеаттрибуте
Поля
А | 65 | Ключ А. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Добавлять | 107 | Клавиша добавления. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Альт | 262144 | Клавиша-модификатор ALT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Программы | 93 | Ключ приложения (Microsoft Natural Keyboard). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Внимание | 246 | Ключ ATTN. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Б | 66 | Клавиша B. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Назад | 8 | Клавиша BACKSPACE. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерНазад | 166 | Клавиша возврата браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерИзбранное | 171 | Клавиша избранного браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерВперед | 167 | Клавиша переадресации браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерГлавная | 172 | Домашний ключ браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерОбновить | 168 | Клавиша обновления браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерПоиск | 170 | Ключ поиска браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
БраузерСтоп | 169 | Клавиша остановки браузера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
С | 67 | Клавиша C. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Отмена | 3 | Клавиша ОТМЕНА. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Столица | 20 | Клавиша CAPS LOCK. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CapsLock | 20 | Клавиша CAPS LOCK. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
чистый | 12 | Клавиша CLEAR. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Контроль | 131072 | Клавиша-модификатор CTRL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Клавиша управления | 17 | Клавиша CTRL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Крсель | 247 | Ключ CRSEL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д | 68 | Клавиша D. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д0 | 48 | Клавиша 0. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д1 | 49 | Ключ 1. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д2 | 50 | Ключ 2. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д3 | 51 | Ключ 3. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д4 | 52 | Ключ 4. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д5 | 53 | Ключ 5. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д6 | 54 | Ключ 6. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д7 | 55 | Ключ 7. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д8 | 56 | Клавиша 8. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Д9 | 57 | Ключ 9. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Десятичный | 110 | Десятичный ключ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Удалить | 46 | Клавиша DEL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Разделять | 111 | Клавиша разделения. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вниз | 40 | Клавиша СТРЕЛКА ВНИЗ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Е | 69 | Клавиша E. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Конец | 35 | Клавиша КОНЕЦ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Войти | 13 | Клавиша ВВОД. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
СтеретьEof | 249 | Клавиша ERASE EOF. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Побег | 27 | Клавиша ESC. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Выполнять | 43 | Клавиша ВЫПОЛНИТЬ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Эксель | 248 | Ключ EXSEL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ф | 70 | Клавиша F. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F1 | 112 | Клавиша F1. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F10 | 121 | Клавиша F10. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F11 | 122 | Клавиша F11. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F12 | 123 | Клавиша F12. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F13 | 124 | Клавиша F13. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F14 | 125 | Клавиша F14. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F15 | 126 | Клавиша F15. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F16 | 127 | Клавиша F16. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F17 | 128 | Клавиша F17. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F18 | 129 | Клавиша F18. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F19 | 130 | Клавиша F19. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F2 | 113 | Клавиша F2. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F20 | 131 | Клавиша F20. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F21 | 132 | Клавиша F21. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F22 | 133 | Клавиша F22. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F23 | 134 | Клавиша F23. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F24 | 135 | Клавиша F24. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F3 | 114 | Клавиша F3. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F4 | 115 | Клавиша F4. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F5 | 116 | Клавиша F5. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F6 | 117 | Клавиша F6. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F7 | 118 | Клавиша F7. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F8 | 119 | Клавиша F8. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
F9 | 120 | Клавиша F9. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Финальный режим | 24 | Ключ окончательного режима IME. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
грамм | 71 | Клавиша G. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ЧАС | 72 | Клавиша H. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ХангуэльМоде | 21 | Клавиша режима IME Hanguel. (поддерживается для совместимости; используйте | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Режим хангыль | 21 | Клавиша режима хангыль IME. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ХанджаМоде | 25 | Ключ режима IME Hanja. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Помощь | 47 | Клавиша ПОМОЩЬ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Дом | 36 | Клавиша ДОМОЙ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
я | 73 | Клавиша I. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IMEAccept | 30 | Ключ принятия IME заменяет IMEAcept. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IMEAceept | 30 | Ключ принятия IME. Устарело, вместо этого используйте IMEAccept. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IMEКонвертировать | 28 | Ключ преобразования IME. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IMEModeChange | 31 | Клавиша смены режима IME. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IMEНеконвертировать | 29 | Непреобразованный ключ IME. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вставлять | 45 | Ключ ИНС. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Дж | 74 | Клавиша J. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
JunjaMode | 23 | Ключ режима IME Junja. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
К | 75 | Ключ К. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
КанаМоде | 21 | Клавиша режима IME Кана. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
КандзиMode | 25 | Клавиша режима IME Kanji. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ключевой код | 65535 | Битовая маска для извлечения кода ключа из значения ключа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
л | 76 | Клавиша L. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LaunchApplication1 | 182 | Запуск приложения одной клавишей. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LaunchApplication2 | 183 | Запуск приложения двумя клавишами. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LaunchMail | 180 | Ключ запуска почты. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LКнопка | 1 | Левая кнопка мыши. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LControlKey | 162 | Левая клавиша CTRL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Оставил | 37 | Клавиша СТРЕЛКА ВЛЕВО. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
перевод строки | 10 | Клавиша LINEFEED. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
164 | Левая клавиша ALT. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LShiftKey | 160 | Левая клавиша SHIFT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LВыигрыш | 91 | Левая клавиша с логотипом Windows (Microsoft Natural Keyboard). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
М | 77 | Ключ М. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MКнопка | 4 | Средняя кнопка мыши (трехкнопочная мышь). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MediaNextTrack | 176 | Клавиша следующей дорожки мультимедиа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
МедиаигратьПауза | 179 | Клавиша паузы воспроизведения мультимедиа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Медиапредыдущий трек | 177 | Клавиша предыдущей дорожки мультимедиа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
МедиаСтоп | 178 | Клавиша остановки мультимедиа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
18 | Клавиша ALT. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Модификаторы | -65536 | Битовая маска для извлечения модификаторов из значения ключа. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Умножить | 106 | Клавиша умножения. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Н | 78 | Клавиша N. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Следующий | 34 | Клавиша PAGE DOWN. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Без имени | 252 | Константа, зарезервированная для использования в будущем. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Никто | 0 | Клавиша не нажата. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NumLock | 144 | Клавиша NUM LOCK. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NumPad0 | 96 | Клавиша 0 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Цифровая клавиатура1 | 97 | Клавиша 1 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
цифровая клавиатура2 | 98 | Клавиша 2 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
цифровая клавиатура3 | 99 | Клавиша 3 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NumPad4 | 100 | Клавиша 4 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NumPad5 | 101 | Клавиша 5 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Цифровая клавиатура6 | 102 | Клавиша 6 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
цифровая клавиатура7 | 103 | Клавиша 7 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Цифровая клавиатура8 | 104 | Клавиша 8 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NumPad9 | 105 | Клавиша 9 на цифровой клавиатуре. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
О | 79 | Клавиша О. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM1 | 186 | Ключ OEM 1. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM102 | 226 | Ключ OEM 102. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM2 | 191 | Ключ OEM 2. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM3 | 192 | Ключ OEM 3. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM4 | 219 | Ключ OEM 4. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM5 | 220 | Ключ OEM 5. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM6 | 221 | Ключ OEM 6. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM7 | 222 | Ключ OEM 7. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEM8 | 223 | Ключ OEM 8. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEMBackslash | 226 | Угловая скобка OEM или клавиша обратной косой черты на 102-клавишной клавиатуре RT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OemОчистить | 254 | Клавиша CLEAR. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEMЗакрытьКвадратные скобки | 221 | Клавиша закрывающей скобки OEM на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Оэмкомма | 188 | Клавиша запятой OEM на клавиатуре любой страны/региона. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ОэмМинус | 189 | Клавиша минус OEM на клавиатуре любой страны/региона. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEMOpenBrackets | 219 | Клавиша открытой скобки OEM на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OemPeriod | 190 | Клавиша точки OEM на клавиатуре любой страны/региона. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OemPipe | 220 | Клавиша канала OEM на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Эмплюс | 187 | Клавиша OEM plus на клавиатуре для любой страны/региона. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OEMВопрос | 191 | Клавиша вопросительного знака OEM на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OemQuotes | 222 | Клавиша OEM с одинарными/двойными кавычками на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OemТочка с запятой | 186 | Клавиша OEM с точкой с запятой на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Эмтильда | 192 | Клавиша тильды OEM на стандартной клавиатуре США. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
п | 80 | Клавиша P. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Па1 | 253 | Ключ PA1. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Пакет | 231 | Используется для передачи символов Unicode, как если бы они были нажатиями клавиш. Значение ключа пакета — это младшее слово 32-битного значения виртуального ключа, используемого для методов ввода без клавиатуры. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Листать вниз | 34 | Клавиша PAGE DOWN. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PageUp | 33 | Клавиша PAGE UP. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Пауза | 19 | Клавиша ПАУЗА. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Играть в | 250 | Клавиша PLAY. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Распечатать | 42 | Клавиша ПЕЧАТЬ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Снимок экрана | 44 | Клавиша ПЕЧАТЬ ЭКРАНА. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Прежний | 33 | Клавиша PAGE UP. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ключ Процесса | 229 | Клавиша КЛЮЧ ПРОЦЕСС. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вопрос | 81 | Клавиша Q. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
р | 82 | Клавиша R. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RButton | 2 | Правая кнопка мыши. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RControlKey | 163 | Правая клавиша CTRL. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Возвращаться | 13 | Клавиша ВОЗВРАТ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Верно | 39 | Клавиша СТРЕЛКА ВПРАВО. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
165 | Правая клавиша ALT. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RShiftKey | 161 | Правая клавиша SHIFT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RWin | 92 | Правая клавиша с логотипом Windows (Microsoft Natural Keyboard). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
С | 83 | Клавиша S. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Прокрутить | 145 | Клавиша БЛОКИРОВКИ ПРОКРУТКИ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Выбирать | 41 | Клавиша ВЫБОР. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ВыбратьМедиа | 181 | Клавиша выбора носителя. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Разделитель | 108 | Ключ-разделитель. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сдвиг | 65536 | Клавиша-модификатор SHIFT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ShiftKey | 16 | Клавиша SHIFT. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Спать | 95 | Клавиша сна компьютера. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Снимок | 44 | Клавиша ПЕЧАТЬ ЭКРАНА. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Пространство | 32 | Клавиша ПРОБЕЛ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вычесть | 109 | Клавиша вычитания. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Т | 84 | Ключ Т. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вкладка | 9 | Клавиша TAB. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
U | 85 | Клавиша U. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вверх | 38 | Клавиша СТРЕЛКА ВВЕРХ. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
В | 86 | Клавиша V. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Убавить звук | 174 | Клавиша уменьшения громкости. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ГромкостьMute | 173 | Клавиша отключения звука. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Увеличить громкость | 175 | Клавиша увеличения громкости. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Вт | 87 | Клавиша W. e ) { // Инициализируем флаг значением false. nonNumberEntered = ложь; // Определяем, является ли нажатие клавиши числом с верхней части клавиатуры. если ( e->KeyCode < Keys::D0 || e->KeyCode > Keys::D9) { // Определяем, является ли нажатие клавиши числом с клавиатуры. если ( e->KeyCode < Keys::NumPad0 || e->KeyCode > Keys::NumPad9 ) { // Определяем, является ли нажатие клавиши возвратом. если ( e->KeyCode != Keys::Back ) { // Была нажата нечисловая клавиша. // Установите флаг в значение true и оцените событие KeyPress. нечисловой ввод = истина; } } } //Если была нажата клавиша Shift, это не число. если (Control::ModifierKeys == Keys::Shift) { нечисловой ввод = истина; } } // Это событие происходит после события KeyDown и может использоваться для предотвращения // символы от входа в элемент управления. e ) { // Проверяем установленный флаг в событии KeyDown. если ( nonNumberEntered == true ) { // Остановить ввод символа в элемент управления, поскольку он не является числовым. е-> Обработано = правда; } } // логический флаг, используемый для определения, когда вводится символ, отличный от числа. частное логическое значение nonNumberEntered = false; // Обработка события KeyDown для определения типа символа, введенного в элемент управления. private void textBox1_KeyDown (отправитель объекта, System.Windows.Forms.KeyEventArgs e) { // Инициализируем флаг значением false. nonNumberEntered = ложь; // Определяем, является ли нажатие клавиши числом с верхней части клавиатуры. если (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9) { // Определяем, является ли нажатие клавиши числом с клавиатуры. если (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9) { // Определяем, является ли нажатие клавиши возвратом. if(e.KeyCode != Keys.Back) { // Была нажата нечисловая клавиша. // Установите флаг в значение true и оцените событие KeyPress. нечисловой ввод = истина; } } } //Если была нажата клавиша Shift, это не число. если (Control.ModifierKeys == Keys.Shift) { нечисловой ввод = истина; } } // Это событие происходит после события KeyDown и может использоваться для предотвращения // символы от входа в элемент управления. private void textBox1_KeyPress (отправитель объекта, System.Windows.Forms.KeyPressEventArgs e) { // Проверяем установленный флаг в событии KeyDown. если (nonNumberEntered == true) { // Остановить ввод символа в элемент управления, поскольку он не является числовым. e.Handled = истина; } } ' Логический флаг, используемый для определения, когда вводится символ, отличный от числа. Private nonNumberEntered As Boolean = False ' Обработать событие KeyDown, чтобы определить тип символа, введенного в элемент управления. Private Sub textBox1_KeyDown (отправитель как объект, e как System.Windows.Forms.KeyEventArgs) _ Обрабатывает textBox1.KeyDown ' Инициализировать флаг значением false. nonNumberEntered = Ложь ' Определить, является ли нажатие клавиши числом с верхней части клавиатуры. Если e.KeyCode < Keys.D0 OrElse e.KeyCode > Keys.D9затем ' Определить, является ли нажатие клавиши числом с клавиатуры. Если e.KeyCode < Keys.NumPad0 OrElse e.KeyCode > Keys.NumPad9 Тогда ' Определить, является ли нажатие клавиши клавишей Backspace. Если e.KeyCode <> Keys.Back Тогда ' Была нажата нечисловая клавиша. ' Установите флаг в значение true и оцените событие KeyPress. ненумерентеред = Истина Конец, если Конец, если Конец, если 'Если была нажата клавиша Shift, это не число. Если Control.ModifierKeys = Keys.Shift Тогда ненумерэнтеред = истина Конец, если Конец сабвуфера ' Это событие происходит после события KeyDown и может быть использовано ', чтобы предотвратить ввод символов в элемент управления. Private Sub textBox1_KeyPress (отправитель как объект, e как System.Windows.Forms.KeyPressEventArgs) _ Обрабатывает textBox1.KeyPress ' Проверяем установленный флаг в событии KeyDown. Если NonNumberEntered = True Тогда ' Остановить ввод символа в элемент управления, поскольку он не является числовым. e.Handled = Истина Конец, если Конец сабвуфера Класс Keys содержит константы для обработки ввода с клавиатуры. Члены перечисления Keys состоят из кода клавиши и набора модификаторов, объединенных в одно целочисленное значение. В интерфейсе прикладного программирования (API) Win32 значение ключа состоит из двух частей: старшие биты содержат код ключа (который совпадает с кодом виртуального ключа Windows), а младшие биты представляют модификаторы ключа, такие как клавиши SHIFT, CONTROL и ALT. Предупреждение Не используйте значения в этом перечислении для комбинированных побитовых операций. Значения в перечислении не являются взаимоисключающими. Примечание Это перечисление не позволяет проверить, активированы ли в данный момент клавиши CAPS LOCK или NUM LOCK. Чтобы определить, активированы ли эти клавиши, можно использовать один из следующих способов:
В следующей таблице показаны значения кодов клавиш, представленные двумя пронумерованными значениями, представляющими как общие ключи производителей оригинального оборудования (OEM), так и более конкретные ассоциации клавиатур США.
Осторожно Для . NET Framework 2.0 был добавлен элемент IMEAccept, который заменяет предыдущую запись IMEAccept, которая была написана неправильно. Старая версия была сохранена для обратной совместимости, но может быть удалена в будущих версиях .NET Framework Применимо кСм. также
Руководство Gavins по сборке 80×86Руководство Gavins по сборке 80×86 — Часть 3Облегчение работыТо, как мы ввели адрес сообщения, которое хотели напечатать было немного громоздко. Потребовалось три строки, и это не самое простое вещь, чтобы помнить.Мы можем заменить все это всего одной строкой. Это делает код легче читать и легче запоминать.mov dx,СМЕЩЕНИЕ MyMessage mov топор,SEG MyMessage мов дс, топор Чтобы это работало, в начале кода добавьте следующие строки:mov dx,СМЕЩЕНИЕ MyMessage Примечание: для A86 вам нужно изменить первую строку на:мов топор,@данные мов дс, топор Это связано с тем, что все данные в сегменте имеют одинаковое значение SEG. Помещение этого в DS избавляет нас от перезагрузки каждый раз, когда мы хотим использовать другую вещь в том же сегменте.мов топор,данные Ввод с клавиатурыМы собираемся использовать прерывание 16h, функцию 00h для чтения клавиатура. это получает ключ из буфера клавиатуры. если нет один, он ждет, пока не будет. Он возвращает код SCAN в AH и перевод ASCII в AL.Все, о чем нам сейчас нужно беспокоиться, это значение ascii, которое в АЛ.xor ах, ах ; функция 00h - получить символ интервал 16ч ; прерывать 16 часов Примечание. XOR выполняет логическое исключающее ИЛИ. Обычно используется чтобы стереть регистр или переменную. Печать символаПроблема в том, что у нас есть клавиша, которая была нажата в ах. Как мы это показываем? Мы не можем использовать функцию 9h, потому что для этого мы нужно уже определить строку, которая должна заканчиваться долларом знак. вот что мы делаем вместо этого:Если вы хотите сохранить значение AH, нажмите AX перед и нажмите это потом.; после вызова функции 00h прерывания 16h мов дл, аль ; переместите al (код ascii) в dl мов ах,02ч ; функция 02h прерывания 21h интервал 21ч ; прерывание вызова 21ч Поток управленияВ ассемблере есть набор команд для управления потоком, как в любой другой язык. Во-первых, самая основная команда:Все это делается для того, чтобы перейти к указанной метке и начать выполнение код там. Например:ярлык jmp Что мы делаем, если хотим что-то сравнить? мы только что получили ключ от пользователя, но мы хотим что-то с ним сделать. Позволяет печатать что-то вне, если оно равно чему-то другому. Как мы это делаем? Это просто. Мы используем команды перехода по условию.JMP ALabel . . . Этикетка: Сначала вы сравниваете операнд с данными, а затем используете правильная команда. Вот их список:cmp ось,3 ; AX = 3? я правильный; да Инструкции перехода по условию
Примечание: переход может быть не более 127 байт в любом направление. CMP: сравнить значение Регистр CMP или переменная, значение пункт назначения jxxПримером этого является: cmp al,'Y' ; сравнить значение в al с Y je ItYES ; если он равен, то перейти к ItYESКаждая инструкция занимает определенное количество кода. Ты получит предупреждение, если вы попытаетесь перепрыгнуть через 127 байт в любом направление от компилятора. Вы можете решить эту проблему, изменив последовательность такая: к чему-то вроде этого:см ось, 10 ; это АКС 10? я сделал; да, давай закончим не сделано: Это решает проблему, но вы можете подумать об изменении порядка ваш код или использование процедур, если это происходит часто.см ось, 10 ; это АКС 10? jne не сделано ; нет джмп сделано; мы закончили Теперь мы рассмотрим программу, которая демонстрирует ввод, вывод и управление потоком. Листинг 2: PROGFLOW. ASM ; программа для демонстрации хода программы и ввода/вывода .модель крошечная .код орг 100ч Начало: mov dx,сообщение OFFSET ; вывести сообщение на экран мов ах, 9; используя функцию 09h интервал 21ч ; прерывания 21ч mov dx,OFFSET Подсказка ; вывести сообщение на экран мов ах,9 ; используя функцию 09h интервал 21ч ; прерывания 21ч jmp в первый раз Подсказка_Еще раз: mov dx,OFFSET Другой ; вывести сообщение на экран мов ах,9 ; используя функцию 09h интервал 21ч ; прерывания 21ч Первый раз: mov dx,OFFSET Снова ; вывести сообщение на экран мов ах,9 ; используя функцию 09h интервал 21ч ; прерывания 21ч xor ах, ах ; функция 00h из интервал 16ч ; прерывание 16h получает символ мов бл, ал ; сохранить в бл мов дл, аль ; переместить al в dl мов ах,02ч ; функция 02h - отображение символа интервал 21ч ; позвонить в службу DOS cmp bl,'Y' ; Аль = Y? je Prompt_Again ; если да, то показать его снова cmp bl,'y' ; аль=у? je Prompt_Again ; если да, то показать его снова конец: mov dx,OFFSET До свидания ; распечатать прощальное сообщение мов ах, 9; используя функцию 9 интервал 21ч ; прерывания 21ч мов ах,4Ч ; завершить программу через 21 час . ДАННЫЕ CR экв 13; войти LF экв 10 ; перевод строки БД сообщений "Простая программа ввода/вывода$" Подсказка DB CR,LF,"Вот ваша первая подсказка.$" Снова DB CR,LF, "Вы хотите получить запрос снова? $" Другой DB CR, LF, "Вот еще одна подсказка! $" До свидания DB CR, LF, «Тогда до свидания». конец начало Вернуться к оглавлениюТехногенная кома: понимание сборки 6502 на Commodore 64Если вы еще не догадались, Assembly — это идеальная стратегическая игра. Имея бесконечные возможности для достижения желаемого результата, мы наслаждались тем фактом, что до сих пор нам требовалось очень мало манипуляций с данными или проверки ошибок. Наша последняя программа использовала жестко запрограммированное значение в определенном месте памяти для выполнения задачи. Фактически это была часть самой программы. Конечно, вы могли бы положить что угодно, но мусор туда и обратно. Фактически единственным взаимодействием с пользователем был запуск самой программы. Когда мы открываем программу, чтобы позволить пользователю вводить данные, игра полностью меняется! Мы делали это раньше с помощью нашей программы Sprite, что было довольно просто. Он распознавал только определенные клавиши и выполнял функцию для каждой из них, не обращая внимания на позиции спрайтов. Это сделало программу короткой и легкой для чтения. На самом деле я создал функцию преобразования двоичных данных только для хранения регистров COMMAND и CONTROL в виде видимых двоичных файлов, вызываемых с помощью (JSR) из другой программы, которая требует постоянной видимости командных и управляющих битов ACIA. Он немного меньше, ему немного сложнее следовать, и он использует преимущества нулевой страницы из последней главы. Как и в нашей программе, где мы жестко закодировали наше значение, процесс заполняет это значение из другого места в памяти и по-прежнему не требует вмешательства человека. Итак, у нас есть двоичный преобразователь. Мы жестко закодировали значение в OURHEXVALUE и позволили программе работать с ним. Он преобразовал значение и бесцеремонно завершил работу. Возникает вопрос: « Насколько сложнее было бы разрешить пользователю вводить шестнадцатеричное значение с клавиатуры, а затем преобразовывать его в ?» Ответ: гораздо больше. Давайте рассмотрим самый простой сценарий! Если вы не можете записать это на бумаге как концепцию, вы не можете это запрограммировать. 1 . Очищаем экран 1 . Здесь не так много изменений, но есть вещи, которые нам нужно будет добавить. Позвольте мне указать здесь, что ни одна программа, подобная этой, не была написана сверху вниз. Он как бы развивается, когда вы достигаете конкретных целей. INIT: Мы использовали эту технику очистки экрана раньше….. но не в этой программе, мы собирались добавить метку поверх наших существующих меток для CHROUT, обратите внимание мы удалили OURHEXVALUE. В этом нет необходимости, так как пользователь будет вводить это значение. Убедитесь, что мы добавили нашу стартовую процедуру после init. Таким образом, INIT будет запускаться только один раз при загрузке программы, START: будет началом каждого экземпляра программы. *=$C000 ; SYS 49152 для начала OURHEXNUM = $033C ; Здесь будет храниться константа OURHEXVALUE Вот мы и достигли нашей первой цели. Теперь экран чист. 2 . Итак, теперь, когда экран чист, мы хотим вывести на экран метку, чтобы проинструктировать пользователя. Это снова будет использовать CHROUT, хотя есть гораздо более эффективные способы сделать это, однако, используя метод, который мы использовали для загрузки данных спрайта, мы можем использовать тот же самый цикл для вывода на экран. Рассмотрите BASIC: После запуска нашей функции очистки экрана на первом этапе экран очищается, и курсор оказывается в левом верхнем углу. В разделе INIT: мы создадим метку с именем START: 9.0010 Как упоминалось ранее, INIT вызывается только один раз. START вызывается каждый раз при запуске программы. НАЧАЛО: Нам понадобится цикл генерации меток и данные для использования в этом цикле. НАПИСНАЯ ЭТИКЕТКА: ; Печатает нашу этикетку и возвращает HELLO находится сразу после окончания нашей программы внизу, как и данные Sprite из предыдущих глав. Используя X в качестве текущей позиции буквы, начиная с 0, мы можем загрузить байт в A, а затем запустить jsr CHROUT, чтобы вывести эту букву на экран. Пробел после двоеточия является допустимым байтом пробела и дает нам фактический пробел между текстом и начальной позицией курсора. Это зациклит $13[hex] раз, каждый раз увеличивая X для следующего байта и, в конечном счете, возвращая RTS с того места, где он был вызван в START. На этом второй шаг завершен …… 3 . При выполнении машинного кода в C64 мигающий курсор автоматически отключается, экономя ненужные впустую процессорные циклы, если они не нужны. Однако мы хотели бы использовать его в качестве подсказки, поэтому в коде мы хотели бы снова включить его. Внизу на нулевой странице находится BLNSW, который контролирует, включен или выключен курсор. Нулевое значение включит его. BLNSW = $CC ; Курсор мигает вкл. или выкл. Поэтому мы добавляем BLNSW в наш список лучших ярлыков. Мы знаем, что для включения требуется значение 0. Непосредственно перед тем, как мы перешли к WRITELABEL, мы уже сделали X нулевым, так почему бы не поместить код для этого прямо над jsr WRITELABEL. НАЧАЛО: Итак, теперь у нас есть очищенный экран, метка с надписью ENTER A HEX VALUE: и мигающий курсор. До сих пор нам не требовалось вмешательства человека. То есть, до сих пор это было довольно легко. Что мы знаем прямо сейчас, так это то, что мы хотим от пользователя только два нажатия клавиш, то есть два байта. Нам нужен какой-то счетчик, который будет инициализирован нулем и будет увеличиваться при каждом нажатии клавиши. Мы можем использовать один байт в памяти, чтобы записать это. Я выбираю 033F Итак, давайте добавим еще одну метку: BYTECOUNTER = $033F ; какая цифра была до Поскольку мы хотим, чтобы значение в BYTECOUNTER было равно нулю, не было бы здорово сделать то, что мы сделали в прошлый раз, и сохранить наш существующий X в BYTECOUNTER точно так же, как BLNSW START: Давайте повторим, что у нас есть….. *=$C000 ; SYS 49152 для начала OURHEXNUM = $033C ; Здесь будет храниться константа OURHEXVALUE INIT: START: WRITLABEL: ; Печатает нашу этикетку и возвращает Как мы есть, с нашим мигающим курсором, расположенным в желаемом месте, пришло время перейти к новому местоположению. В этот момент мы находимся в режиме ожидания, отданы на милость пользователя, ожидая двух наших ключевых вводов… ожидание… и ожидание… и ожидание… … В ядре есть функции, которые ждут нажатия клавиши и, найдя ее, сбрасывают ее в аккумулятор. Эту технику проще всего продемонстрировать, и она работает эффективно только в том случае, если вся программа по замыслу должна останавливаться и ждать. Давайте добавим их к нашим меткам вверху. SCNKEY = $FF9F ; Сканировать клавиатуру на предмет нажатия клавиши Время для нового блока кода: SCANKBD: Мы только что создали бесконечный цикл, как только мы перейдем к SCANKBD, выхода из нашей программы нет. Это потому, что мы не определили, как выйти из петли, в которую мы попали. Давайте дадим себе выход из всего этого. SCANKBD: Теперь все, что нам нужно, это какой-то быстрый и грязный код END для перехода в случае нажатия Q. Прямо над WRITELABEL: и забудьте об этом, он делает то, что должен, он возвращается к BASIC END: Итак, теперь у нас есть выход, но здесь все станет сложнее. Поскольку наши входные значения составляют шестнадцатеричное значение, они должны быть только от 0 до 9 и от A до F, за исключением Q, который мы уже определили. cmp #$30 ; меньше шестнадцатеричного значения для 0? Таким образом, выше, если его значение меньше 0, оно недействительно и должно вернуться к сканированию ключа. Для продолжения оно должно быть больше 0 cmp #$3A ; меньше шестнадцатеричного значения 9, но больше 0? На данный момент мы уже знаем, что значение должно быть 0 или больше, но равно ли оно 9 или меньше. Если оно равно 9 или меньше, мы знаем, что введенное значение должно находиться в диапазоне 0-9, и у нас есть действительный ввод. поэтому мы переходим к функции, чтобы начать наш процесс преобразования Но что, если оно больше 9, оно все еще может быть действительным? Это может быть А-Ф, помните, нам нужно продолжать тестирование. На данный момент мы знаем, что значение должно быть больше 9, иначе он разветвился бы на DIGITCONVERT. cmp #$41 ; меньше значения A Итак, теперь мы спрашиваем, является ли значение, которое, как мы знаем, больше 9, меньше A, потому что если это так, оно недействительно, и нам нужно снова отсканировать клавиатуру. Если бы мы все еще были здесь, мы теперь знаем, что значение равно A или больше, но не было сделано, оно все равно должно быть F или меньше cmp #$47 ; значение F или меньше Если значение равно F или меньше, мы знаем, что у нас есть допустимый ввод в нашем диапазоне от A до F. Мы можем перейти к LETTERCONVERT. Вот наш полный SCANKBD: ;;;;;;;;;;;;;;;;; Наша функция сканирования клавиатуры, если клавиша нажата, появится SCANKBD: Так зачем две отдельные ветки? Чтобы новичкам было легко понять, я сократил код, чтобы он обрабатывал числа и буквы таким образом, чтобы его было легко увидеть. Из-за их шестнадцатеричных значений в логическом порядке A не появляется сразу после 9 . Вы увидите через мгновение Давайте начнем с LETTERCONVERT: Мы хотим сохранить значение, которое вы видите на клавиатуре. не его шестнадцатеричное значение. то есть число 5 должно быть сохранено как 05. Однако, прежде чем мы будем манипулировать им, мы хотим вывести на экран клавишу, которую пользователь нажал, на наш курсор с помощью CHROUT. Связь этих двух функций очевидна и подробно описана здесь. Вычтите $36 из буквы, чтобы получить ее шестнадцатеричное значение, вычтите $2F из числа, чтобы получить его шестнадцатеричное значение ПРЕОБРАЗОВАНИЕ ПИСЬМА: Теперь нам нужна наша функция для преобразования DIGITS 0-9 DIGITCONVERT: После внесения этого изменения мы либо переходим, либо, в случае с DIGITCONVERT:, просто переходим к MAINCONVERT. Важно знать, с каким БАЙТОМ мы работаем, потому что второй байт не нуждается в дальнейшем преобразовании, а первый требует. Я покажу вам, почему. Когда мы вводим 3, а затем F, нам нужно 3F, мы получаем 03 и 0F. Мы хотим перевернуть номер только нашего первого введенного байта, в данном случае 03, и оставить второй в покое. Если бы мы могли превратить 03 в 30, мы могли бы добавить его к 0F и получить сумму 3F. Чего мы и хотим. Наша функция MAINCONVERT загружает байт из BYTECOUNTER, чтобы узнать, находимся ли мы на первом или втором байте. если это первое, мы выполним преобразование, если второе, преобразование не будет выполнено, и мы перейдем к ПРОЦЕССУ: Так уж получилось, что любое число от 00 до 0F можно легко перевернуть с помощью 4 операций asl, посмотрите и убедитесь, как это делается. Мы будем использовать значение 03, которое мы хотим преобразовать в 30. ASL : Арифметический сдвиг влево — сдвигает все биты влево и каждый раз добавляет ноль к младшему биту 03 = 00000011 ASL -> 1st ГЛАВНОЕПРЕОБРАЗОВАНИЕ: Теперь мы переходим к ПРОЦЕССУ, нам понадобится место для хранения этих двух преобразованных байтов. Это означает новые метки вверху LOWBYTE = $033D ; хранилище ввода первой цифры С самого начала мы загружаем наш BYTECOUNTER в X, затем мы сохраняем наше значение в LOWBYTE,X . На самом деле нам не нужна метка с именем HIGHBYTE, но она не скомпилирована, поэтому это просто ссылка. ПРОЦЕСС: ; Здесь мы продолжаем хранить значение в правильном месте При сохранении байтов мы можем видеть, находимся ли мы на 1-м или втором байте. После увеличения X мы можем видеть, находимся ли мы на первом введенном байте или на втором. После обработки первого байта X=1, поэтому, если мы CPX #$02, мы знаем, что оба байта введены. Если X не равно 2, то введен только 1 байт, и мы возвращаемся к функции SCANKBD: и делаем это снова. , если 2, то не ответвляемся, продолжаем на 4 . Итак, теперь мы, например, набрали 3 и F, преобразовали их в 03 и 0F, перевернули цифру в первой, чтобы получить 30 и 0F. Теперь мы ……. 5 . Обратите внимание на первые две строки, которые я закомментировал в коде, они нам не нужны. Все наши усилия были направлены на то, чтобы сохранить значение в OURHEXNUM с клавиатуры, что мы и сделали. SETCONVERT: ПРЕОБРАЗОВАНИЕ: STORE1: ПРОДОЛЖИТЬ: 6 . Я собираюсь вставить здесь в середине кода. Как только мы ввели наше второе число, двоичное значение появится внизу экрана посередине. Если бы мы сразу вернулись к INIT, мы бы очистили экран и никогда не увидели бы выведенное значение. Нет необходимости очищать весь экран, только две позиции, в которых мы ввели наш номер. ;;;;;;;;; ОТПУСТИТЕ ДВЕ ЦИФРЫ, УСТАНОВИТЕ КУРСОР В ИСХОДНУЮ ПОЗИЦИЮ ВВОДА Поэтому мы загружаем A со значением $20, которое является пустым пространством, и очищаем с его помощью два наших местоположения, $0413 и $0414. К сожалению, именно здесь были наши две цифры, сохраняя эту легкость, вторая цифра приводит вещи в движение и, кажется, почти очищается сама собой. Ничего страшного, возможно, в будущем мы сможем реализовать ожидание RETURN, чтобы все заработало. Установив X с координатой X и Y с координатой Y и jsr в PLOT. мы перемещаем курсор в верхнюю левую позицию, где мы генерируем наш текст ENTER A HEX VALUE: И так все начинается сначала…….. Наш полный код…… ; Программа C64 Hex to Binary Converter OURHEXNUM = $033C ; Здесь будет храниться константа OURHEXVALUE nop ; привыкаю, оставляю на пробу и снимаю по INIT: НАЧАЛО: SETCONVERT: CONVERTION: STORE1: ПРОДОЛЖЕНИЕ: ;;;;;;;;; ОТПУСТИТЕ ДВЕ ЦИФРЫ, УСТАНОВИТЕ КУРСОР В ИСХОДНУЮ ПОЗИЦИЮ ВВОДА ;;;;;;;;;;;;;;;;; Наша функция сканирования клавиатуры, если клавиша нажата, она появится SCANKBD: ldx BYTECOUNTER ; вывести BYTECOUNTER в X sta LOWBYTE,x ; помещает наши значения в LOWBYTE и HIGHBYTE inx ; Мы должны увеличить BYTECOUNTER на 1 stx BYTECOUNTER ; и сохраните новое значение в BYTECOUNTER cpx #$02 ; если BYTECOUNTER равен $02, добавление значений bne SCANKBD ; Не 2, продолжайте поиск входов ;;;;; Если мы здесь, значит, теперь у нас есть два байта, мы должны LETTERCONVERT: DIGITCONVERT: MAINCONVERT: END: ; убивает программу WRITELABEL: ; Печатает нашу этикетку и возвращает NEXT——> Содержание Прерывания DOSПрерывания DOSDOS INT 21h — Коды функций DOS Следующий сокращенный список прерываний DOS был извлечен из большой список, составленный Ральфом Брауном. Они доступны на любом зеркале Simtel. (например, sunsite.anu.edu.au) в каталоге ms-dos/info/interNNp.zip 9Разрыв проверен См. также: AH=06h,AH=09h АХ = 05h — ЗАПИСАТЬ СИМВОЛ НА ПРИНТЕР Ввод: DL = символ для печати Примечания:
См. также: AH=0Ch Формат входного буфера DOS:
|