Search code examples
assemblyreadfilemasm

Unable to read a number from file in MASM


The problem here is that i have to find fibonacci series upto a given limit in MASM.I have to read that limit from a file.Like for example 5 stored in a file named "Test.txt".

Here is my code

 .model small
 .stack
 .data
    msg0 db 'enter the filename $'
    msg1 db 'file found $'
    msg2 db 'file not found $'
    msg3 db 'file read successfull $'
    msg4 db 'file read not successfull $'
    newline db 10,13,'$'
    limit dw ?
    filename db 50 dup(?)
    filedata db 50 dup(?)
    pointerpos db 100 dup(?) 
   .code
    print macro msg
    push ax
    push dx

    mov ah,09h
    mov dx,offset msg
    int 21h

    pop dx
    pop ax
    endm

    .startup
    print msg0
    mov si,offset filename
    call readstring
    mov dx,offset filename
    mov al,00h
    mov ah,3dh
    int 21h
    jc failed
    print msg1
    mov bx,ax

    mov al,00h
    mov dx,offset pointerpos
    mov ah,42h
    int 21h 
    jc failed3

    mov dx,offset filedata
    mov cx,1
    mov ah,3fh
    int 21h
    jc failed1
    print newline
    print msg3

    mov si,offset filedata
    call readlimit
    mov ax,limit
    call display
    .exit
   failed: print newline
           print msg2
          .exit

   failed1: print newline
            print msg4
           .exit
   failed3: print newline
            .exit

  readstring proc near
    push ax
    push si

  l1:     mov ah,01h
    int 21h
    cmp al,0dh
    je skip
    mov [si],al
    inc si
    jmp l1

  skip:   mov al,0h
    mov [si],al
    pop si
    pop ax
    ret
  readstring endp

  readlimit proc near
    push ax
    push bx
    push cx
    push dx   
    mov bx,0
    mov cx,10     

  l2:     mov al,[si]
    cmp al,'0'
    jb last
    cmp al,'9'
    ja last
    sub al,30h
    mov ah,0
    push ax
    mov ax,bx
    mul cx
    mov bx,ax
    pop ax
    add bx,ax


   last:   mov limit,bx
    pop dx
    pop cx
    pop bx
    pop ax
    ret
   readlimit endp

   display proc near
    push ax
    push bx
    push cx
    push dx
    mov bx,10
    mov cx,0

  l5:     mov dx,0
    div bx
    cmp ax,0
    je l4
    inc cx
    push dx
    jmp l5

   l4:     pop dx
    add dl,30h
    mov ah,02h
    int 21h
    loop l4     ;decrement cl by 1 and check if cl==0
   pop dx
   pop cx
   pop bx
   pop ax
   ret
  display endp  
  end

here the error i m getting is that some garbage value is showing up when i print the value that i read from the file.

NB: i haven't tried to print the fibonacci series as i 'm not able read the number from the file.


Solution

  • Your code looks OK up to the point where the file has been opened.
    From here it's not clear what you are trying to do. You defined pointerpos as a buffer of 100 bytes, but I don't get why! Shouldn't it be a mere dword containing the offset in the file you just opened?

    Anyway, the next lines are not using this DOS function like it should:

    mov al,00h
    mov dx,offset pointerpos
    mov ah,42h
    int 21h 
    jc failed3
    

    The Seek function expects you to pass a file offset in CX:DX.
    If e.g. your example value 5 is placed in the first byte of the file then both CX and DX must be set to zero.

    Here's how it could be written:

    pointerpos   dd 0
    ...
    mov al, 00h
    mov dx, [pointerpos]
    mov cx, [pointerpos+2]
    ; handle already in BX
    mov ah, 42h
    int 21h 
    jc failed3
    

    I also found an error in your display routine. You need to assure that al least 1 push is done, otherwise the program will crash!
    Change your code

    l5:
     mov dx,0
     div bx
     cmp ax,0
     je l4
     inc cx
     push dx
     jmp l5
    

    to

    l5:
     mov dx,0
     div bx
     inc cx
     push dx
     cmp ax,0
     jne l5