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
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
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.
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:
[ 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..
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..
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" :/
Thanks I will try the suggestions. Not me going nuts!
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.
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.
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
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