Разное

Ассемблер ввод с клавиатуры числа: Решение: Ввод чисел с клавиатуры

Содержание

Основы языка ассемблер. Операции ввода/вывода

Похожие презентации:

Основы разработки программы на ассемблере

Организация прерываний. Аппаратные прерывания

Язык Ассемблер

Архитектура ЭВМ и язык ассемблера

Основные компоненты языка Ассемблер

Программирование на Ассемблере

Программирование на языке ассемблер

Основы языка ассемблера

Программная модель микропроцессора INTEL 8080, регистры, форматы и системы команд, методы адресации

Лекции по программированию на ассемблере

1. Основы языка ассемблер

2. Операции ввода/вывода

2

3. Операции ввода/вывода по прерыванию 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. Работа со стеком

push
dx
;поместить значение
;регистра dx в стек
pop
dx
;записать в dx число
;из стека
4

5. Задача

Вывести значение переменной на экран.
1
начало
да
да
Число=0?
cx = 0 ?
нет
Извлечение цифры из
стека
нет
Деление на 10
Вывести число
на экран
Преобразование
остатка в символ
Помещение цифры в
стек
1
конец
5

6. Программа

6

7. Задача

1. Найти сумму двух чисел введенных с клавиатуры, если сумма < 10.
2. Найти сумму двух чисел введенных с клавиатуры для любой суммы.
7

8. Программа

8

9. ВВОД С КЛАВИАТУРЫ ПО КОМАНДЕ 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
до 5. Признак конца ввода — нажатие клавиши [Ввод] (код 13). Преобразовать число в двоичное и вывести его
двоичное представление на экран.
•Введите 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

 




     главная | новости | институт | курсовые | комплексные | рефераты | преподы | фотоальбом | приколы | АТС | гостевая
 
   ©НОСКІЗ-ДУІТ 2002-2003

 


Программа на языке Ассемблер.

Подпрограмма, преобразующую произвольное число из 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, убедитесь, что вы освоили следующие основные концепции:

    1. C++ предоставляет входной поток cin, который ваши программы могут использовать для чтения ввода с клавиатуры.
    2. Если программы для чтения ввода используют cin, они должны указать одну или несколько переменных, в которые cin будет помещать данные.
    3. Чтобы направить ввод в переменную, вам следует использовать cin с оператором извлечения (>>).
    4. При применении cin для чтения нескольких значений, cin использует пустые символы (пробел, табуляция или возврат каретки), чтобы определить, где заканчивается одно значение и начинается другое.
    5. Если пользователь вводит неверные данные, могут возникать ошибки переполнения или несоответствия типов, а значения, присвоенные входным потоком 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 
Наследование

Объект

Тип значения

Перечисление

Ключи

Атрибуты

ТипКонвертерАтрибуте ФлагиАтрибут Комвисиблеаттрибуте

Поля

6.1 netframework-4.6.2 netframework-4.7 netframework-4.7.1 netframework-4.7.2 netframework-4.8 windowsdesktop-3.0 windowsdesktop-3.1 windowsdesktop-5.0 windowsdesktop-6.0 windowsdesktop-7.0 «> 1 windowsdesktop-5.0 windowsdesktop-6.0 windowsdesktop-7.0 «> 0 netframework-3.0 netframework-3.5 netframework-4.0 netframework-4.5 netframework-4.5.1 netframework-4.5.2 netframework-4.6 netframework-4.6.1 netframework-4.6.2 netframework-4.7 netframework-4.7.1 netframework-4.7.2 netframework-4.8 windowsdesktop-3.0 windowsdesktop-3.1 windowsdesktop-5.0 windowsdesktop-6.0 windowsdesktop-7.0 «> 6.1 netframework-4.6.2 netframework-4.7 netframework-4.7.1 netframework-4.7.2 netframework-4.8 windowsdesktop-3.0 windowsdesktop-3.1 windowsdesktop-5.0 windowsdesktop-6.0 windowsdesktop-7.0 «>
А 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. (поддерживается для совместимости; используйте HangulMode )

Режим хангыль 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. Чтобы определить, активированы ли эти клавиши, можно использовать один из следующих способов:

  • Вызовите метод IsKeyLocked класса Control.

  • Для более точного управления используйте для этого функции Windows API GetKeyState , GetAsyncKeyState или GetKeyboardState , определенные в user32.dll. Дополнительные сведения о вызове собственных функций см. в разделе Использование неуправляемых функций DLL.

В следующей таблице показаны значения кодов клавиш, представленные двумя пронумерованными значениями, представляющими как общие ключи производителей оригинального оборудования (OEM), так и более конкретные ассоциации клавиатур США.

Шестнадцатеричное значение Клавиатура США Общий OEM
БА OEMТочка с запятой OEM1
БФ OEMВопрос OEM2
С0 Эмтильда ОЕМ3
ДБ OEMOpenBrackets ОЕМ4
DC Производственная труба OEM5
ДД OemCloseBrackets ОЕМ6
Немецкий OemQuotes ОЕМ7
Е2 Обратная косая черта OEM ОЕМ102

Осторожно

Для . NET Framework 2.0 был добавлен элемент IMEAccept, который заменяет предыдущую запись IMEAccept, которая была написана неправильно. Старая версия была сохранена для обратной совместимости, но может быть удалена в будущих версиях .NET Framework

Применимо к

См. также

  • KeysConverter
  • СендКейс
  • Консольный ключ
  • Ярлык
  • Ключи Модификатора
  • ИсКейЛоккед (Ключи)
  • Кейевентаргс

Руководство 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.
xor ах, ах ; функция 00h - получить символ
интервал 16ч ; прерывать 16 часов
 
Все, о чем нам сейчас нужно беспокоиться, это значение ascii, которое в АЛ.

Примечание. XOR выполняет логическое исключающее ИЛИ. Обычно используется чтобы стереть регистр или переменную.

Печать символа

Проблема в том, что у нас есть клавиша, которая была нажата в ах. Как мы это показываем? Мы не можем использовать функцию 9h, потому что для этого мы нужно уже определить строку, которая должна заканчиваться долларом знак. вот что мы делаем вместо этого:

; после вызова функции 00h прерывания 16h
мов дл, аль ; переместите al (код ascii) в dl
мов ах,02ч ; функция 02h прерывания 21h
интервал 21ч ; прерывание вызова 21ч
 
Если вы хотите сохранить значение AH, нажмите AX перед и нажмите это потом.

Поток управления

В ассемблере есть набор команд для управления потоком, как в любой другой язык. Во-первых, самая основная команда:
ярлык jmp
 
Все это делается для того, чтобы перейти к указанной метке и начать выполнение код там. Например:
JMP ALabel
.
.
.
Этикетка:
 
Что мы делаем, если хотим что-то сравнить? мы только что получили ключ от пользователя, но мы хотим что-то с ним сделать. Позволяет печатать что-то вне, если оно равно чему-то другому. Как мы это делаем? Это просто. Мы используем команды перехода по условию.

Сначала вы сравниваете операнд с данными, а затем используете правильная команда.

cmp ось,3 ; AX = 3?
я правильный; да
 
Вот их список:

Инструкции перехода по условию

