Написать программы (.com и .exe) для проверки вводимого пароля с клавиатуры. В качестве пароля использовать первые 6 символов номера зачётки
Эту программу нужно написать как программу .com, так и как .exe. На самом деле в нашем случае отличия заключаются только в "окружении", то есть в определении и объявлении нужных машинных слов и меток. А так, две программы имеют "под капотом" один и тот же алгоритм.
Надеюсь, что основные используемые директивы уже нам знакомы, посмотрим на то, что появилось нового
cor_psw db '22u086$'
p_size = $ - cor_psw
buff db 128,?,p_size dup(?)В объявлениях этой лабороторной есть такие строки. Рассмотрим подробнее:
p_size = $ - cor_psw. Учтите, разбирался с этим сам. Не уверен в корректности объяснения!$- Указывает на нынешний адрес выполняемой команды. Таким образом получается что мы смотрим, куда мы попали после строчки выше, где мы определили строку. А после этого вычитаем адрес этой строки, в итоге у нас остаётся длина последовательности, в которой лежит строка.buff db 128,?,128 dup(?). Здесь мы объявляем буффер для ввода с клавиатуры. Первое значение - максимальная длина ввода (Дальше просто нельзя будет считать). Дальше, нам необходимо заполнить его, чтобы впоследствии мы могли туда положить прочитанные данные.
start:
push ax
mov dx,buff
mov ah,0x0a
int 21h ;ds:dx
pop ax
mov si,dx
add si,2
mov cx,p_size
dec cx
mov di,cor_psw
pusha
repe cmpsb ;ds:si и es:di
je correct
jmp wrongТак что же мы тут делаем. Вначале mov dx, buff мы указываем смещение для буфера. Дальше вызываем прерывание 21h с функцией 0x0a. Дальше мы сравниваем введённую строку с нашем паролем. В ds:si лежит введённая нами строка, а в es:di лежит правильный пароль.
wrong:
push dx
push ax
mov dx,false_msg
mov ah,09h
int 21h
pop ax
pop dx
jmp start
correct:
push dx
push ax
mov dx,cor_msg
mov ah,09h
int 21h
pop ax
pop dxВ блоках реакции мы просто выводим сообщение пользователю и делаем переход. Если пользователь ошибся, то мы снова переходим к вводу пароля, а если пароль правильный, то код продолжает выполнение (под блоком correct находится блок finish)
format MZ
entry code_seg:start
stack 400h
;--------------
segment data_seg
cor_psw db '22u086$'
p_size = $ - cor_psw
buff db 128,?,p_size dup(?)
cor_msg db 0xA, 0xD, 'Correct password', 0xA, 0xD, '$'
false_msg db 0xA, 0xD, 'Wrong password', 0xA, 0xD, '$'На самом деле, здесь почти всё то же самое, что и в программе .com. Обратим внимание на пару вещей:
format MZ- Указываем, что программа будет типа .exe под MS-DOSentry code_seg:start- Указывает точку входа в программуstack 400h- Указываем размер стекаsegment data_seg- Указываем сегмент с объявлениями. По нему мы будем обращаться для поиска нужной информации
start:
mov ax,data_seg
mov ds,ax
mov es,ax
mov dx,buff
mov ah,0x0a
int 21h ;ds:dx
mov ax, 0
mov si,dx
add si,2
mov cx,p_size
dec cx
mov di,cor_psw
pusha
repe cmpsb ;ds:si и es:di
je correct
jmp wrongВ данном случае, алгоритм такой же, как и в программе .com.
Разве что добавляется блок, где мы метку сегмента объявлений кладем в сегментный регистр ES. Это пригодится, когда мы будет сравнивать строки командой repe cmpsb.
Они абсолютно идентичны программе .com
mov ax,0x0
int 16h
mov ax, 0x4c00
int 21hВ отличие от программ .com, функция выхода имеет код 0x4C00. В остальном, то же самое, что было раньше.
Если вы найдёте ошибки или заходите уточнить или изменить определённую информацию, смело пишите, открывайте issue.
Учитывайте, что в данном случае много информации я найти не успел, так что разбирался самостоятельно.
