summaryrefslogtreecommitdiffstats
path: root/private/os2/ssrtl/i386/setjmp.asm
blob: 7e4c622d76e9cb9094df0ae0bf2cf6404fd79627 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
	page	,132
	title	setjmp - set and do long jump
;***
;setjmp.asm - set and do a long jump
;
;	Copyright (c) 1985-1988, Microsoft Corporation.  All rights reserved.
;
;Purpose:
;	defines setjmp() and longjmp() - set and do a long jump.
;	Stores machine state in a user-supplied buffer to set a jump
;	and then retores that state to perform a long jump.
;
;	format of the buffer 'env':
;		-----------
;		|   ebp   |	env+0
;		-----------
;		|   edi   |	env+4
;		-----------
;		|   esi   |	env+8
;		-----------
;		|   ebx   |	env+12
;		-----------
;		|   esp   |	env+16 (8)
;		-----------
;		| retaddr |	env+20
;		-----------
;
;	Calling longjmp(env,val); will generate a return of val to
;	the last call of setjmp(env) by restoring sp, bp, pc, and
;	other regs from buffer 'env' and doing a return. If val
;	is 0, 1 is returned; else val is returned.
;
;Revision History:
;	10-19-83  RN	initial version
;	08-08-88  JCR	386 version
;	10-24-88  JCR	Cleaned up code for 386 only
;
;*******************************************************************************

.386p
        .xlist
include ks386.inc
        .list

	OFFBP	=	0
	OFFBX	=	OFFBP + 4
	OFFDI	=	OFFBX + 4
	OFFSI	=	OFFDI + 4
	OFFSP	=	OFFSI + 4
	OFFRET	=	OFFSP + 4


_TEXT   SEGMENT DWORD USE32 PUBLIC 'CODE'
        ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING

        page , 132
        subttl  "setjmp"

;***
;int setjmp(env) - save the current stack environment
;
;Purpose:
;	Saves the current stack environment in env so that longjmp
;	can jump back here at some later time.
;
;Entry:
;	jmp_buf env - buffer to save stack environment in
;
;Exit:
;	returns 0 after setting a jump point (saving environment)
;	if returns as a result of longjmp call, returns value that
;	that longjmp passed (1 if longjmp passed 0).
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************

	public _setjmp
_setjmp	proc
				; remember where we are now, so we can
				; come back later if we have to

	mov	eax,ebp 	; save ebp
	mov	ebp,esp

	mov	edx,[ebp+4]     ; edx=pointer to env

	mov	[edx+OFFBP],eax ; save ebp
	mov	[edx+OFFBX],ebx ; save ebx
	mov	[edx+OFFDI],edi ; save edi
	mov	[edx+OFFSI],esi ; save esi
	mov	[edx+OFFSP],esp ; save esp
	mov	ecx,[ebp]
	mov	[edx+OFFRET],ecx; save ret addr

	mov	ebp,eax 	; restore ebp
	xor	eax,eax 	; return 0

	ret

_setjmp	endp


page
;***
;longjmp(env, val) - Do a long jump
;
;Purpose:
;	Restores the stack environment set by setjmp(), thereby transfering
;	control to the point at which setjmp() was called.  The specified
;	value will be returned by the setjmp() call.
;
;Entry:
;	jmp_buf env - buffer environment was previously stored in
;	int val - value setjmp() returns (0 will be returned as 1)
;
;Exit:
;	Routine does not exit - transfers control to place where
;	setjmp() was called.
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************

	public	_longjmp
_longjmp proc

	mov	ebp,esp
	mov	eax,[ebp+4+4]
				; return value; get it before we lose bp
	or	eax,eax 	; see if arg is 0; if so, return 1
	jnz	short not0	; return value != 0, so return it
	inc	eax		; set ax to 1
not0:

	mov	edx,[ebp+4]     ; ebx=pointer to env
	mov	ebx,[edx+OFFBX] ; restore ebx
	mov	edi,[edx+OFFDI] ; restore edi
	mov	esi,[edx+OFFSI] ; restore esi
	mov	esp,[edx+OFFSP] ; restore esp
	mov	ebp,esp 	; ...to get into the old stack frame
	mov	ecx,[edx+OFFRET]; ret addr
	mov	[ebp],ecx	;   restored
	mov	ebp,[edx+OFFBP]; restore ebp

; now everything is completely set up for a return to the old context

	ret

_longjmp endp

_TEXT   ends
	end