Переходит, если первое число было выше второго числа
JA
ДЖАЭ то же, что и выше, но также будет прыгать, если они равны
ДЖБ прыгает, если первое число было меньше второго
JBE То же, что и выше, но также будет прыгать, если они равны
ЮНА переходов, если первое число НЕ было выше (JBE)
JNAE перескакивает, если первый номер TDe НЕ выше или TDe такой же, как (JNB)
ДЖНБ переходов, если первое число НЕ было ниже (JAE)
ДЖНБЭ переходит, если первое число НЕ было ниже или совпадало с (JA)
ДЗ прыжков, если два числа были равны
JE такой же, как JZ, только другое имя
ДЖНЗ переходит, если два числа НЕ равны
JNE то же, что и выше
ДК перейти, если установлен флаг переноса

Примечание: переход может быть не более 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 . Очищаем экран
2 . Создаем, начиная слева вверху небольшой баннер с надписью «Введите шестнадцатеричное значение:»
3 . Мы предоставляем мигающий курсор в качестве подсказки для ввода двух символов.
4 . Мы предоставляем код для помещения этих двух символов в OURHEXVALUE
5 . Мы запускаем наш существующий код для преобразования значения и выводим его
6 . Повторяем процесс

1 . Здесь не так много изменений, но есть вещи, которые нам нужно будет добавить. Позвольте мне указать здесь, что ни одна программа, подобная этой, не была написана сверху вниз. Он как бы развивается, когда вы достигаете конкретных целей.
Я попытаюсь построить это на основе нашей предыдущей программы.

INIT:
lda #$93
jsr CHROUT ; Загрузите 147, шестнадцатеричное значение $93 в регистр A и JSR в CHROUT

     Мы использовали эту технику очистки экрана раньше….. но не в этой программе, мы собирались добавить метку поверх наших существующих меток для CHROUT, обратите внимание мы удалили OURHEXVALUE. В этом нет необходимости, так как пользователь будет вводить это значение. Убедитесь, что мы добавили нашу стартовую процедуру после init. Таким образом, INIT будет запускаться только один раз при загрузке программы, START: будет началом каждого экземпляра программы.

*=$C000               ; SYS 49152 для начала

OURHEXNUM = $033C     ; Здесь будет храниться константа OURHEXVALUE
TESTBYTE = $0345      ; Здесь будет храниться наш тестовый байт для lsr
BIT7 = $0708          ; Это расположение 7-го бита, необходимое место для
                      ; 8 последовательных байтов после начального адреса
                    ; использование 0708 выгружает его прямо на экран RAM, внизу по центру
CHROUT = $FFD2        ; Процедура ядра вывода символов

Вот мы и достигли нашей первой цели. Теперь экран чист.

2 . Итак, теперь, когда экран чист, мы хотим вывести на экран метку, чтобы проинструктировать пользователя. Это снова будет использовать CHROUT, хотя есть гораздо более эффективные способы сделать это, однако, используя метод, который мы использовали для загрузки данных спрайта, мы можем использовать тот же самый цикл для вывода на экран.

Рассмотрите BASIC:
10 CLS
20 PRINT «ВВЕДИТЕ ШЕСТНАДЦАТЕРИЧНОЕ ЗНАЧЕНИЕ: »

     После запуска нашей функции очистки экрана на первом этапе экран очищается, и курсор оказывается в левом верхнем углу. В разделе INIT: мы создадим метку с именем START: 9.0010

Как упоминалось ранее, INIT вызывается только один раз. START вызывается каждый раз при запуске программы.

НАЧАЛО:
ldx #$00              ; Инициализировать X значением 0 для нашей метки
jsr WRITELABEL        ; JSR to WRITELABEL 

Нам понадобится цикл генерации меток и данные для использования в этом цикле.

НАПИСНАЯ ЭТИКЕТКА:    ; Печатает нашу этикетку и возвращает
lda HELLO,x
jsr CHROUT
inx
cpx #$13
bne WRITELABEL
rts
HELLO: .text ‘введите шестнадцатеричное значение: ‘ ; $13 байт

     HELLO находится сразу после окончания нашей программы внизу, как и данные Sprite из предыдущих глав. Используя X в качестве текущей позиции буквы, начиная с 0, мы можем загрузить байт в A, а затем запустить jsr CHROUT, чтобы вывести эту букву на экран. Пробел после двоеточия является допустимым байтом пробела и дает нам фактический пробел между текстом и начальной позицией курсора. Это зациклит $13[hex] раз, каждый раз увеличивая X для следующего байта и, в конечном счете, возвращая RTS с того места, где он был вызван в START.

На этом второй шаг завершен ……

3 . При выполнении машинного кода в C64 мигающий курсор автоматически отключается, экономя ненужные впустую процессорные циклы, если они не нужны. Однако мы хотели бы использовать его в качестве подсказки, поэтому в коде мы хотели бы снова включить его. Внизу на нулевой странице находится BLNSW, который контролирует, включен или выключен курсор. Нулевое значение включит его.

BLNSW = $CC           ; Курсор мигает вкл. или выкл.

     Поэтому мы добавляем BLNSW в наш список лучших ярлыков. Мы знаем, что для включения требуется значение  0. Непосредственно перед тем, как мы перешли к WRITELABEL, мы уже сделали X нулевым, так почему бы не поместить код для этого прямо над jsr WRITELABEL.

НАЧАЛО:
ldx #$00
stx BLNSW           ; Поддерживает мигание курсора для входных данных в нашей программе
jsr WRITELABEL      ; вывести нашу метку на экран

     Итак, теперь у нас есть очищенный экран, метка с надписью ENTER A HEX VALUE:  и мигающий курсор. До сих пор нам не требовалось вмешательства человека. То есть, до сих пор это было довольно легко. Что мы знаем прямо сейчас, так это то, что мы хотим от пользователя только два нажатия клавиш, то есть два байта. Нам нужен какой-то счетчик, который будет инициализирован нулем и будет увеличиваться при каждом нажатии клавиши. Мы можем использовать один байт в памяти, чтобы записать это. Я выбираю 033F

Итак, давайте добавим еще одну метку:

BYTECOUNTER = $033F   ; какая цифра была до

     Поскольку мы хотим, чтобы значение в BYTECOUNTER было равно нулю, не было бы здорово сделать то, что мы сделали в прошлый раз, и сохранить наш существующий X в BYTECOUNTER точно так же, как BLNSW

START:
ldy #$80            ; Первый битовый тест для бита 7 должен быть 10000000 $80
sty TESTBYTE        ; сохраните наш начальный тестовый байт здесь
ldx #$00
stx BLNSW           ; Поддерживает мигание курсора для входных данных в нашей программе
stx BYTECOUNTER     ; какое нажатие клавиши мы имеем до
jsr WRITELABEL      ; вывести нашу этикетку на экран

Давайте повторим, что у нас есть…..

*=$C000 ; SYS 49152 для начала

OURHEXNUM = $033C     ; Здесь будет храниться константа OURHEXVALUE
BYTECOUNTER = $033F  ; какие нажатия клавиш были до
TESTBYTE = $0345      ; Здесь будет храниться наш тестовый байт для lsr
BIT7 = $0708          ; Это расположение 7-го бита, требуется место для
                    ; 8 последовательных байтов после начального адреса
                    ; использование 0708 выгружает его прямо на экран RAM, внизу по центру
