Search code examples
assemblydosfasm

fasm, searching a word in dos environment


The exercise is to take a word from keyboard, search the DOS environment and if that word is there, display the line with this word from DOS environment.

Here is my code:

format binary
org 100h

 start:
        mov es,[ds:02ch]
        xor si,si

;*****************************

;*****************************

        mov ah,9
        mov dx,string
        int 21h

        mov ah,10
        mov dx,word
        int 21h

        mov ah,0
        int 16h

;*****************************

;*****************************
        xor di,di
        xor bx,bx

        start_while:

          mov di,$-word
          jge equal

          mov dl,[es:si]
          mov bl,dl
          mov dl,[bx+di]
          cmp dl,[string+di]
          jne next_line

          add di,1
          jmp start_while

        next_line:
          inc si
          cmp dl,0
          jnz notexist

        equal:
          mov ah,2
          int 21h
          jmp end

        notexist:
          mov ah,9
          mov dx,d_exist
          int 21h
          jmp end

        end:
         mov ah,08h
         int 21h
         ret

;**************************************

;**************************************

string db 'THE WORD:',10,13,"$"
word db 6
      db 0
      times 22 db "$"
d_exist db 'variable does not exist',10,13,"$'            

The compiler says: mov dl,[dl+di] error. I am a begginer, how to fix the code? I have no idea.


Solution

  • Aside from the issue previously mentioned with x86 base plus index addressing, here are some additional questions and problems, some of which are leading to your undesired results:

    start:
        mov es,[ds:02ch]
        xor si,si
    
        mov ah,9               ; Writes out THE WORD:
        mov dx,string
        int 21h
    
        mov ah,10              ; Accepts user input into "word"
        mov dx,word
        int 21h                ; reads buffered input for "word"
    
        ; reads keyboard key
        ; -->**** WHY? Input was just read above with INT 21 / AH = 10
        ;   
        mov ah,0
        int 16h                ;   AH = scan code, AX = ASCII char
    
        xor di,di
        xor bx,bx
    
    start_while:
        mov di,$-word        ; Moves address of current location
                             ;   minus address of "word" to di -->***WHY?
    
        ; The last operation to affect flags was xor bx,bx, which results
        ;   in a zero. So this jump will ALWAYS be taken
        jge equal          
    
        ... All the code here up until the 'equal' label is skipped
    
    equal:
        mov ah,2          ; write the character in dl to stdout
                          ;   -->*** BUT the contents of dl are unknown
        int 21h
        jmp end           ; exit the program
    

    The above comments should explain why you aren't seeing any output or why your terminal switches off (perhaps some control character in dl).

    The expression $-word in mov di,$-word is not the length of the word at word. The $ symbol represents the address of the current location in which the $ appears, so in the above, it's actually the address of that mov instruction. Therefore, you're getting some odd negative number in di than you wanted. If you want the length of the word, you should set a new data item after word, a common pattern is to make it an item after the definition of word:

    word db 6                   ; This defines one byte, value = 6
         db 0
         times 22 db "$"
    word_len db $-word          ; Word length is current address - addr of "word"
                                ; I'm assuming all 24 bytes above are for "word"