Изменение исходного кода для процессора 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

Оцени полезность:

15   голосов , оценка 3.8 из 5
Похожие ответы