CHROUT = $FFD2        ; Процедура ядра вывода символов

INIT:
lda #$93
jsr CHROUT            ; Загрузите 147, hex $93 в регистр A и JSR в CHROUT

START:
ldx #$00
stx BLNSW             ; Курсор мигает для ввода в нашей программе0008 jsr WRITELABEL        ; вывести нашу этикетку на экран

WRITLABEL:           ; Печатает нашу этикетку и возвращает
lda HELLO,x
jsr CHROUT
inx
cpx #$13
bne WRITELABEL
rts
HELLO: . text ‘введите шестнадцатеричное значение: ‘ ; $13 [hex] bytes

     Как мы есть, с нашим мигающим курсором, расположенным в желаемом месте, пришло время перейти к новому местоположению. В этот момент мы находимся в режиме ожидания, отданы на милость пользователя, ожидая двух наших ключевых вводов… ожидание… и ожидание… и ожидание… …

     В ядре есть функции, которые ждут нажатия клавиши и, найдя ее, сбрасывают ее в аккумулятор. Эту технику проще всего продемонстрировать, и она работает эффективно только в том случае, если вся программа по замыслу должна останавливаться и ждать. Давайте добавим их к нашим меткам вверху.

SCNKEY = $FF9F      ; Сканировать клавиатуру на предмет нажатия клавиши
GETIN = $FFE4        ; Получить ввод из буфера, сохранить его в A

Время для нового блока кода:

SCANKBD:
jsr SCNKEY        ; наши подпрограммы ядра для сканирования клавиатуры
JSR GETIN         ; наша подпрограмма ядра для is key found dump in Accumulator
jmp SCANKBD

     Мы только что создали бесконечный цикл, как только мы перейдем к SCANKBD, выхода из нашей программы нет. Это потому, что мы не определили, как выйти из петли, в которую мы попали. Давайте дадим себе выход из всего этого.

SCANKBD:
jsr SCNKEY        ; наши подпрограммы ядра для сканирования клавиатуры
jsr GETIN         ; наша подпрограмма ядра для ключа, найденного дампом в Аккумуляторе
cmp #$51          ; Если введена буква Q……….
beq END          ; перейти к END

     Теперь все, что нам нужно, это какой-то быстрый и грязный код END для перехода в случае нажатия Q. Прямо над WRITELABEL: и забудьте об этом, он делает то, что должен, он возвращается к BASIC

END:
rts

     Итак, теперь у нас есть выход, но здесь все станет сложнее. Поскольку наши входные значения составляют шестнадцатеричное значение, они должны быть только от 0 до 9 и от A до F, за исключением Q, который мы уже определили.
    
    Наша функция уже проверяет, является ли Q равным HEX $51, но теперь мы хотели бы ограничить наши возможные допустимые входные данные, начиная с самого низкого до самого высокого сразу после beq END в SCANKBD, мы хотим, чтобы она игнорировала все значения, кроме наших желаемых. Предполагая, что Q не была нажата, тест продолжается.

cmp #$30          ; меньше шестнадцатеричного значения для 0?
bcc SCANKBD       ; да, проигнорируйте и продолжайте сканирование

    Таким образом, выше, если его значение меньше 0, оно недействительно и должно вернуться к сканированию ключа. Для продолжения оно должно быть больше 0

cmp #$3A          ; меньше шестнадцатеричного значения 9, но больше 0?
bcc DIGITCONVERT  ; перейти к нашей функции для преобразования цифры

     На данный момент мы уже знаем, что значение должно быть 0 или больше, но равно ли оно 9 или меньше.  Если оно равно 9 или меньше, мы знаем, что введенное значение должно находиться в диапазоне 0-9, и у нас есть действительный ввод. поэтому мы переходим к функции, чтобы начать наш процесс преобразования

     Но что, если оно больше 9, оно все еще может быть действительным? Это может быть А-Ф, помните, нам нужно продолжать тестирование. На данный момент мы знаем, что значение должно быть больше 9, иначе он разветвился бы на DIGITCONVERT.

cmp #$41          ; меньше значения A
bcc SCANKBD       ; меньше, чем шестнадцатеричное значение F, но больше, чем A?

Итак, теперь мы спрашиваем, является ли значение, которое, как мы знаем, больше 9, меньше A, потому что если это так, оно недействительно, и нам нужно снова отсканировать клавиатуру.

Если бы мы все еще были здесь, мы теперь знаем, что значение равно A или больше, но не было сделано, оно все равно должно быть F или меньше

cmp #$47          ; значение F или меньше
bcc ПРЕОБРАЗОВАТЬ БУКВУ ; перейти к нашей функции, чтобы преобразовать букву 

     Если значение равно F или меньше, мы знаем, что у нас есть допустимый ввод в нашем диапазоне от A до F. Мы можем перейти к LETTERCONVERT.

Вот наш полный SCANKBD:

;;;;;;;;;;;;;;;;; Наша функция сканирования клавиатуры, если клавиша нажата, появится
;;;;;;;;;;;;;;;;; В аккумуляторе шестнадцатеричное значение и проверено

SCANKBD:
jsr SCNKEY        ; наши подпрограммы ядра для сканирования клавиатуры
jsr GETIN         ; наша подпрограмма ядра для ключа, найденного дампом в Аккумуляторе
cmp #$51          ; Если введена буква Q. ………
beq END          ; перейти к END
cmp #$30          ; меньше шестнадцатеричного значения для 0?
bcc SCANKBD       ; да, игнорировать и продолжать сканирование
cmp #$3A          ; меньше шестнадцатеричного значения 9, но больше 0?
bcc DIGITCONVERT  ; перейти к нашей функции для преобразования цифры
cmp #$41          ; меньше значения A
bcc SCANKBD       ; меньше, чем шестнадцатеричное значение F, но больше, чем A?
cmp #$47          ; перейти к нашей функции, чтобы преобразовать букву
bcc ПРЕОБРАЗОВАТЬ БУКВУ ; перейти к нашей функции для преобразования буквы        
jmp SCANKBD       ; если что-либо выходит за рамки этих критериев, игнорируйте 
                  ; его и продолжайте сканировать  0-9 или A-F или Q

     Так зачем две отдельные ветки? Чтобы новичкам было легко понять, я сократил код, чтобы он обрабатывал числа и буквы таким образом, чтобы его было легко увидеть. Из-за их шестнадцатеричных значений в логическом порядке A не появляется сразу после 9 . Вы увидите через мгновение

Давайте начнем с LETTERCONVERT:

     Мы хотим сохранить значение, которое вы видите на клавиатуре. не его шестнадцатеричное значение. то есть число 5 должно быть сохранено как 05. Однако, прежде чем мы будем манипулировать им, мы хотим вывести на экран клавишу, которую пользователь нажал, на наш курсор с помощью CHROUT.

     Связь этих двух функций очевидна и подробно описана здесь. Вычтите $36 из буквы, чтобы получить ее шестнадцатеричное значение, вычтите $2F из числа, чтобы получить его шестнадцатеричное значение

