title: Weird Macros (TASM)
body: <p>Consider the following macros:</p>
  
  <pre><code>pixelFast MACRO
      ; This macro draws a pixel, assuming the coordinates are already loaded in cx&amp;dx and the color is in al.
      xor bh, bh
      mov ah, 0ch
      int 10h
  ENDM
  
  drawRect MACRO x1, y1, x2, y2, color
      LOCAL @@loop, @@row_loop
      xor cx, cx
      mov dx, y1
      mov al, BYTE PTR [color]
  
      @@loop:
          mov cx, x1
          @@row_loop:
              pixelFast
  
              inc cx
              cmp cx, x2
              jna @@row_loop
  
          inc dx
          cmp dx, y2
          jna @@loop
  ENDM
  
  rendToolBar MACRO
      drawRect COLORDISP_X1, COLORDISP_Y1, COLORDISP_X2, COLORDISP_Y2, foreground_color
      mov temp_color, 36h
      drawRect COLORBTN1_X1, COLORBTN1_Y1, COLORBTN1_X2, COLORBTN1_Y2, temp_color
      mov temp_color, 2Eh
      drawRect COLORBTN2_X1, COLORBTN2_Y1, COLORBTN2_X2, COLORBTN2_Y2, temp_color
      mov temp_color, 4h
      drawRect COLORBTN3_X1, COLORBTN3_Y1, COLORBTN3_X2, COLORBTN3_Y2, temp_color
      mov temp_color, 2Bh
      drawRect COLORBTN4_X1, COLORBTN4_Y1, COLORBTN4_X2, COLORBTN4_Y2, temp_color
  ENDM
  </code></pre>
  
  <p>Somewhere in my code, I use the rendToolBar macro. It is supposed to draw a big white canvas, and then a small square and next to it some smaller squares in a certain pattern, which is irrelevant for my question.
  Notice that rendToolBar calls drawRect 5 times. I followed this code in turbo debugger (because something went awfully wrong) and noticed that in the 4th execution of the drawRect macro, the "int 10h" from pixelFast is not actually "int 10h", but rather "int 2". This causes an NMI, which messes stuff up for my program. I want to know what makes TASM expand the macro differently for that line in the 4th call for that macro, despite the fact that this line "int 10h" does not rely on any macro arguments.
  <a href="https://i.stack.imgur.com/wNxvC.png" rel="noreferrer"><img src="https://i.stack.imgur.com/wNxvC.png" alt="enter image description here"></a>
  If you look at this image, you can see the unexpected "int 2" there, which was supposed to be an "int 10". After it, you can see:</p>
  
  <pre><code>cmp [bx+si], ax
  add ch, bh
  cmp [bx+03], dx
  </code></pre>
  
  <p>According to the macro's source code, These 3 instructions were in fact supposed to be</p>
  
  <pre><code>inc cx
  cmp cx, COLORBTN3_X2
  jna @@row_loop
  </code></pre>
  
  <p>There are some other instructions which are a bit off before the interrupt, but you get the point.</p>