Написать программы (.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.
Учитывайте, что в данном случае много информации я найти не успел, так что разбирался самостоятельно.