ПРЕОБРАЗОВАНИЕ ПИСЬМА:
jsr CHROUT      ; Давайте напечатаем цифру, прежде чем мы с ней возимся
sbc #$36        ; Вычитает шестнадцатеричное значение 2F, чтобы получить фактическое значение в памяти
jmp MAINCONVERT ; перейти к MAINCONVERT после выполнения подпрограммы

Теперь нам нужна наша функция для преобразования DIGITS 0-9

DIGITCONVERT:
jsr CHROUT      ; Давайте выведем цифру на экран, прежде чем мы с ней возимся
sbc #$2F        ; Вычитает шестнадцатеричное значение 2F, чтобы получить фактическое значение в памяти
                ; Программа перейдет прямо к MAINCONVERT после
                ; завершая эту подпрограмму, так почему бы не поставить ее чуть выше
                ; MAINCONVERT и сохраните программу пробелом и циклами                    ; запуска jmp MAINCONVERT. LETTERCONVERT не имеет
                ; это роскошь, но там 10 цифр и всего шесть букв
                ; поэтому логично оставить DIGITCONVERT чуть выше
                ; MAINCONVERT

     После внесения этого изменения мы либо переходим, либо, в случае с 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
06 =     00000110   ASL -> 2-й
12 =     00001100   ASL -> 3-й
24 =     00011000   ASL -> 4-й
48 =       00110000   3 выводится 48 (decimalEX 9)0010

ГЛАВНОЕПРЕОБРАЗОВАНИЕ:
ldy BYTECOUNTER ; Загрузить Y текущим счетчиком BYTE                          
cpy #$01        ; Находимся ли мы во втором байте, LSB               
beq PROCESS   ; ДА, оставьте преобразованный байт в покое и вернитесь к ПРОЦЕССУ
asl             ;
над уровнем моря             ; Сдвинем двоичное значение влево четыре раза           
над уровнем моря             ; превращает 01 в 10, 02 в 20, 03 в 30 и т. д. и т. д. и т. д.
asl             ; просто отличный трюк, пока ничего не превышает FF            
               ; чего не будет, максимально возможная сумма равна F0            
jmp PROCESS     ; вернуться к процессу

Теперь мы переходим к ПРОЦЕССУ, нам понадобится место для хранения этих двух преобразованных байтов. Это означает новые метки вверху

LOWBYTE = $033D       ; хранилище ввода первой цифры
HIGHBYTE = $033E      ; хранение второй цифры ввода

С самого начала мы загружаем наш BYTECOUNTER в X, затем мы сохраняем наше значение в LOWBYTE,X
, если X=0 значение будет сохранено в LOWBYTE
, если X=1  значение будет храниться в LOWBYTE+1, которое мы назвали HIGHBYTE

. На самом деле нам не нужна метка с именем HIGHBYTE, но она не скомпилирована, поэтому это просто ссылка.

ПРОЦЕСС:          ; Здесь мы продолжаем хранить значение в правильном месте
ldx BYTECOUNTER  ; вывести BYTECOUNTER в X
sta LOWBYTE,x     ; помещает наши значения в LOWBYTE и HIGHBYTE
inx               ; Мы должны увеличить BYTECOUNTER на 1
stx BYTECOUNTER ; и сохраните новое значение в BYTECOUNTER
cpx #$02          ; если BYTECOUNTER равен $02, добавление значений
bne SCANKBD       ; Не 2, продолжайте поиск входов
;;;;; Если мы правы здесь, это означает, что теперь у нас есть два байта, мы должны
;;;;; Сложите их вместе, чтобы получить окончательное шестнадцатеричное значение для преобразования в двоичное число
;;;;; Мы сохраним окончательное значение в OURHEXNUM и перейдем к SETCONVERT
clc   ; на всякий случай очистить все скрытые флаги переноса
lda LOWBYTE       ; загрузить младший байт в A
adc HIGHBYTE      ; добавить к нему старший байт
sta OURHEXNUM     ; сохранить окончательное значение в OURHEXNUM для обработки
jmp SETCONVERT    ; перейти к конверсионной части нашей программы

     При сохранении байтов мы можем видеть, находимся ли мы на 1-м или втором байте. После увеличения X мы можем видеть, находимся ли мы на первом введенном байте или на втором. После обработки первого байта X=1, поэтому, если мы CPX #$02, мы знаем, что оба байта введены. Если X не равно 2, то введен только 1 байт, и мы возвращаемся к функции SCANKBD: и делаем это снова. , если 2, то не ответвляемся, продолжаем на

4 . Итак, теперь мы, например, набрали 3 и F, преобразовали их в 03 и 0F, перевернули цифру в первой, чтобы получить 30 и 0F.

Теперь мы …….
Очистите флаг переноса
Загрузка A со значением Lowbyte 0F
Добавить его к значению Highbyte 30
, которое дает нам 3F
и хранит наше значение в нашемгенме, это было исходное хранилище точка, которую мы использовали в более ранней программе, где шестнадцатеричное значение было жестко запрограммировано.

5 . Обратите внимание на первые две строки, которые я закомментировал в коде, они нам не нужны. Все наши усилия были направлены на то, чтобы сохранить значение в OURHEXNUM с клавиатуры, что мы и сделали.

SETCONVERT:
;lda OURHEXVALUE ; это будет тестовый номер
;sta OURHEXNUM   ; мы сохраним здесь номер теста на постоянной основе     
ldx #$00         ; Инициализировать X для нашего цикла

ПРЕОБРАЗОВАНИЕ:
lda OURHEXNUM    ; загрузите наш тестовый шестнадцатеричный номер, это константа
и TESTBYTE     ; замаскируйте его нашим тестовым байтом
cmp #$00         ; результат 00?
bne STORE1       ; Нет, jsr to STORE1
lda #$30         ; Загрузите отображаемое значение 0 в A
jmp CONTINUE

STORE1:
lda #$31         ; Загрузите отображаемое значение 1 в A

ПРОДОЛЖИТЬ:
sta BIT7,x       ; Загрузите отображаемое значение в A
inx              ; Увеличение X для нашего цикла
lda TESTBYTE     ; загрузить тестовый байт в A0008 лср              ; разделить на 2
sta TESTBYTE     ; сохранить новый тестовый байт обратно в свою область памяти
cpx #$08         ; Х=8?
bne ПРЕОБРАЗОВАНИЕ ; Нет, вернуться к ПРЕОБРАЗОВАНИЮ

6 . Я собираюсь вставить здесь в середине кода. Как только мы ввели наше второе число, двоичное значение появится внизу экрана посередине. Если бы мы сразу вернулись к INIT, мы бы очистили экран и никогда не увидели бы выведенное значение. Нет необходимости очищать весь экран, только две позиции, в которых мы ввели наш номер.

