2016-09-18 58 views
-1

我已經編寫了一個代碼作爲學校的最終項目...這是一個登錄表單。 它可以註冊並登錄,但我發現的唯一錯誤是我無法輸入16位數的密碼。登錄表單的改進8086

請給我反饋,我可以在程序中修復或改進什麼。

在此先感謝。

.MODEL small 
.STACK 100h 
.DATA 
uinp db 13, 0, 14 DUP('$') ; Username register input, max 12 letters     ; 
pinp db 17, 0, 16 DUP('$') ; Password register input, max 16 letters 

ulinp db 13, 0, 14 DUP('$') ; Username login input 
plinp db 17, 0, 16 DUP('$') ; Password login input 

wlmsg db "  Welcome user!  ", 10, 13, "$"  ;  
wlmsg2 db "  Please login...  ", 10, 13, "$" ; Welcome messages 
wlmsg3 db "  Press any key..  ", 10, 13, "$" ; 

umsg db "  Username:   ", 10, 13,  ; 
db "  Password:   $", 10, 13,  ; Username and password text 

question db "  Would you like to    ", 10, 13 ; 
    db "  (R) Register    ", 10, 13  ; Main menu text 
    db "  (L) Login    ", 10, 13   ; 
    db "   ()    $", 10, 13   ; 

errormsg db "   ERROR!  ", 10, 13   ; 
    db "  Please make sure you  ", 10, 13  ; 
    db " followed the instructions  ", 10, 13 ; Error message    ; JUST TO CLARIFY: 
    db "  and wrote your choice  ", 10, 13 ;        ; At first I wanted to create a file, write the username and password onto it 
    db "  with CAPITAL LETTERS  $", 10, 13 ;        ; and then read it. Turn's out that it was out of the course scope and it's not 
                         ; critical for the program. 

errormsg2 db "  username or password are incorrect ", 10, 13  ; Second error message 
     db "   try again later... $" 

afterRegisterMsg db "  Nice, now go back to menu $", 10, 13 ; After registration message 

sLogin db "         ", 10, 13 
    db "  ********************************* ", 10, 13 
    db "  *You have succesfully logged in!* ", 10, 13 ; Message after  succesful match to the user name and password 
    db "  *********************************$", 10, 13 
choice db ' '  ;o Choice of user in menu  

fLogin db "  Username and password are incorrect.",10 ,13 ; Fail to login message 
    db "  Please try again and make sure", 10, 13 
    db "   enterd the right username and", 10, 13 
    db "     password.   $", 10, 13 

.CODE               

mov ax, @data     
mov ds, ax         


Welcome: 
mov dx, offset wlmsg ; First message 
mov ah, 09h 
int 21h 

mov dx, offset wlmsg2 ; Second message 
mov ah, 09h 
int 21h 

mov dx, offset wlmsg3 ; Third message 
mov ah, 09h 
int 21h 

mov ah, 01h ; Wait for user to continue 
int 21h  ; 

call clear ; Clear screen 


Menu: 
call clear    ; Clear screen 

mov dx, offset question ; 
mov ah, 09h    ; Print menu 
int 21h     ; 

mov dh, 03h  ; 
mov dl, 12   ; 
mov bh, 0   ; Set cursor to (12,3) 
mov ah, 02h  ; 
int 10h 

mov ah, 01h    ; 
int 21h     ; Reads user's choice   


cmp al, 'R' ; Check if user picked register option 

je Register   ; Jump to 1register label 

cmp al, 'L' ; Check if user picked login option 

je Login    ; Jump to login label 
jmp Error 


Error: 
call clear 

mov dx, offset errormsg ; 
mov ah, 09h    ; Print error message 
int 21h     ; 

mov ah, 08h ; Wait for user to continue 
int 21h  ; 


jmp Menu     ; Jump back to menu 


Register: 
call clear   ; Clear screen 

mov dx, offset umsg ; 
mov ah, 09h   ; Print username 
int 21h    ;   

mov dx, 18  ; 
mov bh, 0   ; Set cursor to (18,0) 
mov ah, 02h  ; 
int 10h 

mov dx, offset uinp ; 
mov ah, 0Ah   ; Read username input and puts it into uinp 
int 21h    ; 

mov dh, 01h  ; 
mov dl, 18  ; 
mov bh, 0   ; Set cursor to (18,1) 
mov ah, 02h  ; 
int 10h 

mov dx, offset pinp  ; 
mov ah, 0Ah    ; Reads password input and puts it into pinp 
int 21h     ; 

call clear 

mov dx, offset afterRegisterMsg ; 
mov ah, 09h      ; Print after registration message 
int 21h       ; 

mov ah, 01h      ; Waits for user to click a button 
int 21h       ; 

jmp menu      ; Go back to menu 

