RendoJack
RendoJack

Reputation: 366

ASM x86 Push and pop

This should compare a string given by user with each line of the text file

The line must be printed if equals


But program simply prints nothing even if correct string is provided

I'm probably doing something wrong with push and pop instructions

.model small
.stack  100h

.data
            filename          db 255 dup(0)
            text              db 255 dup(0)
            char              db ?

            text1             db 0dh, 0ah, 'Enter a string to search for: $'
            text2             db 0dh, 0ah, 'Enter a filename             : $' 

            string            db 255 dup(0)

            filehandle        dw ?

.code
            newline macro    ;NEW LINE
                             ;
            mov dl, 10       ;
            mov ah, 02h      ;
            int 21h          ;
                             ;
            mov dl, 13       ;
            mov ah, 02h      ;                     ;
            int 21h          ;
            endm             ;NEW LINE
main:

            mov ax, @data
            mov ds, ax

            mov ah, 09h
            lea dx, text1    ;'Enter a string to search for: $'
            int 21h 

            lea si, string
            mov ah, 01h      ;read character

string_input:

            int 21h

            cmp al, 0dh      ;end of string
            je zero_terminator2

            mov [si], al
            inc si

            jmp string_input

zero_terminator2:

            mov byte ptr [si], 0

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

            lea si, filename
            mov ah, 01h      ;read character

char_input:

            int 21h

            cmp al, 0dh      ;end of string
            je zero_terminator

            mov [si], al
            inc si

            jmp char_input

zero_terminator:

            mov byte ptr [si], 0

open_file:

            lea dx, filename
            mov al, 0
            mov ah, 3Dh      ;open file
            int 21h

            mov filehandle, ax

            lea si, text

read_line:

            mov ah, 3Fh      ;read file
            mov bx, filehandle
            lea dx, char
            mov cx, 1
            int 21h

            cmp ax, 0       ;EOF
            je EO_file

            mov al, char

            cmp al, 0ah     ; line feed
            je compare      ; compare line with string given by user

            mov [si], al
            inc si

            jmp read_line

EO_file:

            push dx         ;save dx for later use
            push cx         ;
            push si         ;

            xor dx, dx
            xor si, si
            xor di, di

            lea si, text
            lea di, string 

        loop_cmp_EOF:

            mov al, [si]    ;Get the next byte from text
            mov bl, [di]    ;Get the next byte from string

            cmp al, bl      ;Compare bytes
            jne end_it      ;end of program if not equal

            cmp al, 0       ;End of string. text=string
            je last_print   ;Print that line from text  

            inc si
            inc di 

            jmp loop_cmp_EOF  

        last_print:

            pop dx           
            pop cx
            pop si   

            newline

            lea dx, text    ;DX=offset(address) of text
            mov ah, 40h     ;print
            mov cx, si      ;CX = # characters. Move pointer to last char to it
            sub cx, dx      ;Subtract the offset of text (in DX) from CX
                            ;To get the actual number of chars in the buffer
            mov bx, 1
            int 21h  

       end_it:

            mov ah, 4ch
            int 21h

LF_print:    

            pop dx           
            pop cx
            pop si

            newline         ;Macro

            lea dx, text    ;DX=offset(address) of text
            mov ah, 40h     ;print
            mov cx, si      ;CX = # characters. Move pointer to last char to it
            sub cx, dx      ;Subtract the offset of text (in DX) from CX
                            ;To get the actual number of chars in the buffer                
            mov bx, 1
            int 21h 

            mov si, dx      ;Start from beginning of buffer 
                            ;(DX=beginning of text buffer)
            jmp read_line


       compare:

            push dx         ;save dx for later use
            push cx         ;
            push si         ;

            xor dx, dx
            xor si, si
            xor di, di

            lea si, text
            lea di, string 

       loop_cmp:

            mov al, [si]    ;Get the next byte from text
            mov bl, [di]    ;Get the next byte from string

            cmp al, bl      ;Compare bytes
            jne read_line   ;Do not print. Take another line from text

            cmp al, 0       ;End of string. text=string
            je LF_print     ;Print that line from text 

            inc si
            inc di 

            jmp loop_cmp

end main

Upvotes: 3

Views: 2975

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

A few problems.

  • You have to pop the registers in the reverse order.

    push dx         ;save dx for later use
    push cx         ;
    push si         ;
    ...
    pop  si           
    pop  cx
    pop  dx
    
  • In loop_cmp you can not just jump back to read_line because you have 3 words pushed on the stack that will never get popped off!

    loop_cmp:
     mov al, [si]    ;Get the next byte from text
     mov bl, [di]    ;Get the next byte from string
     cmp al, bl      ;Compare bytes
     jne read_line   ;Do not print. Take another line from text
    
  • In loop_cmp you compare with zero but you defined the end of the line to be a linefeed (=10). That's not consistent!

     cmp al, 0       ;End of string. text=string
     je LF_print     ;Print that line from text
    

Upvotes: 3

Related Questions