3 Copyright (c) 1998-2000 by Florian Klaempfl
5 SetJmp and LongJmp implementation for recovery handling of the
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 ****************************************************************************}
36 _ax
,_bx
,_cx
,_dx
,_si
,_di
,_bp
,_sp
,_ip
,flags
: word;
37 _cs
,_ds
,_es
,_ss
: word;
39 {$ifdef Delphi} { must preserve: ebx, esi, edi, ebp, esp, eip only }
40 _ebx
,_esi
,_edi
,_ebp
,_esp
,_eip
: longint;
42 eax
,ebx
,ecx
,edx
,esi
,edi
,ebp
,esp
,eip
,flags
: longint;
43 cs
,ds
,es
,fs
,gs
,ss
: word;
51 function setjmp(var rec
: jmp_buf
) : integer;
52 procedure longjmp(const rec
: jmp_buf
;return_value
: integer);
54 function setjmp(var rec
: jmp_buf
) : longint;
55 {$ifdef Delphi}stdcall;{$endif}
56 procedure longjmp(const rec
: jmp_buf
;return_value
: longint);
57 {$ifdef Delphi}stdcall;{$endif}
61 recoverpospointer
: pjmp_buf
= nil;
62 longjump_used
: boolean = false;
67 {*****************************************************************************
69 *****************************************************************************}
73 function setjmp(var rec
: jmp_buf
) : integer;
79 mov es:[di].jmp_buf._ax
,ax
80 mov es:[di].jmp_buf._bx
,bx
81 mov es:[di].jmp_buf._cx
,cx
82 mov es:[di].jmp_buf._dx
,dx
83 mov es:[di].jmp_buf._si
,si
89 mov es:[di].jmp_buf._di
,ax
95 mov es:[di].jmp_buf._es
,ax
99 mov es:[di].jmp_buf._bp
,ax
104 mov es:[di].jmp_buf._sp
,ax
106 { the return address }
108 mov es:[di].jmp_buf._ip
,ax
110 mov es:[di].jmp_buf._cs
,ax
114 pop word ptr es:[di].jmp_buf.flags
116 mov es:[di].jmp_buf._ds
,ds
117 mov es:[di].jmp_buf._ss
,ss
123 { we come from the initial call }
130 procedure longjmp(const rec
: jmp_buf
;return_value
: integer);
134 { this is the address of rec }
137 { save return value }
139 mov ds:[di].jmp_buf._ax
,ax
141 { restore compiler shit }
144 { restore some registers }
145 mov bx,ds:[di].jmp_buf._bx
146 mov cx,ds:[di].jmp_buf._cx
147 mov dx,ds:[di].jmp_buf._dx
148 mov bp,ds:[di].jmp_buf._bp
150 { create a stack frame for the return }
151 mov es,ds:[di].jmp_buf._ss
152 mov si,ds:[di].jmp_buf._sp
157 mov ax,ds:[di].jmp_buf._ds
161 mov ax,ds:[di].jmp_buf._di
165 mov ax,ds:[di].jmp_buf._si
169 mov ax,ds:[di].jmp_buf.flags
173 mov ax,ds:[di].jmp_buf._ip
177 mov ax,ds:[di].jmp_buf._cs
185 { load return value }
186 mov ax,ds:[di].jmp_buf._ax
189 mov es,ds:[di].jmp_buf._es
204 function setjmp(var rec
: jmp_buf
) : longint; assembler;
205 { [ebp+12]: [ebp+8]:@rec, [ebp+4]:eip', [ebp+0]:ebp' }
206 asm // free: eax, ecx, edx
207 { push ebp; mov ebp,esp }
209 mov [edx].jmp_buf._ebx
,ebx { ebx }
210 mov [edx].jmp_buf._esi
,esi { esi }
211 mov [edx].jmp_buf._edi
,edi { edi }
212 mov eax,[ebp] { ebp (caller stack frame) }
213 mov [edx].jmp_buf._ebp
,eax
214 lea eax,[ebp+12] { esp [12]: [8]:@rec, [4]:eip, [0]:ebp }
215 mov [edx].jmp_buf._esp
,eax
217 mov [edx].jmp_buf._eip
,eax
223 procedure longjmp(const rec
: jmp_buf
; return_value
: longint);assembler;
224 { [ebp+12]: return_value [ebp+8]:@rec, [ebp+4]:eip', [ebp+0]:ebp' }
226 { push ebp, mov ebp,esp }
229 mov ebx,[edx].jmp_buf._ebx
{ ebx }
230 mov esi,[edx].jmp_buf._esi
{ esi }
231 mov edi,[edx].jmp_buf._edi
{ edi }
232 mov ebp,[edx].jmp_buf._ebp
{ ebp }
233 mov esp,[edx].jmp_buf._esp
{ esp }
234 mov eax,[edx].jmp_buf._eip
{ eip }
244 function setjmp(var rec
: jmp_buf
) : longint;
269 { the return address }
277 { !!!!! the segment registers, not yet needed }
278 { you need them if the exception comes from
279 an interrupt or a seg_move }
290 { we come from the initial call }
299 procedure longjmp(const rec
: jmp_buf
;return_value
: longint);
302 { restore compiler shit }
304 { this is the address of rec }
307 { save return value }
311 { !!!!! load segment registers }
315 { ... and some other registers }
321 { !!!!! movw 50(%edi),%es }
324 { create a stack frame for the return }
354 { load and store flags }
361 { load return value }
365 !!!!! movw 44(%edi),%es
369 !!!!! movw 50(%edi),%ss }
388 Revision 1.1 2002/02/19 08:24:08 sasu
391 Revision 1.1 2000/07/13 06:30:02 michael
394 Revision 1.13 2000/05/11 09:36:22 pierre
395 * Delphi implementation by Kovacs Attila Zoltan
397 Revision 1.12 2000/02/24 18:41:39 peter
398 * removed warnings/notes
400 Revision 1.11 2000/02/11 23:59:35 jonas
401 + $asmmode att for people with -Rintel in their ppc386.cfg
403 Revision 1.10 2000/02/09 13:23:08 peter
406 Revision 1.9 2000/01/07 01:14:48 peter
407 * updated copyright to 2000
409 Revision 1.8 1999/08/18 11:35:59 pierre
410 * esp loading corrected