;;;;;;;;; ОТПУСТИТЕ ДВЕ ЦИФРЫ, УСТАНОВИТЕ КУРСОР В ИСХОДНУЮ ПОЗИЦИЮ ВВОДА
;;;;;;;;;
lda #$20        ; загрузить значение пробела в A
sta $0413       ; сохраните его в наших входных числах, чтобы очистить его
sta $0414       ; для следующего набора входов
clc ; очистить все скрытые флаги переноса на всякий случай
ldx #$00        ; установить X для верхней строки
ldy #$00        ; установить Y для первого символа
jsr PLOT        ; переместить курсор
jmp START       ; повторите весь процесс снова с СТАРТ

     Поэтому мы загружаем A со значением $20, которое является пустым пространством, и очищаем с его помощью два наших местоположения, $0413 и $0414. К сожалению, именно здесь были наши две цифры, сохраняя эту легкость, вторая цифра приводит вещи в движение и, кажется, почти очищается сама собой. Ничего страшного, возможно, в будущем мы сможем реализовать ожидание RETURN, чтобы все заработало. Установив X с координатой X и Y с координатой Y и jsr в PLOT. мы перемещаем курсор в верхнюю левую позицию, где мы генерируем наш текст ENTER A HEX VALUE:

И так все начинается сначала……..

Наш полный код……

; Программа C64 Hex to Binary Converter
; 64код стиля ассемблера ТАСС для 6502
; Джордан Рубин, 2014 г. http://technocoma.blogspot.com
;
; Принимает шестнадцатеричное значение в качестве входных данных, преобразует его в двоичное для отображения 
; на экране как двоичное число. Нажмите Q для выхода  
   
*=$C000 ; SYS 49152 для начала

OURHEXNUM = $033C     ; Здесь будет храниться константа OURHEXVALUE
МЛАДШИЙ БАЙТ = $033D       ; хранилище ввода первой цифры
HIGHBYTE = $033E      ; хранилище ввода второй цифры
BYTECOUNTER = $033F  ; какая цифра была до
TESTBYTE = $0345      ; Здесь будет храниться наш тестовый байт для lsr
BIT7 = $0708          ; Это расположение 7-го бита, необходимое место для
                  ; 8 последовательных байтов после начального адреса
                  ; использование 0708 выгружает его прямо на экран RAM, внизу по центру
CHROUT = $FFD2        ; Процедура ядра вывода символов
TEXTSTART = $0400     ; Где мы хотим начать метку для ввода
SCNKEY = $FF9F        ; Сканировать клавиатуру на предмет нажатия клавиши
GETIN = $FFE4         ; Получить ввод
BLNSW = $CC           ; Включение или выключение мигания курсора
PLOT = $FFF0          ; Установка/чтение положения курсора

nop                   ; привыкаю, оставляю на пробу и снимаю по
                 ; конец проекта

INIT:
lda #$93
jsr CHROUT ; Загрузите 147, шестнадцатеричные $93 в регистр A и JSR в CHROUT 9. 0008                       ; (Очищает экран)

НАЧАЛО:
ldy #$80             ; Первый битовый тест для бита 7 должен быть 10000000 $80
sty TESTBYTE         ; сохраните наш начальный тестовый байт здесь
ldx #$00             ; Установите для X значение 0
stx BLNSW            ; Поддерживает мигание курсора для входных данных в программе
stx BYTECOUNTER      ; Сделайте наш счетчик байтов равным 0, нам нужно 2 байта
                     ; для выполнения операции
jsr WRITELABEL       ; вывести нашу этикетку на экран
jmp SCANKBD          ; перейти к началу процедуры scanKDB

SETCONVERT:
ldx #$00             ; Инициализировать X для нашего цикла

CONVERTION:
lda OURHEXNUM  ; загрузить наш тестовый шестнадцатеричный номер, это из пользовательского ввода
и TESTBYTE    ; замаскируйте его нашим тестовым байтом
cmp #$00        ; результат 00?
bne STORE1      ; Нет, jsr to STORE1
lda #$30        ; Загрузите отображаемое значение 0 в A
jmp CONTINUE

STORE1:
lda #$31       ; Загрузите отображаемое значение 1 в A

ПРОДОЛЖЕНИЕ:
sta BIT7,x     ; Загрузите отображаемое значение в A
inx            ; Увеличение X для нашего цикла
lda TESTBYTE  ; загрузить тестовый байт в A
lsr            ; разделить его на 2
sta TESTBYTE   ; сохранить новый тестовый байт обратно в свою область памяти
cpx #$08       ; Х=8?
bne ПРЕОБРАЗОВАНИЕ ; Нет, вернуться к ПРЕОБРАЗОВАНИЮ

;;;;;;;;; ОТПУСТИТЕ ДВЕ ЦИФРЫ, УСТАНОВИТЕ КУРСОР В ИСХОДНУЮ ПОЗИЦИЮ ВВОДА
;;;;;;;;;
lda #$20        ; загрузить значение пробела в A
sta $0413       ; сохраните его в наших входных числах, чтобы очистить его
sta $0414       ; для следующего набора входов
clc ; очистить все скрытые флаги переноса на всякий случай
ldx #$00        ; установить X для верхней строки
ldy #$00        ; установить Y для первого символа
jsr PLOT        ; переместить курсор
jmp START       ; повторите весь процесс снова, начиная с START
               

;;;;;;;;;;;;;;;;; Наша функция сканирования клавиатуры, если клавиша нажата, она появится
;;;;;;;;;;;;;;;; В аккумуляторе шестнадцатеричное значение и проверено

SCANKBD:
jsr SCNKEY        ; наши подпрограммы ядра для сканирования клавиатуры
jsr GETIN         ; наша подпрограмма ядра для is key found dump in Accumulator
cmp #$51          ; Если введена буква Q. ………
beq END         ; перейти к END
cmp #$30          ; меньше шестнадцатеричного значения для 0?
bcc SCANKBD       ; да, игнорировать и продолжать сканирование
cmp #$3A          ; меньше шестнадцатеричного значения 9но больше 0?
bcc DIGITCONVERT  ; перейти к нашей функции для преобразования цифры
cmp #$41          ; меньше значения A
bcc SCANKBD       ; меньше, чем шестнадцатеричное значение F, но больше, чем A?
cmp #$47          ; перейти к нашей функции для преобразования буквы
bcc LETTERCONVERT ; перейти к нашей функции для преобразования буквы        
jmp SCANKBD       ; если что-либо выходит за рамки этих критериев, игнорируйте 
                  ; и продолжайте сканировать 0–9, A–F или Q

9.0006 ПРОЦЕСС:         ; Здесь мы продолжаем хранить значение в правильном месте
ldx BYTECOUNTER  ; вывести BYTECOUNTER в X
sta LOWBYTE,x     ; помещает наши значения в LOWBYTE и HIGHBYTE
inx               ; Мы должны увеличить BYTECOUNTER на 1
stx BYTECOUNTER ; и сохраните новое значение в BYTECOUNTER
cpx #$02          ; если BYTECOUNTER равен $02, добавление значений
bne SCANKBD       ; Не 2, продолжайте поиск входов

;;;;; Если мы здесь, значит, теперь у нас есть два байта, мы должны
;;;;; Сложите их вместе, чтобы получить окончательное шестнадцатеричное значение для преобразования в двоичное число
;;;;; Мы сохраним окончательное значение в OURHEXNUM и перейдем к SETCONVERT
clc               ; очистить все скрытые флаги переноса на всякий случай
lda LOWBYTE       ; загрузить младший байт в A
adc HIGHBYTE      ; добавьте к нему старший байт
sta OURHEXNUM     ; сохранить окончательное значение в OURHEXNUM для обработки
jmp SETCONVERT    ; перейти к конверсионной части нашей программы

