News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Program abnormally terminates

Started by Liys, June 06, 2006, 01:12:16 AM

Previous topic - Next topic

Liys

Hi all:
  I'm trying to output the "year" in data seg to display buffer, but I always received a "Termination" messagebox in debug, when "YLL:mov dl, [si]" was reached. I can't see where's wrong.




assume cs:code,ds:data,es:ave


data segment
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
data ends


code segment
start:
     call dispalY


dispalY: mov ax, data
         mov ds, ax
         mov si, 0
         mov di, 0
         mov ax, 0B800h
         mov es, ax
         mov bx, 0
         mov ax, stack
         mov ss, ax
         mov sp, 6
         mov dx, 0
      YL:
         mov al, 0A0h
         mul bx
         push bx


         mov cx, 4
     YLL:mov dl, [si]
         cmp dx, 0
         jz ok
         mov bx, ax
         mov byte ptr es:[bx + di], dl
         add di, 2
         inc si
         loop  YLL
         pop bx
         inc bx
         jmp YL
      ok:ret


code ends
end start

MichaelW

Your code has multiple problems that prevent it from assembling, how are you running it in a debugger?

liys.asm(1) : error A2006: undefined symbol : ave
liys.asm(24) : error A2006: undefined symbol : stack
liys.asm(39) : error A2108: use of register assumed to ERROR


The error on line 39 is caused by the problem with assume on line 1.

I'm not sure what you are trying to do with your stack initialization code. The loader will set up a workable stack, so there should be no need to do anything with SS and SP.

I also do not understand what you are doing with BX.

Your code is testing DL for a zero byte, but your code does not define a zero byte at the end of your data. The data is padded with zeros to the end of the paragraph, but if the data ended on a paragraph boundary there would be no zero padding, and you code would likely fail. Instead of depending on luck you should define a zero byte at the end of your data.

You cannot terminate an EXE with a near return as you can with a COM file. You should call interrupt 21h, function 4Ch instead.
eschew obfuscation

Liys

Sorry Michael! I blindly copy this code snippet from the program.There's something missing when I'm copying! Here's the updated one and not fully funcitonal one, but under debugging. And the program I mentioned early didn't repro.


assume cs:code,ds:data


data segment
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992', 0
data ends

stack segment
        db 0
stack ends

code segment
start:
     call dispalY
     
     mov ax,4c00h
     int 21h


dispalY: mov ax, data
         mov ds, ax
         mov si, 0
         mov di, 0
         mov ax, 0B800h
         mov es, ax
         mov bx, 0
         mov ax, stack
         mov ss, ax
         mov sp, 6
         mov dx, 0
      YL:
         mov al, 0A0h
         mul bx
         push bx


         mov cx, 4
     YLL:mov dl, [si]
         cmp dx, 0
         jz ok
         mov bx, ax
         mov byte ptr es:[bx + di], dl
         add di, 2
         inc si
         loop  YLL
         pop bx
         inc bx
         jmp YL
      ok:ret


code ends
end start


Liys

Actually when I dubug it, there's always a "int 3"
interrupt comes after "mov cx, 3", this blocking me from debugging
further.

MichaelW

There is no mov cx,3 and your code does not contain an interrupt 3, so it must have been added by your debugger.

A 1-byte stack is not going to work. Because you are setting SP to 6, the first two pushes will overwrite the call instruction. The stack "grows" down in memory, so further pushes will overwrite your data. For this app I would define a stack of 200h bytes. For the simplified segment directives the default stack size is 1KB. You should set SP to the last word of the stack, so for example with a 200h byte stack SP should be set to 1FEh. Here is the current layout of your segments, from the map file produced by the linker:

Start  Stop   Length Name                   Class
00000H 00048H 00049H DATA                   
00050H 00117H 000C8H STACK                 
00120H 00164H 00045H CODE


To produce a map file use a command line like this:

LINK16 /map liys.obj;

To get the linker to recognize the stack and stop returning "LINK : warning L4021: no stack segment", you should set the combine type to STACK. For more information:

http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_02.htm

I did not notice until now, but you are changing stacks in a procedure, so the return address for the call, which the call instruction is placing on the stack provided by the loader, is being lost, and the return is failing. You would normally set DS and SS at the entry to the program, outside of any procedure.
eschew obfuscation