Изменение исходного кода для процессора 8086 - Assembler
Формулировка задачи:
Кто может пожалуйста немного нужно изменить код чтобы отличался от данного
;ASGN: N1
;Buff - строка с паролем
;MaxLen - Максимальная длина строки
MaxLen equ 100
.286
.model small
.stack 100h
.data
buff db 101 dup(?)
pass db 101 dup(?)
PathtoFile db '1.txt',0
Msg1 db 13,10,'Input password: $'
Msg2 db 13,10,'The password is incorrect$'
Msg_error db 'Error$'
Month db 'January$ '
db 'February$ '
db 'March$ '
db 'April$ '
db 'May$ '
db 'June$ '
db 'July$ '
db 'August$ '
db 'September$'
db 'October$ '
db 'November$ '
db 'December$ '
ln_pass dw 0
handle dw 0
cnt dw 3
s db ":$"
.code
startupcode
Open:
mov ah, 3dh
mov al, 00
lea dx, PathtoFile
int 21h
jc Error
mov handle,ax
jmp Readfile
Error:
mov ah,9
mov dx,offset Msg_error; ссылка на сообщение
int 21h
jmp exit
Readfile:
mov ah, 3fh
mov bx, handle
mov cx, 512
lea dx, pass
int 21h
jc Error
mov ln_pass, ax
PassAttempt:
mov di,offset buff ;Указатель на строку
xor cx,cx ;Счетчик введенных символов обнуляем
;вывод сообщения
mov ah,9
lea dx, Msg1
int 21h
PassLoop: ;Начало цикла ввода
mov ah,08h
int 21h ;Ждем нажатия клавиши
cmp al,0dh
je EndLoop ;Если Enter то закончить цикл
cmp cx,MaxLen
je PassLoop ;Если конец буфера строки то ждем Enter
mov [di],al ;Помещаем нажатую клавишу в буфер
inc di ;Увеличиваем адрес
inc cx ;Увеличиваем счетчик
mov ah,02h
mov dl,"*"
int 21h ;Выводим звездочку
jmp PassLoop ;На начало цикла
EndLoop:
xor al,al ;Обнуляем al
mov [di],al ;В конец нашей строки 0
push cx
push ds
pop es
lea si, buff
lea di, pass
mov cx, ln_pass
repe cmpsb
pop cx
je PrintDate
;вывод сообщения
mov ah,9
lea dx, Msg2
int 21h
dec cnt
cmp cnt,0
jne PassAttempt
jmp exit
PrintDate:
;перевод в начало следущей строки
mov ah,2
mov dl,0dh
int 21h
mov dl,0ah
int 21h
;получаем дату
mov ah,2ah
int 21h
;вывод дня
push cx
push dx
xor ax, ax
mov al, dl
call PrintNum
mov ah, 02h
mov dl, " "
int 21h
pop dx
;вывод месяца
mov ah,10
mov al, dh
dec dh
mov al,dh
mul ah
lea dx, Month
add dx, ax
mov ah, 9
int 21h
mov ah, 02h
mov dl, " "
int 21h
;вывод года
pop cx
mov ax, cx
call PrintNum
;перевод в начало следущей строки
mov ah,2
mov dl,0dh
int 21h
mov dl,0ah
int 21h
;Получаем время
mov ah,2ch
int 21h
;Вывод часа
push dx
push cx
xor ax,ax
mov al,ch
Call PrintNum
mov ah,9
lea dx,s
int 21h
;вывод минут
pop cx
xor ax,ax
mov al,cl
Call PrintNum
mov ah,9
lea dx,s
int 21h
;Вывод секунд
pop dx
xor ax,ax
mov al,dh
Call PrintNum
exit: ; Выход из программы
mov ah, 3eh ;закрытие файла
mov bx, handle
int 21h
mov ah,4ch
int 21h
;Макрос переводящий число в строку (не более 65535)
;num - число
;на выходе, в стеке хранится размер и число по разрядам
dectoascii macro num
mov cx,num
xor di,di
mov bx,10
@@1:
inc di
xor dx,dx
mov ax,cx
div bx
push dx
mov cx,ax
cmp cx,0
je @@2
jmp @@1
@@2:
push di
endm
printnum proc
dectoascii ax
;Вывод на экран
pop cx ;длина числа в cx
@@3:
mov ah,02h
pop dx ;восстанавливаем из стека очередной разряд
add dl,"0"
int 21h
loop @@3
ret
printnum endp
ENDРешение задачи: «Изменение исходного кода для процессора 8086»
textual
Листинг программы
.286 .model small .stack 100h ; размер стека ;ASGN: N1 ;Buff - строка с паролем ;MaxLen - Максимальная длина строки .data MaxLen equ 512 buff db MaxLen+1 dup(0) pass db MaxLen+1 dup(0) PathtoFile db '1.txt',0 Msg1 db 13,10,'Input password: $' Msg2 db 13,10,'The password is incorrect$' Msg_error db 'Error$' Month db 'January$ ' ; по 16 символов, чтоб пользоваться сдвигом на 4 db 'February$ ' db 'March$ ' db 'April$ ' db 'May$ ' db 'June$ ' db 'July$ ' db 'August$ ' db 'September$ ' db 'October$ ' db 'November$ ' db 'December$ ' ln_pass dw 0 handle dw 0 cnt dw 3 ; количество попыток ввода пароля .code startupcode ; Открываем файл на чтение Open: mov ah, 3dh ; открыть описатель файла mov al, 00 ; для чтения lea dx, PathtoFile ; ds:dx адрес строки ASCIIZ с именем файла int 21h jc Error mov handle,ax jmp Readfile Error: mov ah,9 ; Выдать строку на дисплей lea dx, Msg_error ; дрес строки, заканчивающейся символом '$' int 21h jmp quit ; Читаем из файла MaxLen байт в буфер pass Readfile: mov ah, 3fh ; читать файл через описатель mov bx, handle ; описатель файла lea dx, pass ; DS:DX = адрес буфера для чтения данных mov cx, MaxLen ; число считываемых байт int 21h jc Error mov ln_pass, ax ; читаем с консоли символы в buff (пароль) PassAttempt: mov ah, 09h ; Выдать строку на дисплей lea dx, Msg1 ; дрес строки, заканчивающейся символом '$' int 21h lea di, buff ; Указатель на строку xor cx, cx ; Счетчик символов PassLoop: cmp cx, MaxLen je EndLoop mov ah, 08h ; Консольный ввод без эха int 21h cmp al, 0dh ; Клавиша Enter je EndLoop mov [di],al ; Пишем в буфер inc di ; Сдвигаемся по буферу inc cx ; Увеличиваем счетчик mov ah, 02h ; вывод на дисплей mov dl, '*' int 21h jmp PassLoop EndLoop: xor al, al mov [di],0 ; Ставим 0 в конец buff ; сравниваем buff и pass (проверяем пароль) [cx уже содержит количество байт в buff] lea si, buff lea di, pass cld repe cmpsb je PrintDate ; проверка не удалась mov ah, 09h ; Выдать строку на дисплей lea dx, Msg2 ; дрес строки, заканчивающейся символом '$' int 21h dec cnt ; уменьшаем количество попыток cmp cnt, 0 jne PassAttempt ; отправляем вводить пароль снова jmp exit PrintDate: ; это перевод в начало следущей строки mov ah, 02h ; вывод на дисплей mov dl, 0dh ; 13 int 21h mov dl, 0ah ; 10 int 21h mov ah, 2ah ; дать системную дату int 21h ; AL = день недели (0=Вск, 1=Пнд,...6=Суб) DOS 3.0+ ; CX = год (1980 до 2099) ; DH = месяц (1 до 12) ; DL = день (1 до 31) push cx ; прячем в стеке год push dx ; потом месяц и день ;вывод дня movzx ax, dl call PrintNum mov ah, 02h ; вывод на дисплей (разделитель в дате) mov dl, ' ' int 21h pop dx ;вывод месяца (буквами) dec dh movzx ax, dh mov ah, 09h ; Выдать строку на дисплей lea dx, [Month+4*ax] ; DS:DX = адрес строки, заканчивающейся символом '$' int 21h mov ah, 02h ; вывод на дисплей (разделитель в дате) mov dl, ' ' int 21h pop cx ;вывод года mov ax, cx call PrintNum ; это перевод в начало следущей строки mov ah, 02h ; вывод на дисплей mov dl, 0dh ; 13 int 21h mov dl, 0ah ; 10 int 21h mov ah, 2ch ; дать время DOS int 21h ; CH = часы (0 до 23) ; CL = минуты (0 до 59) ; DH = секунды (0 до 59) ; DL = сотые доли секунды (0 до 99) push dx ; пишем в стек секунды и доли push cx ; потом часы и минуты ;Вывод часа movzx ax,ch Call PrintNum mov ah, 02h ; вывод на дисплей mov dl, ':' ; разделитель чисел int 21h ;вывод минут pop cx movzx ax,cl Call PrintNum mov ah, 02h ; вывод на дисплей mov dl, ':' ; разделитель чисел int 21h ;Вывод секунд pop dx movzx ax,dh Call PrintNum exit: mov ah, 3eh ; Закрыть описатель файла mov bx, handle ; описатель файла int 21h quit: mov ah, 4ch ; завершить программу -- EXIT int 21h ; al - код выхода ;Макрос переводящий число в строку (не более 65535) ;num - число ;на выходе, в стеке хранится размер и число по разрядам dectoascii macro num mov ax, num ; кладем число в ax mov bx, 10 ; будем делить его на 10 xor di, di ; количество цифр @@1: inc di xor dx, dx ; (ax:dx = num) div bx push dx ; последняя цифра уходит в стек test ax, ax jnz @@1 push di ; всего цифр тоже отправляем в стек endm printnum proc dectoascii ax pop cx ; количество цифр (счетчик цикла) @@3: mov ah, 02h ; вывод на дисплей pop dx ; вынимаем цифру из стека add dl, '0' int 21h loop @@3 ret printnum endp END