-3

hello if anyone can help me with this code that im facing a problem with i dont know where exactly is the error but its only working with the first few steps then when it coms to letting the user input a message its causing an error

; multi-segment executable file template.

data segment
    ; add your data here!
    pkey db "press any key...$" 
    prompt1 db "if u want to encrypt,type E,if u want to decrypt,type D:",0Ah,0Dh,"$"
    prompt2 db "enter the encryption key(a single digit from 1 to 9):",0Ah,0Dh,"$"
    prompt3 db "input a message of no more than 20 characters ,when done press <ENTER>:",0Ah,0Dh,"$"
    message db 20 dup(?)
    result db 20 dup(?)
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
                               
                             
    ; add your code here  
    ; prompt the user for input
    mov ah, 09h
    mov dx, offset prompt1
    int 21h        
    ; read the user's input and store it in x3100
    mov ah, 01h
    int 21h
    mov [3100H], al  
    ; prompt the user for the encryption key
   mov ah, 09h
   mov dx, offset prompt2
   int 21h  
   ; read the encryption key and store it in x3101
mov ah, 01h
int 21h
mov [3101H], al

; prompt the user for the message
mov ah, 09h
mov dx, offset prompt3
int 21h

; read the message and store it in x3102
mov ah, 0ah
mov dx, offset message
int 21h

; encrypt/decrypt the message based on the user's input
mov al, [3100H]
cmp al, 'E'
je encrypt
cmp al, 'D'
je decrypt
; encrypt the message
encrypt:
    mov si, offset message
    mov di, offset result
    mov bx, [3101H] ; encryption key
    mov cx, 20 ; number of characters to process

encrypt_loop:
    ; toggle the low-order bit of the ASCII code
    mov al, [si]
    xor al, 1
    add al, [bx] ; add the encryption key
    mov [di], al
    inc si
    inc di
    loop encrypt_loop

; output the encrypted message
mov ah, 09h
mov dx, offset result
int 21h
; decrypt the message
decrypt:
    mov si, offset message
    mov di, offset result
    mov bx, [3101H] ; encryption key
    mov cx, 20 ; number of characters to process

decrypt_loop:
    ; subtract the encryption key from the ASCII code
    mov al, [si]
    sub al,[ bx]
    ; toggle the low-order bit of the result
    xor al, 1
    mov [di], al
    inc si
    inc di
    loop decrypt_loop

; output the decrypted message
mov ah, 09h
mov dx, offset result
int 21h

                      
                      
            
    lea dx, pkey
    mov ah, 9
    int 21h        ; output string at ds:dx
    
    ; wait for any key....    
    mov ah, 1
    int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends

end start ; set entry point and stop the assembler.

its telling me to correct example of int21/9h

mov dx,offset message 
mov ah,9

i dont even know where the error is

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 1
    What error? A [mcve] should quote it exactly. Also, emu8086 has a debugger built-in, so it should be showing you what instruction triggered the error, or you can single-step. (If you're not actually using emu8086, use a debugger for whatever environment you are using. That's nearly essential to avoid wasting time while debugging.) – Peter Cordes Dec 28 '22 at 10:08

1 Answers1

0

when it coms to letting the user input a message its causing an error

You are using the DOS.BufferedInput function 0Ah for inputting the string to be encoded/decoded. The trouble you're facing comes from not having supplied the correct input structure to this DOS function.
You need to change message db 20 dup(?) into message db 21, 0, 21 dup(0). But don't take it from me just like that! Read How buffered input works for a thorough explanation.

And since you apparently want the user to input 20 characters exactly, I would have preferred the use of a simple loop over the use of the buffered input function:

  mov  ah, 09h
  mov  dx, offset prompt3
  int  21h
  mov  di, offset message
  mov  cx, 20
NextChar:
  mov  ah, 01h    ; DOS.GetCharacter
  int  21h        ; -> AL
  mov  [di], al
  inc  di
  loop NextChar

Your program exhibits more errors

; read the user's input and store it in x3100
; read the encryption key and store it in x3101
; read the message and store it in x3102

Storing at fixed addresses may be something you do in architectures like LC3, but it's definitely not what you should do on x86.
Just like your current data program segment has storage for messages and buffers, should you add storage for these additional items.

EncryptionMethod db 0
EncryptionKey    db 0
cmp al, 'E'
je encrypt
cmp al, 'D'
je decrypt
; encrypt the message
encrypt:

If the user selects anything other than 'E' or 'D', your program encrypts anyway! A decent input strategy would be to accept the lowercase commands 'e' and 'd' too, and in case of non-complying that you have the user redo from start.

; output the encrypted message
mov ah, 09h
mov dx, offset result
int 21h
; decrypt the message
decrypt:

Once you have encrypted (and displayed) a string, you immediately start decrypting it additionally. This could be intentional, but it turns selecting an encryption method ('E' or 'D') into (kind of) a silly/redundant operation.

mov bx, [3101H] ; encryption key
add al, [bx] ; add the encryption key

Although this is MASM style, it is confusing to see these square brackets when the number that you're loading is just an address. Simply write it as mov bx, 3101h. And much better if you write is as mov bx, offset EncryptionKey.
About the encryption key: you have asked the user for "a single digit from 1 to 9", but in absence of any conversion, the value that you have stored in memory is still the ASCII code for one of the characters "1" to "9". To obtain a value between 1 and 9, you need to subtract 48.

its telling me to correct example of int21/9h
i dont even know where the error is

The DOS.PrintString function 09h expects in DS:DX the far pointer to a $-terminated string. The 20-byte string that you have in your result buffer does not have that $ terminator. Write it as result db 20 dup(0), '$'.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76