Can anyone please tell me why the following does not work on Windows 98?
Windows XP works fine.
Is it me being stupid?

1 allocate some memory using GlobalAlloc (say 30k)
2 Set ESP to the end of this memory less a bit of slack but on a word boundary
3 Call a Windows function (say MessageBeep)

I get a stack fault with 98!

A problem driving me nuts!

Regards
Posted on 2006-10-02 20:44:22 by oldrec
Just a guess but perhaps Win98 handles the stack segment differently, since it is essentially a 16 bit OS at it's core your allocated memory may be out of it's range, on an NT based system which is fully 32 bit this may not be an issue.
Posted on 2006-10-02 21:59:15 by donkey
oldrec,
did you update FS:4 and FS:8 (TIB's StackBase and StackLimit)?

try the following initializiation code and check if things stop to crash:


        MOV    DWORD PTR FS:[8],0x00000000
        MOV    DWORD PTR FS:[4],0x7FFF0000 ; the last 64KB are marked as non-accessible area for the User anyway


[ Edit: Also, you may really want to align the stack to a DWORD boundary, not a WORD one, for performance reasons. ]

I wrote, some years ago, a ~comprehensive post about this "switch stack" argument, and the reasons why you can't set ESP to what you like in Win32 without updating these two FS segment entries (Thread Info Block), but I can't find it anymore on the board.

Maybe some mods..

Posted on 2006-10-03 02:58:46 by Maverick
Hm, I can't immediately find the post either, Maverick - the forum search system isn't the world's best... at least I don't know the syntax to search for exactly "FS:4" :/
Posted on 2006-10-03 06:12:03 by f0dder
Thanks I will try the suggestions. Not me going nuts!
Posted on 2006-10-03 08:38:40 by oldrec
custom stack, eh? thats a flipping nice idea!
I wonder why its never occured to me before?
My heads already overflowing with the possibilities!  :D
Please post any code you produce, i would be very interested to see that.
Posted on 2006-10-04 08:33:22 by Nice Eddie
Happy to oblige Nice Eddie ..If it means anything to anyone.
Part of a socket server.
Basically each task has its own stack and it is convenient to allocate this from
global memory.

\ ******************
\ MULTI TASKER
\ ******************

      9 1K *          CONSTANT STACKSIZE
        1K              CONSTANT HERESIZE

        THIS-TASK CONSTANT TASK0

: LINK-TASK  ( ADDR ...) TASK0 @ OVER ! TASK0 ! ;

: UNLINK-TASK ( ADDR ...) DUP TASK0
        BEGIN 2DUP @ - WHILE @ REPEAT -DROP SWAP @ SWAP ! ;

: SLEEP ( TASK ...) -1 SWAP ' AWAKE @ + +! ;

: WAKE  ( TASK ...)  1 SWAP ' AWAKE @ + +! ;

CODE (KILL-TASK) ( TASK ...)
        EAX POP EAX EDI CMP =
        IF EDI TASK0 # MOV
            ' AWAKE @ +DISP DWORD DEC
            ESP ' SAVED-SP @ +DISP  MOV
            ESI POP EBP POP
        ENDIF EAX PUSH EXTERNAL KERN. GlobalFree # CALL
              RESORCE DWORD DEC
        ;NEXT

: KILL-TASK ( TASK ...) DUP
        IF DUP DUP UNLINK-TASK (KILL-TASK) ENDIF DROP ;

: KILL-THIS-TASK ( ...) THIS-TASK TASK0 <>
        IF THIS-TASK KILL-TASK ENDIF ;

: RUN-TASK ( PFA PARAMETER TASK...) >R
        ' R0 @ R + @ CELL -
        ' KILL-THIS-TASK OVER ! SWAP            \ RETURN TO R
        ' S0 @ R + @ CELL - SWAP OVER !        \ PARAMETER TO S
        CELL - SWAP OVER !                            \ RP TO S
        CELL - SWAP OVER !                            \ IP TO S
        ' SAVED-SP @ R + !                            \ SAVE SP
        1 ' AWAKE @ R> + !  ;                          \ FLAG AS AWAKE

CODE FS! ( N ADDR...) EBX POP FS: POP ;NEXT

: CREATE-TASK  ( PFA PARAMETER...TASK)
        \ *****
        0                  8 FS!     
        2147418112  4 FS!  \ MAVERICK'S SUGGESTION
        \ *****
        [ USERSIZE STACKSIZE + RSTACKSIZE + HERESIZE + ],
        +MEM0 +RESORCE >R
        TASK0 R USERSIZE CMOVE
        R LINK-TASK
        R [ USERSIZE RSTACKSIZE + ], + DUP CELL - ' R0 @ R + !
        STACKSIZE + DUP CELL - -8 AND ( ALLIGN)
        ' S0 @ R + ! ' DP @ R + !
        R RUN-TASK R> ;

CODE PAUSE ( ...)  \ TASK SWITCHER
        EBP PUSH                        \ SAVE STATE
        ESI PUSH
        ' SAVED-SP @ +DISP ESP MOV \ INTO SAVED SP
        ' AWAKE @ +DISP DWORD INC  \ WAKEUP TASK FOR NEXT TIME

          BEGIN
            EDI MOV                \ NEXT TASK IN CHAIN
            ' AWAKE @ +DISP 0 #
            DWORD CMP <>                \ UNTIL ANOTHER TASK AWAKE
          UNTIL

        ' AWAKE @ +DISP DWORD DEC  \ FLAG NEW TASK AS RUNNING
        ESP ' SAVED-SP @ +DISP MOV \  GET STATE
        ESI POP
        EBP POP
        ;NEXT

: TASKS ( ...N) 0 TASK0
        BEGIN @ DUP TASK0 <> WHILE 1 UNDER+ REPEAT DROP ;

: KILL-TASKS ( ...)
        BEGIN TASK0 DUP @ <> WHILE TASK0 @ KILL-TASK REPEAT ;

\ USER WORDS = CREATE-TASK KILL-TASK KILL-THIS-TASK
\              SLEEP WAKE PAUSE TASKS KILL-TASKS
Posted on 2006-10-04 12:06:44 by oldrec