Search code examples
assemblyfile-iotasm

TASM write to stdout vs write to file behaviour difference when using print macro


This is my macro for writing to STDOUT:

; print string (immediate): ex. m_puts "hello!"
m_puts macro string
local @@start, @@data
      push ax dx
      push ds
      jmp short @@start     ; string is being stored
@@data db string,'$'        ; in the code segment
@@start:                    ; so skip over it
      mov  ax,cs
      mov  ds,ax       ; set DS to code segment
      mov  ah,9
      lea  dx, [@@data]
      int  21h
      pop  ds          ; restore registers
      pop dx ax
endm 

it writes to CS and reads from it (by using DS temporarily to point to CS), writing what it had read to STDOUT.

Usage example: m_puts 'hello world!'

Now I'm making minor changes to write to a file instead:

m_puts_to_file macro string
local @@start, @@data
      push ax cx dx
      push ds
      jmp short @@start     ; string is being stored
@@data db string            ; in the code segment
@@start:                    ; so, skip over it
      mov  ax,cs
      mov  ds,ax            ; set DS to code segment
      mov  ah,40h
      mov  bx, file_out_handle
      mov  cx, si      ; how many bytes to write
      lea  dx, [@@data]
      int  21h
      pop  ds          ; restore registers
      pop dx cx ax
endm 

Where file_out_handle is a word in memory.

However, nothing is written to a file after running:

mov si, 12
m_puts_to_file 'hello world!'

If I define 'hello world!' directly in data segment, without using the macro, writing to a file works.

What could be the case here and how could I troubleshoot it?


Solution

  • mov  ax,cs
     mov  ds,ax            ; set DS to code segment
     mov  ah,40h
     mov  bx, file_out_handle
    

    Your file_out_handle variable sits in the DS segment, but you're reading it after you have changed DS to point to CS.
    Move the mov bx, file_out_handle higher up in the code.