LETTERCONVERT:
jsr CHROUT      ; Давайте напечатаем цифру, прежде чем мы с ней возимся
sbc #$36        ; Вычитает шестнадцатеричное значение 2F, чтобы получить фактическое значение в памяти
jmp MAINCONVERT ; перейти к MAINCONVERT после выполнения процедуры

DIGITCONVERT:
jsr CHROUT      ; Давайте выведем цифру на экран, прежде чем мы с ней возимся
sbc #$2F        ; Вычитает шестнадцатеричное значение 2F, чтобы получить фактическое значение в памяти
                ; Программа перейдет прямо к MAINCONVERT после
                ; завершая эту подпрограмму, так почему бы не поставить ее чуть выше
                ; MAINCONVERT и сохраните программу в пространстве и циклах 
                ; запуска jmp MAINCONVERT. LETTERCONVERT не имеет
                ; это роскошь, но там 10 цифр и всего шесть букв
                ; поэтому логично оставить DIGITCONVERT
                ; чуть выше MAINCONVERT

MAINCONVERT:
ldy BYTECOUNTER ; Загрузить Y текущим счетчиком BYTE                          
cpy #$01        ; Находимся ли мы во втором байте, LSB               
beq PROCESS   ; ДА, оставьте преобразованный байт в покое и вернитесь к ПРОЦЕССУ                                            
asl             ;
над уровнем моря             ; Сдвинем двоичное значение влево четыре раза           
над уровнем моря             ; превращает 01 в 10, 02 в 20, 03 в 30 и т. д. и т. д. и т. д.
asl             ; просто отличный трюк, пока ничего не превышает FF            
; чего не будет, максимально возможная сумма os F0            
jmp PROCESS     ; вернуться к процессу

END:            ; убивает программу
rts

WRITELABEL:    ; Печатает нашу этикетку и возвращает
lda HELLO,x
jsr CHROUT
inx
cpx #$13
bne WRITELABEL
rts
HELLO: . text ‘введите шестнадцатеричное значение: ‘ ; 13 байт                    

NEXT——>
Понимание сборки 6502 на Commodore 64 — (17) Подробное описание стека и регистра ЦП

Содержание

Прерывания DOS

Прерывания DOS

DOS INT 21h — Коды функций DOS

