Consider the following macros:
pixelFast MACRO
; This macro draws a pixel, assuming the coordinates are already loaded in cx&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
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.
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:
cmp [bx+si], ax
add ch, bh
cmp [bx+03], dx
According to the macro's source code, These 3 instructions were in fact supposed to be
inc cx
cmp cx, COLORBTN3_X2
jna @@row_loop
There are some other instructions which are a bit off before the interrupt, but you get the point.