Login: 
call clear    ; Clear screen 

mov dx, offset umsg ; 
mov ah, 09h   ; Prints username and password 
int 21h    ; 

mov dx, 18  ; 
mov bh, 0   ; Set cursor to (18,0) 
mov ah, 02h  ; 
int 10h 

mov dx, offset ulinp ; 
mov ah, 0Ah   ; Reads username login input 
int 21h    ; 

mov dh, 01h  ; 
mov dl, 18  ; 
mov bh, 0   ; Set cursor to (18,1) 
mov ah, 02h  ; 
int 10h 

mov dx, offset plinp ; 
mov ah, 0Ah   ; Reads password login input 
int 21h    ; 

call chkLength ; Match length 

mov dx, 0  ; 
mov cx, 0  ; Reset all the registers for compUser 
mov ax, 0  ; 

jmp CompareU ; Check if username is correct 

hlt 


chkLength:   ; 

mov dh, [uinp + 1] ; Finding the length of the username that the user have enterd 
mov dl, [ulinp + 1] ; "          "     " 

cmp dh, dl   ; Comparing their lengths 

jne Error2   ; If their lengths aren't equal there will be an error 

mov dh, [pinp + 1] ; Finding the length of the password that the user have enterd 
mov dl, [plinp + 1] ; "          "     " 

cmp dh, dl   ; Comparing their lengths 

jne Error2   ; Error if the strings don't have the same lengths 

ret     ; Go back to the login main 


Error2:    ; After comparing error 

call clear  ; call clear 

mov dx, offset errormsg2  ; 
mov ah, 09h     ; Error in case the user entered wrong username and password 
int 21h      ; 

mov ah, 01h  ; Wait for click 
int 21h   ; 

call clear  ; Clear screen 
int 20h   ; End the program   


CompareU:   ; Comparing the usernames 

mov dh, offset uinp ; Get uinp address 
add dh, 2  ; Add 2 to skip to the actaul string 

mov dl, offset ulinp ; Get ulinp address 
add dl, 2  ; Add 2 to skip to the actaul string 

add dh, cl  ; Adding the index to the address so it can know what character to go through 
add dl, cl  ; "                   " 

push cx   ; Maintaining the index count 

mov bh, 0  ; 
mov bl, dh  ; Going into the memory to get uinp actaul string 
mov ch, [bx] ; 

mov bh, 0  ; 
mov bl, dl  ; Going into the memory to get ulinp actaul string 
mov cl, [bx] ; 

cmp cl, ch  ; Comparing the two usernames  

jne Error2  ; If the usernames are not the same it sum as an error 

mov bh, 0  ; 
mov bl, dh  ; 
mov al, [bx] ; Cheking if the string ended 
cmp al, '$'  ; 

je resetReg  ; Reset all the registers for the password compare 

pop cx   ; Pop the index back out again so it could be increased 

inc cl   ; Increase the index by 1 to go over the next charachter 

jmp CompareU ; Jump back again to the head of the label to check all over again 


resetReg:   ; Reset registers label 

mov ax, 0  ; Reset ax 
mov bx, 0  ; Reset bx 
mov cx, 0  ; Reset cx 
mov dx, 0  ; Reset dx 

jmp CompareP ; Go to the password comparing 


CompareP:   ; Comparing the passwords 

mov dh, offset pinp ; Get pinp address 
add dh, 2  ; Add 2 to skip to the actaul string 

mov dl, offset plinp ; Get plinp address 
add dl, 2  ; Add 2 to skip to the actaul string 

add dh, cl  ; Adding the index to the address so it can know what character to go through 
add dl, cl  ; "                   " 

push cx   ; Maintaining the index count 

mov bh, 0  ; 
mov bl, dh  ; Going into the memory to get pinp actaul string 
mov ch, [bx] ; 

mov bh, 0  ; 
mov bl, dl  ; Going into the memory to get plinp actaul string 
mov cl, [bx] ; 

cmp cl, ch  ; Comparing the two passwords  

jne Error2  ; If the passwords are not the same it sum as an error 

mov bh, 0  ; 
mov bl, dh  ; 
mov al, [bx] ; Cheking if the string ended 
cmp al, '$'  ; 

je successLogin ; Letting the user know that he enterd and both username and password are true 

pop cx   ; Pop the index back out again so it could be increased 

inc cl   ; Increase the index by 1 to go over the next charachter 
jmp CompareP ; Jump back again to the head of the label to check all over again 

successLogin:  ; Successful login message 

call clear  ; Clearing the screen 

mov dx, offset sLogin  ; 
mov ah, 09h    ; Print the successful login message 
int 21h     ; 

mov ah, 01h  ; Waiting for the user to make it's final click 
int 21h   ; 

int 20h    ; End of the program in case the login was succesful 

clear: 
mov ah, 06h  ; 
mov al, 00h  ; 
mov bh, 0Fh  ; 
mov cx, 0   ; Clear Screen 
mov dh, 100  ; 
mov dl, 40  ; 
int 10h   ; 

mov dx, 0   ; 
mov bh, 0   ; Set cursor to (0,0) 
mov ah, 02h  ; 
int 10h 

ret    ; Return back to where it was called 

int 20h    ; End of program no matter what 
+0

歡迎SO。你嘗試過調試嗎?如果沒有,請做。一步一步跟蹤它,觀察寄存器值。哪一行的行爲與你所期望的不同? –

+0

如果這項工作,你要求代碼審查,有一個[codereview.SE]網站。因爲這是一個很好的問題,所以你仍然需要更多的高層次描述它應該做的事情。我只看到一大塊代碼(有很多低級評論描述本地發生的事情),但是IDK總體設計是什麼,甚至是原始問題陳述是什麼,更不用說在編寫它時考慮什麼折衷了。例如什麼是輸入/輸出和數據結構。用英文描述其中的一些內容,以及只顯示代碼。 –

+0

我看到@Fifoernik得到了很好的評論。這些評論需要花費很多時間來寫!我建議你點擊答案左邊的複選標記以接受它。你也可以通過這種方式獲得一些積分。 –

回答

2

但我發現的唯一的錯誤是,我無法與16位輸入密碼。

用於輸入密碼的結構使用不一致的設置。您已經聲明緩衝區比您提供的緩衝區更長!

uinp db 13, 0, 14 DUP('$') ; Username register input, max 12 letters     ; 
pinp db 17, 0, 16 DUP('$') ; Password register input, max 16 letters 

ulinp db 13, 0, 14 DUP('$') ; Username login input 
plinp db 17, 0, 16 DUP('$') ; Password login input 

這兩條線的用戶名都很好,但密碼的線應該在16 DUP('$')代替使用18 DUP('$')

進一步的考慮是,DOS將需要2個字節,每個擴展字符,你想包括在密碼中。 (在密碼中並不少見),也許你可以防止這種通過寫

pinp db 17, 0, 35 DUP('$') ; Password register input, max 16 letters 
plinp db 17, 0, 35 DUP('$') ; Password login input 

有在你的程序中你寫了幾個地方:

mov dh, offset uinp ; Get uinp address 
add dh, 2  ; Add 2 to skip to the actaul string 

mov dl, offset ulinp ; Get ulinp address 
add dl, 2  ; Add 2 to skip to the actaul string 

這是一個非常危險構建!
在您當前的程序中,它的工作原理是,因爲涉及的結構放置在.DATA段的早期,這意味着偏移地址的高字節將爲零。考慮一下如果這些輸入結構放在所有其他消息之下會發生什麼。大禍臨頭!
我建議你使用由OFFSET運算符給出的完整的16位值。

CompareU:   ; Comparing the usernames 

mov di, offset uinp ; Get uinp address 
add di, 2  ; Add 2 to skip to the actaul string 

mov si, offset ulinp ; Get ulinp address 
add si, 2  ; Add 2 to skip to the actaul string 

add di, cx  ; Adding the index to the address so it can know what character to go through 
add si, cx  ; "                   " 

push cx   ; Maintaining the index count 

mov ch, [di] ; 
mov cl, [si] ; 
cmp cl, ch  ; Comparing the two usernames  
jne Error2  ; If the usernames are not the same it sum as an error 

cmp ch, '$'  ; Cheking if the string ended 
je resetReg  ; Reset all the registers for the password compare 

pop cx   ; Pop the index back out again so it could be increased 

inc cx   ; Increase the index by 1 to go over the next charachter 

jmp CompareU ; Jump back again to the head of the label to check all over again 

在前面的代碼中,我只關注字大小替換,但它還有其他問題。

看看發現字符串結束時會發生什麼。您跳到resetReg標籤,但該堆棧仍然保留的CX值不是pop -ed。這裏的解決方案是將pop cx指令放在cmpje指令之間。你可以這樣做,因爲pop指令不會修改任何標誌。跳到錯誤2標籤沒有問題,因爲程序無論如何都會結束。

cmp ch, '$'  ; Cheking if the string ended 
pop cx   ; Pop the index back out again so it could be increased 
je resetReg  ; Reset all the registers for the password compare 

以上所有的也適用於CompareP程序。


這裏有很多優化代碼的機會。 我只會顯示1,因爲最終這不是StackOverflow的內容!

mov ch, [di] ; 
mov cl, [si] ; 
cmp cl, ch  ; Comparing the two usernames 

您可以直接從內存中轉移到CL寄存器代替比較:

mov ch, [di] ; 
cmp [si], ch ; Comparing the two usernames