x86 Assembly

Moderators: None (Apply to moderate this forum)
Number of threads: 4563
Number of posts: 16029

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Manually changing SP to prevent stack overflow Posted by vikingnoise on 4 Apr 2011 at 11:55 AM
I'm still working on my game project (a text-based dungeon crawl in the tradition of several DOS-based BBS door games), although it's coming along further. I ran into a design problem, though, and I'd like some input on my stop-gap solution.

With my current approach the stack will eventually overflow if the user dies and either starts a new game or loads from a previous save several times in a single program execution. My tentative fix is to save SP right before the main loop that calls all other branching functions, and in the event the player restarts I restore that SP value and jump back to the beginning of that main loop. Here are some code snippets, TASM syntax:

        public  SP_STATE, GAME_RESET
SP_STATE        dw      0               ;Stack Pointer state stored for game resetting
                                        ; to keep stack from overflowing.

GAME_RESET      dw      DrawMenu        ;Offset of DrawMenu for resetting game.
.
.
.

        public  TextDungeon
        extrn   ReadByte:proc, ClearScreen:proc, WriteString:proc
        extrn   SendCRLF:proc, GotoXY:proc, WriteChar:proc
        extrn   RandomMonster:proc, ResetChar:proc

TextDungeon     proc
        push    ax
        push    bx
        push    dx    
        mov     [SP_STATE],sp           ;Save SP to SP_STATE for later reset

DrawMenu:
        call    ClearScreen
        xor     dx,dx
        call    GotoXY                  ;Put cursor at 0,0 (top left)
        mov     dx,[CurrentMenu]
        call    WriteString             ;Draw menu and prompt
        lea     dx,[MenuPrompt]
        call    WriteString
.
.
.


And here is the current SP resetting procedure:

        public  RenewGame
        extrn   ClearScreen:proc, ChangeName:proc, TextDungeon:proc
        extrn   ResetChar:proc
.data
        extrn   SP_STATE:word, GAME_RESET:word

.code
RenewGame       proc
        call    ClearScreen
        call    ResetChar
        call    ChangeName
        mov     ax,[GAME_RESET]
        mov     sp,[SP_STATE]
        jmp     ax                      ;Jump to TextDungeon DrawMenu label.
        
        mov     ax,4C99h                ;Should never be reached but gives error
        int     21h                     ; and exits if it happens...

RenewGame       endp


I've read repeatedly that SP should never be modified directly unless you know exactly what you're doing, given that a system interrupt can occur in the middle of the process and bring the whole thing to an ugly, grinding halt. I've done my best to ensure that the IP change happens immediately after the SP change, which seems to me like it should minimize the chance of a problem down to the smallest it can get.

Is this a good way to do things or should I suck it up and fix my short-sighted design?
Report
Re: Manually changing SP to prevent stack overflow Posted by Bret on 5 Apr 2011 at 6:42 PM
Where you need to worry about interruptions is when you are in the middle of doing something non-atomic, like an entire sub-procedure, or certain "complicated" CPU instructions like BTR. The CLI/STI combination or LOCK prefix will usually (but not always) handle those situations.

A simple MOV SP,xx is atomic, so there is no possibility of an interruption in the middle of it. The only thing you really need to worry about is that in YOUR program, there is nothing left on the old stack that you may need to "copy" to the new stack. The amount of time between changing SP and changing CS (or even which one you do first) really doesn't matter, either.

The only thing I would add is that if you are changing the entire stack (both SS and SP at the same time), the CPU will automatically treat the combination of a MOV SS,xx followed immediately by a MOV SP,xx as atomic. You must be absolutely sure, though, that the MOV SS,xx is first and the MOV SP,xx follows IMMEDIATELY with no other instructions (not even a NOP) between them.
Report
Re: Manually changing SP to prevent stack overflow Posted by AsmGuru62 on 6 Apr 2011 at 4:44 AM
The better question would be why stack overflows? I wrote a lot of ASM code for PCs since 86 (and there was some big production programs), and there is always a way to allocate memory instead of putting it all on stack. Also, there are ways to solve problems without recursion.
Report
Re: Manually changing SP to prevent stack overflow Posted by vikingnoise on 6 Apr 2011 at 8:27 PM
The recursion is actually a design oversight on my part. I don't currently have a way of returning back out of all the nested procedure calls when the player dies and is prompted to either start a new game or load a previous save. As such the stack would keep hanging on to all the pushed data from each previous play through, and eventually (granted it could take a while) the stack would overflow. I haven't actually tested it out since I'm currently writing the save/load routines, but I know it's an eventuality.

All I'm doing is trying to dump the old stack data that's no longer needed *without* having to add all the code necessary to return all the way back up. It's a kludge, I know, but I'm trying to avoid a lot of rewriting or a complete redesign before I've even finished the first complete working draft.
Report
Re: Manually changing SP to prevent stack overflow Posted by vikingnoise on 6 Apr 2011 at 8:32 PM
Thanks for the information :) That's what I was hoping. So as long as nothing ugly and complicated is in danger of being interrupted it shouldn't be a serious problem.

Fortunately I don't need to change the stack segment in this program.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.