Следующий сокращенный список прерываний DOS был извлечен из большой список, составленный Ральфом Брауном. Они доступны на любом зеркале Simtel. (например, sunsite.anu.edu.au) в каталоге ms-dos/info/interNNp.zip 9Разрыв проверен

  • последним выводимым символом будет символ в DL, если только DL=09h при вводе, и в этом случае AL=20h, так как вкладки расширяются до пробелов
  • , если стандартный вывод перенаправляется в файл, проверка ошибок не выполняется (запись защищенные, полные носители и т. д.) выполняются
  • См. также: AH=06h,AH=09h

    АХ = 05h — ЗАПИСАТЬ СИМВОЛ НА ПРИНТЕР

    Ввод: DL = символ для печати

    Примечания:

    • клавиатура проверена на ^C/^Break 9Разрыв НЕ проверяется
    • , если возвращенный символ 00h, пользователь нажал клавишу с расширенным код ключа, который будет возвращен при следующем вызове этой функции
    • , хотя возврат AL=00h, когда нет доступных символов, невозможен. Break 9Разрыв проверен
    • читает со стандартного ввода

    См. также: AH=0Ch

    Формат входного буфера DOS:

    Смещение Размер Описание
    00 1 максимальный буфер символов может содержать
    01 1 количество символов из последнего ввода, которые могут быть вызваны ИЛИ количество символов фактически прочитанные символы, за исключением CR 9Разрыв проверен

    См. также: AH=06h»ВХОД»

    АХ = 0Ch — ОЧИСТИТЬ БУФЕР И СЧИТАТЬ СТАНДАРТНЫЙ ВХОД

    Ввод:

    • AL = функция ввода STDIN для выполнения после очистки буфера
    • другие регистры, соответствующие функции ввода

    Возврат: в зависимости от указанной функции ввода

    Примечание: если AL не является одним из 01h, 06h, 07h, 08h или 0Ah, буфер сбрасывается но попытка ввода не предпринимается

    См. также: AH=01h,AH=06h»INPUT»,AH=07h,AH=08h,AH=0Ah

    АХ = 0Dh — СБРОС ДИСКА

    Примечания. Эта функция записывает все измененные дисковые буфера на диск, но не не обновлять информацию каталога

    См. также: AX=5D01h

    АХ = 0Eh — ВЫБЕРИТЕ ПРИВОД ПО УМОЛЧАНИЮ

    Запись: DL = новый диск по умолчанию (0=A:, 1=B: и т. д.)

    Возврат: AL = количество потенциально допустимых букв дисков

    Примечания: возвращаемое значение представляет собой самый высокий из имеющихся дисков

    См. также: AH=19h,AH=3Bh,AH=DBh

    АХ = 19h — ПОЛУЧИТЬ ТЕКУЩИЙ ДИСК ПО УМОЛЧАНИЮ

    Возврат: AL = диск (0=A:, 1=B: и т. д.)

    См. также: AH=0Eh,AH=47h,AH=BBh

    АХ = 25h — УСТАНОВИТЬ ВЕКТОР ПРЕРЫВАНИЯ

    Ввод:

    • AL = номер прерывания
    • DS:DX -> новый обработчик прерываний

    Примечания: эта функция предпочтительнее прямого изменения прерывания векторная таблица

    См. также: AX=2501ч,AH=35ч

    АХ = 2Ач — ПОЛУЧИТЬ СИСТЕМНУЮ ДАТУ

    Возврат: CX = год (1980-2099) DH = месяц DL = день AL = день недели (00h=воскресенье)

    См. также: AH=2Bh»DOS»,AH=2Ch,AH=E7h

    АХ = 2Bh — УСТАНОВИТЬ СИСТЕМНУЮ ДАТУ

    Запись: CX = год (1980-2099) DH = месяц DL = день

    Возврат:

    • AL = 00 успешно
    • FFh неверная дата, системная дата не изменилась

    Примечание: DOS 3.3+ также устанавливает часы CMOS

    См. также: AH=2Ah,AH=2Dh

    АХ = 2Ch — ПОЛУЧИТЬ СИСТЕМНОЕ ВРЕМЯ

    Возврат: CH = час CL = минута DH = секунда DL = 1/100 секунды

    Примечание: в большинстве систем разрешение системных часов составляет около 5/100 с, поэтому возвращаемое время обычно не увеличивается на 1 в некоторых системах, DL может всегда возвращать 00h

    См. также: AH=2Ah,AH=2Dh,AH=E7h

    АХ = 2Dh — УСТАНОВИТЬ СИСТЕМНОЕ ВРЕМЯ

    Ввод: CH = час CL = минута DH = секунда DL = 1/100 секунды

    Возврат:

    • AL = 00h успешно
    • FFh, если неверное время, системное время не изменилось

    Примечание: DOS 3. 3+ также устанавливает часы CMOS

    См. также: AH=2Bh»DOS»,AH=2Ch

    АХ = 2Eh — УСТАНОВИТЬ ФЛАГ ПРОВЕРКИ

    Запись: AL = новое состояние флага проверки (00 off, 01h o)

    Примечания:

    • состояние по умолчанию при загрузке системы выключено
    • , когда ON, все записи на диск проверяются, если драйвер устройства поддерживает проверка чтения после записи

    См. также: AH=54h

    АХ=30ч — ПОЛУЧИТЬ ВЕРСИЮ DOS

    Запись: AL = что возвращать в BH (номер OEM 00h, флаг версии 01h)

    Возврат:

    • AL = основной номер версии (00h, если DOS 1.x)
    • AH = дополнительный номер версии
    • BL:CX = 24-битный серийный номер пользователя (в большинстве версий это не используется), если DOS <5 или AL=00h
    • BH = OEM-номер MS-DOS, если DOS 5+ и AL=01h
    • BH = флаг версии, бит 3: DOS находится в ПЗУ, другое: зарезервировано (0)

    Примечания:

    • DOS 4. 01 и 4.02 идентифицируют себя как версию 4.00
    • MS-DOS 6.21 сообщает о своей версии как 6.20; версия 6.22 возвращает правильный значение
    • Windows95 возвращает версию 7.00 (базовая MS-DOS)

    См. также: AX=3000h/BX=3000h,AX=3306h,AX=4452h

    АХ=35ч — ПОЛУЧИТЬ ВЕКТОР ПРЕРЫВАНИЯ

    Запись: AL = номер прерывания

    Возврат: ES:BX -> текущий обработчик прерывания

    См. также: AH=25h,AX=2503h

    АХ = 36ч — ПОЛУЧИТЬ СВОБОДНОЕ МЕСТО НА ДИСКЕ

    Запись: DL = номер диска (0=по умолчанию, 1=A: и т. д.)

    Возврат:

    • AX = FFFFh, если неверный диск
    • AX = секторов на кластер BX = количество свободных кластеров CX = байтов на сектор DX = общее количество кластеров на диске

    Примечания:

    • свободное место на диске в байтах равно AX * BX * CX
    • общее место на диске в байтах равно AX * CX * DX
    • «потерянных кластера» считаются используемыми
    • эта функция не возвращает правильных результатов на компакт-дисках; используйте AX=4402h»CD-ROM» вместо

    См. также: AH=1Bh,AH=1Ch,AX=4402h»CD-ROM»

    АХ = 39h — «MKDIR» — СОЗДАТЬ ПОДКАТАЛОГ

    Запись: DS:DX -> имя пути ASCIZ

    Возврат:

    • CF очищается в случае успеха AX уничтожается
    • CF установлен при ошибке AX = код ошибки (03h,05h)

    Примечания:

    • все каталоги по указанному пути, кроме последнего, должны существовать
    • сбой, если родительский каталог является корневым и заполнен
    • DOS 2.x-3.3 позволяют создать каталог достаточно глубоко, чтобы невозможно сделать этот каталог текущим каталогом, потому что путь превысит 64 символа

    См. также: AH=3Ah,AH=3Bh,AH=6Dh

    АХ = 3Ah — «RMDIR» — УДАЛИТЬ ПОДКАТАЛОГ

    Запись: DS:DX -> ASCIZ путь к удаляемому каталогу

    Возврат:

    • CF очищается в случае успеха, AX уничтожается
    • CF установлен при ошибке AX = код ошибки (03h,05h,06h,10h)

    Примечания: каталог должен быть пустым (содержать только записи ‘. ‘ и ‘..’)

    См. также: AH=39h,AH=3Bh

    АХ = 3Bh — «CHDIR» — УСТАНОВИТЬ ТЕКУЩИЙ КАТАЛОГ

    Запись: DS:DX -> Путь ASCIZ, чтобы стать текущим каталогом (макс. 64 байт)

    Возврат:

    • CF очищается в случае успеха, AX уничтожается
    • CF установлен при ошибке AX = код ошибки (03h)

    Примечания: если новое имя каталога включает букву диска, диск по умолчанию не изменяется, только текущий каталог на этом диске

    См. также: AH=47h,AH=71h,INT 2F/AX=1105h

    АХ = 3Ch — «СОЗДАТЬ» — СОЗДАТЬ ИЛИ ОБРЕЗАТЬ ФАЙЛ

    Ввод:

    • СХ = файл атрибуты
    • DS:DX -> имя файла ASCIZ

    Возврат:

    • CF очищается в случае успеха, AX = дескриптор файла
    • CF установлен при ошибке AX = код ошибки (03h,04h,05h)

    Примечания: если файл с таким именем существует, он усекается до нуля длина

    См. также: AH=16h,AH=3Dh,AH=5Ah,AH=5Bh

    АХ = 3Dh — «ОТКРЫТЬ» — ОТКРЫТЬ СУЩЕСТВУЮЩИЙ ФАЙЛ

    Ввод:

    • AL = режимы доступа и совместного использования
    • DS:DX -> имя файла ASCIZ

    Возврат:

    • CF очищается в случае успеха, AX = дескриптор файла
    • CF установлен при ошибке AX = код ошибки (01h, 02h, 03h, 04h, 05h, 0Ch, 56h)

    Примечания:

    • указатель файла установлен на начало файла
    • дескрипторы файлов, которые унаследованы от родителя, также наследуют общий доступ и ограничения доступа
    • файлы могут быть открыты, даже если заданы скрытые или системные атрибуты

    См. также: AH=0Fh,AH=3Ch,AX=4301h,AX=5D00h

    АХ = 3Eh — «ЗАКРЫТЬ» — ЗАКРЫТЬ ФАЙЛ

    Запись: BX = дескриптор файла

    Возврат:

    • CF очищается в случае успеха, AX уничтожается
    • CF установлен при ошибке, AX = код ошибки (06h)

    Примечание: если файл был записан, выполняются все ожидающие записи на диск, метки времени и даты устанавливаются на текущее время, а каталог запись обновлена ​​

    См. также: AH=10h,AH=3Ch,AH=3Dh

    АХ = 3Fh — «ЧТЕНИЕ» — ЧТЕНИЕ ИЗ ФАЙЛА ИЛИ УСТРОЙСТВА

    Ввод:

    • BX = дескриптор файла
    • CX = количество байтов для чтения
    • DS:DX -> буфер для данных

    Возврат:

    • CF очищается в случае успеха — AX = число фактически прочитанных байтов (0, если в EOF перед вызовом)
    • CF установлен при ошибке AX = код ошибки (05h,06h)

    Примечания:

    • данные считываются, начиная с текущей позиции файла, и позиция файла обновляется после успешного чтения
    • возвращенный AX может быть меньше, чем запрос в CX, если частичный чтение произошло
    • при чтении из CON чтение останавливается на первом CR

    См. также: АХ=27ч,АХ=40ч,АХ=93ч

    АХ=40ч — «ЗАПИСЬ» — ЗАПИСЬ В ФАЙЛ ИЛИ УСТРОЙСТВО

    Ввод:

    • BX = дескриптор файла
    • CX = количество байтов для записи
    • DS:DX -> данные для записи

    Возврат:

    • CF очищается в случае успеха -AX = количество фактически записанных байтов
    • CF установлен при ошибке — AX = код ошибки (05h,06h)

    Примечания:

    • , если CX равен нулю, данные не записываются, а файл усекается или расширяется в текущую позицию
    • данные записываются, начиная с текущей позиции файла, и файл позиция обновляется после успешной записи
    • обычной причиной AX < CX при возврате является полный диск

    См. также: AH=28h,AH=3Fh

    АХ = 41H — «ОТКЛЮЧИТЬ» — УДАЛИТЬ ФАЙЛ

    Ввод:

    • DS:DX -> имя файла ASCIZ (без подстановочных знаков, см. примечания)
    • CL = маска атрибута для удаления (только вызов сервера, см. примечания)

    Возврат:

    • CF очищается в случае успеха, AX уничтожается (DOS 3.3) AL похоже на диск удаленного файла
    • CF установлен при ошибке AX = код ошибки (02h,03h,05h)

    Примечания:

    • (DOS 3.1+) подстановочные знаки разрешены при вызове через AX=5D00h, в котором В этом случае спецификация файлов должна быть канонической (как возвращается AH=60h), и только файлы соответствующие маске атрибута в CL удаляются
    • DOS не стирает данные файла; он просто становится недоступным потому что цепочка FAT для файла очищена
    • удаление открытого в данный момент файла может привести к повреждению файловой системы.

    См. также: AH=13h,AX=4301h,AX=4380h,AX=5D00h,AH=60h,AH=71h

    АХ=42ч — «LSEEK» — УСТАНОВИТЬ ТЕКУЩУЮ ПОЗИЦИЮ ФАЙЛА

    Ввод:

    • AL = источник перемещения 00h начало файла 01h текущая позиция в файле 02h конец файла
    • BX = дескриптор файла
    • CX:DX = смещение от начала новой позиции файла

    Возврат:

    • CF очищается в случае успеха, DX:AX = новая позиция файла в байтах от начала файла
    • CF установлен при ошибке, AX = код ошибки (01h,06h)

    Примечания:

    • для исходных точек 01h и 02h, указатель может располагаться перед началом файла; в этом случае ошибка не возвращается, но последующие попытки при вводе/выводе выдает ошибки
    • , если новая позиция находится за текущим концом файла, файл будет быть расширен следующей записью (см. AH=40h)

    См. также: AH=24h

    АХ=43 — ПОЛУЧИТЬ АТРИБУТЫ ФАЙЛА

    Ввод:

    • АЛ = 00ч
    • DS:DX -> имя файла ASCIZ

    Возврат:

    • CF очищается в случае успеха CX = файл атрибуты
    • CF установлен при ошибке, AX = код ошибки (01h,02h,03h,05h)
    • ОШИБКА

    : вместо этого Windows для рабочих групп возвращает код ошибки 05h (отказано в доступе) кода ошибки 02h (файл не найден) при попытке получить атрибуты несуществующего файла.

    См. также: AX=4301h,AX=4310h,AX=7143h,AH=B6h

    АХ=43 — «CHMOD» — УСТАНОВИТЬ АТРИБУТЫ ФАЙЛА

    Ввод:

    • АЛ = 01ч
    • CX = новый файл атрибуты
    • DS:DX -> имя файла ASCIZ

    Возврат:

    • CF очищается в случае успеха, AX уничтожается
    • CF установлен при ошибке, AX = код ошибки (01h,02h,03h,05h)

    Примечания:

    • не изменит биты метки тома или атрибута каталога, но изменить другие биты атрибута каталога
    • Сообщается, что MS-DOS 4. 01 закрывает файл, если он в данный момент открыт

    См. также: AX=4300h,AX=4311h,AX=7143h,INT 2F/AX=110Eh

    Битовые поля для атрибутов файла:

    Биты 7 6 5 4 3 2 1 0
    Описание общий архив каталог том. этикетка система скрыто только для чтения

    АХ = 47h — «CWD» — ПОЛУЧИТЬ ТЕКУЩИЙ КАТАЛОГ

    Ввод:

    • DL = номер диска (00h = по умолчанию, 01h = A: и т. д.)
    • DS:SI -> 64-байтовый буфер для имени пути ASCIZ

    Возврат:

    • CF очищается в случае успеха
    • CF установлен при ошибке, AX = код ошибки (0Fh)

    Примечания:

    • возвращаемый путь не включает диск или начальную обратную косую черту
    • многие продукты Microsoft для Windows полагаются на то, что AX равен 0100h в случае успеха

    См. также: AH=19h,AH=3Bh,AH=71h

    АХ = 4Ch — «ВЫХОД» — ЗАВЕРШЕНИЕ С КОДОМ ВОЗВРАТА

    Ввод: AL = код возврата

    Возврат: никогда не возвращает

    Примечания: если процесс не является своим родителем, все открытые файлы закрываются. и вся память, принадлежащая процессу, освобождается

    См. также: AH=00h,AH=26h,AH=4Bh,AH=4Dh

    АХ = 4Dh — ПОЛУЧИТЬ КОД ВОЗВРАТА (УРОВЕНЬ ОШИБКИ)

    Возврат:

    • AH = тип завершения (00=нормальный, 01h управление-C прерывание, 02h=критический прерывание по ошибке, 03h завершается и остается резидентным)
    • AL = код возврата

    Примечания:

    • слово, в котором DOS хранит код возврата, очищается после читается этой функцией, поэтому код возврата можно получить только один раз
    • COMMAND.COM сохраняет код возврата последней внешней команды. выполнен как ERRORLEVEL

    См. также: AH=4Bh,AH=4Ch,AH=8Ah

    АХ = 54h — ПОЛУЧИТЬ ФЛАГ ПРОВЕРКИ

    Возврат: AL = флаг проверки (00h=выкл. , 01h=вкл., т.е. все записи на диск проверены после написания)

    См. также: AH=2Eh

    АХ = 56h — «ПЕРЕИМЕНОВАТЬ» — ПЕРЕИМЕНОВАТЬ ФАЙЛ

    Ввод:

    • DS:DX -> имя существующего файла в формате ASCIZ (без подстановочных знаков, но см. ниже)
    • ES:DI -> новое имя файла ASCIZ (без подстановочных знаков)
    • CL = маска атрибута (только вызов сервера, см. ниже)

    Возврат:

    • CF очищается в случае успеха
    • CF установлен при ошибке, AX= код ошибки (02h,03h,05h,11h)

    Примечания:

    • позволяет перемещаться между каталогами на одном логическом томе
    • эта функция не устанавливает атрибут архива
    • открытые файлы нельзя переименовывать
    • (DOS 3.0+) позволяет переименовывать каталоги

    АХ = 57h — ПОЛУЧИТЬ ДАТУ И ВРЕМЯ ПОСЛЕДНЕЙ ЗАПИСИ ФАЙЛА

    Ввод:

    • AL = 00h (Получить атрибут)
    • BX = дескриптор файла

    Возврат:

    • CF очищается в случае успеха, CX = время файла DX = дата файла
    • CF установлен при ошибке, AX = код ошибки (01h,06h)

    См.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *