Search code examples
assemblytasm

Trouble with encrypting a string in TASM


Hi I am very new to assembly language and I am using TASM for my .asm file. I want to create a encrypt and decrypt program that takes an input.txt file and encrypts the message in that file. Only 30 characters max. The input.txt file contains this phrase, "You can read this!" Here is how it looks like so far.

.MODEL SMALL
.STACK
.386

.DATA
welcome_msg1 db "Welcome to the Encrypt/Decrypt program.",13,10,'$'
welcome_msg2 db "Here are your choices.",13,10,'$'
choice_msg1 db "E - Encrypt",13,10,'$'
choice_msg2 db "D - Decrypt",13,10,'$'
choice_msg3 db "Q - Quit",13,10,'$'

filename db 'c:\input.txt',0
file_error db "Error, file not found!",13,10,'$'
string db 30 dup(0)     ; Only 30 characters!
len equ $ - string
endchar db '$'
handle dw 0

.CODE
.STARTUP

call instructions
call openfile
call readfile
call closefile

            ; encrypt Text
lea si, string
mov cl, len
call encrypt

            ; display string
mov ah,09h
lea dx, string
int 21h

            ; terminate program once finish
mov ax,4c00h
int 21h


;*************************************;
;**************FUNCTIONS**************;
;*************************************;

            ; print instructions
instructions proc near

    mov ah, 09h
    lea dx, welcome_msg1
    int 21h

    mov ah, 09h
    lea dx, welcome_msg2
    int 21h

    mov ah, 09h
    lea dx, choice_msg1
    int 21h

    mov ah, 09h
    lea dx, choice_msg2
    int 21h

    mov ah, 09h
    lea dx, choice_msg3
    int 21h

    ret

instructions endp

            ; open file
openfile proc near

    mov ax,3d02h
    lea dx,filename
    int 21h
    jc error
    mov handle,ax 
    ret

openfile endp

            ; read from file
readfile proc near

    mov ah,3fh
    mov bx,handle
    mov cx,30
    lea dx,string
    int 21h
    jc error
    ret

readfile endp

            ; close file
closefile proc near

    mov ah,3eh
    mov bx,handle
    int 21h
    ret

closefile endp

            ; encrypt the string
encrypt proc near

    mov ch, 0

    shift_char:
        cmp si, len
        je done
        add [si],01
        inc si
    loop shift_char
    ret

encrypt endp

done proc near

    mov [si], "$"
    ret

done endp

            ; terminate program if fails
error proc near

    mov ah, 09h
    lea dx, file_error
    int 21h

    mov ax,4c00h
    int 21h

error endp

end

Here is the output:Program output

I have created a separate file which only contains specific parts like this

.MODEL SMALL
.STACK
.386

.DATA
filename db 'c:\input.txt',0
string db 30 dup(0)     ; Only 30 characters!
len equ $ - string
endchar db '$'
handle dw 0

.CODE
.STARTUP

;open file
mov ax,3d02h
lea dx,filename
int 21h
jc error
mov handle,ax

;read file
mov ah,3fh
mov bx,handle
mov cx,30
lea dx,string
int 21h
jc error

;close file
mov ah,3eh
mov bx,handle
int 21h

;encrypt string
lea si, string
mov cl, len
call encrypt

;print string
mov ah,09h
lea dx, string
int 21h

;finishes if done
done proc near
    mov [si], "$"
    ret
done endp

encrypt proc near
      mov ch, 0
          shift_char:
            cmp si, len
            je done
            add [si],01
            inc si
        loop shift_char
   ret

encrypt endp

;terminate if error
error proc near
    mov ax,4c00h
    int 21h
error endp

end

and when I run that cropped program, I get what I want. Here is the out put for that enter image description here

which is exactly what I want. The original code haves extra smiley faces at the end which is what I don't want. So I am currently confused what the problem is.


Solution

  • You issue is that you are encrypting all the 0 you have in your buffer.

    string db 30 dup(0)     ; Only 30 characters!
    

    This declaration of string is 30 bytes filled with zeros and you calculation of length is 30 no matter how many characters will be read.

    What you should do is either calculate the len based on the input from file or change the encrypt to stop when char 0 is read.

    The second approach might be like this:

    encrypt proc near
        mov ch, 0
      shift_char:
        cmp si, len
        je done
        cmp byte ptr [si], 0 ; <-- added
        je done              ; <-- finish when reaching the 0
        add [si],01
        inc si
      loop shift_char
        ret
    encrypt endp
    

    Additionally, warnings can be fixed by adding byte ptr in from of the memory access as I did with cmp byte ptr [si], 0.