assembly - Weird Macros (TASM) -


consider following macros:

pixelfast macro     ; macro draws pixel, assuming coordinates loaded in cx&dx , color 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 code, use rendtoolbar macro. supposed draw big white canvas, , small square , next smaller squares in pattern, irrelevant question. notice rendtoolbar calls drawrect 5 times. followed code in turbo debugger (because went awfully wrong) , noticed in 4th execution of drawrect macro, "int 10h" pixelfast not "int 10h", rather "int 2". causes nmi, messes stuff program. want know makes tasm expand macro differently line in 4th call macro, despite fact line "int 10h" not rely on macro arguments. enter image description here if @ image, can see unexpected "int 2" there, supposed "int 10". after it, can see:

cmp [bx+si], ax add ch, bh cmp [bx+03], dx 

according macro's source code, these 3 instructions in fact supposed be

inc cx cmp cx, colorbtn3_x2 jna @@row_loop 

there other instructions bit off before interrupt, point.

consider math transform logical (segment:offset) addresses linear ones:

cs:ip = 49ae:03cc = 49eac 3cc offset of first unexpected byte.

ss:sp = 39ed:fffc = 49ecc.

visualizing 2 linear addresses, have

   |       |    | 49ecc | <-- stack pointer, going down    |       |   32 bytes below     |       |    | 49eac | <-- execution flow, going    |       | 

your stack must have clashed code segment @ point before screenshot.
try setting stack far enough code.


the maximum stack size in real mode 64kib, size of segment.
in dos safe assume memory after program not used1 and, long exists, can use stack. not wasting memory dos not multitasking.
note stack segment won't take space on binary file unless explicitly define things in it.

there 2 ways manage stack:

  1. using assembler
    see tasm manual reference, page 92.

    if using stack directive put upper bound on estimated size of stack.

    if writing exe can use model modifier farstack.
    ss:sp should set based on values linker wrote on mz header.
    let have full 64kib stack not putting stack segment dgroup.

     

  2. manually
    if know won't need full 64kib of stack, can put @ end of data segment (that com code segment)

    ;com                      ;exe mov ax, cs                mov ax, ds  ;assume small memory model mov ss, ax                mov ss, ax  ;see below xor sp, sp                xor sp, sp 

    this gives 64kib - <code+data size>.

    if need full 64kib stack can use next available segment

    ;com                      ;exe mov ax, cs                mov ax, ds      ;assume small memory model, if not           add ax, 1000h             add ax, 1000h   ;use symbol last data       mov ss, ax                mov ss, ax      ;segment xor sp, sp                xor sp, sp 

    this assumes last segment if used saves segment/offset/symbols arithmetic.


1 because dos not multitasking , programs loaded above tsr programs.
non resident part of command.com loaded top of conventional memory can overwritten.


Comments

Popular posts from this blog

jOOQ update returning clause with Oracle -

java - Warning equals/hashCode on @Data annotation lombok with inheritance -

java - BasicPathUsageException: Cannot join to attribute of basic type -