OberonCore https://forum.oberoncore.ru/ |
|
SEH исключения в BB https://forum.oberoncore.ru/viewtopic.php?f=2&t=294 |
Страница 1 из 1 |
Автор: | MT [ Четверг, 17 Август, 2006 19:49 ] |
Заголовок сообщения: | SEH исключения в BB |
Пример реализации SEH исключений в стиле TRY .. EXCEPT .. END (из DELPHI) – модуль EXCEP и пример использования - модуль AAAAA. Допускает вложенные исключения. Наверняка много недостатков, если кто-то улучшит код, не молчите. MODULE bapiExcep; (* 07.07.2006 *) (* exception SEH *) IMPORT S:= SYSTEM; TYPE PTR_FRM = POINTER TO EXCPFRM; EXCPFRM = RECORD [untagged] next : PTR_FRM; hand : EXCPPRC; (* расширено *) code : INTEGER; (* код исключения *) ebp_ : INTEGER; eip_ : INTEGER; (* адрес бз.места *) END; PTR_REC = POINTER TO EXCPREC; EXCPREC = RECORD [untagged] code : INTEGER; (* код исключения *) flgs : SET; (* 0 ,1, 2-раскр. *) nrec : PTR_REC; addr : INTEGER; (* adr исключения *) ninf : INTEGER; info : ARRAY 015 OF INTEGER; END; PTR_CON = POINTER TO CONTEXT; CONTEXT = RECORD [untagged] flags : SET; debug : ARRAY 06 OF INTEGER; float : ARRAY 28 OF INTEGER; gs,fs : INTEGER; es,ds : INTEGER; di,si : INTEGER; bx,dx : INTEGER; cx,ax : INTEGER; bp,ip : INTEGER; cs,pf : INTEGER; sp,ss : INTEGER; END; EXCPPRC = PROCEDURE(prec : PTR_REC; pfrm : PTR_FRM; cont : PTR_CON; disp : INTEGER):INTEGER; (* code procedures for exception handling *) PROCEDURE [code] nullNOP 090H; (* пустой *) PROCEDURE [code] PushEAX 050H; PROCEDURE [code] Pop_EAX 058H; PROCEDURE [code] PushEDX 052H; PROCEDURE [code] Pop_EDX 05AH; PROCEDURE [code] PushEBX 053H; PROCEDURE [code] Pop_EBX 05BH; PROCEDURE [code] PushESP 054H; PROCEDURE [code] Pop_ESP 05CH; PROCEDURE [code] PushEBP 055H; PROCEDURE [code] Pop_EBP 05DH; PROCEDURE [code] PushESI 056H; PROCEDURE [code] Pop_ESI 05EH; PROCEDURE [code] PushEDI 057H; PROCEDURE [code] Pop_EDI 05FH; PROCEDURE [code] Get_ESP( ) : INTEGER 089H, 0E0H; (* mov eax,esp *) PROCEDURE [code] Put_ESP(_esp : INTEGER) 089H, 0C4H; (* mov esp,eax *) PROCEDURE [code] Get_EBP( ) : INTEGER 089H, 0E8H; (* mov eax,ebp *) PROCEDURE [code] Put_EBP(_esp : INTEGER) 089H, 0C5H; (* mov ebp,eax *) PROCEDURE [code] GetrADDR( ) : INTEGER (* адрес возврата из процедуры *) 08BH, 045H, 004H; (* mov eax,[ebp+4] *) PROCEDURE [code] SetrADDR(offs : INTEGER) (* смена адреса возврата *) 089H, 045H, 004H; (* mov [ebp+4],eax *) PROCEDURE [code] GotoADDR(offs : INTEGER) (* переход выполнения по адресау *) 0FFH, 0E0H; (* jmp eax *) PROCEDURE [code] pushEXTD (* установка exception handling *) 033H, 0C0H, (* xor eax,eax *) 052H, (* push edx *) 055H, (* push ebp *) 050H; (* push eax (=0) *) PROCEDURE [code] instEXCP(offs : EXCPPRC) (* установка exception handling *) 050H, (* push eax (=offs) *) 033H, 0C0H, (* xor eax,eax *) 064H, 0FFH, 030H, (* push fs:[eax] *) 064H, 089H, 020H; (* mov fs:[eax],esp *) PROCEDURE [code] ret 0C3H; (* ret *) PROCEDURE [code] get_PFRM() : PTR_FRM 033H, 0C0H, (* xor eax,eax *) 064H, 08BH, 000H; (* mov eax,fs:[eax] *) (* pass procedures for exception handling *) PROCEDURE [noframe] Get_EIP() : INTEGER; (* на вершине стека адрес возврата = *) (* следующей инструкции на выполнение *) BEGIN Pop_EAX; PushEAX; ret; END Get_EIP; PROCEDURE TRYPROC(prec : PTR_REC; pfrm : PTR_FRM; cont : PTR_CON; disp : INTEGER) : INTEGER; (* процедура обработки исключения *) BEGIN (* exception нельзя обработать *) IF prec.flgs = {1} THEN RETURN 1 END; (* exception раскрутка стека *) IF prec.flgs = {2} THEN RETURN 2 END; (* исключeние в исключении *) IF prec.code = 111 THEN RETURN 1 END; (* exception можно обработать *) pfrm.code := prec.code; (* код исключ. *) cont.ip := pfrm.eip_; (* safe place *) cont.bp := pfrm.ebp_; (* safe stace *) cont.sp := S.VAL(INTEGER, pfrm ); (* cont.sp := pfrm.esp_; (* safe stace *) *) (* ------------ способ 2 -------------- Put_ESP(S.VAL(INTEGER,pfrm)); Put_EBP( pfrm._ebp); GotoADDR(pfrm.goto); -------------------------------------- *) RETURN 0; END TRYPROC; (* excport *) PROCEDURE [code] get_CODE*() : INTEGER (* чтение кода исключения *) 033H, 0C0H, (* xor eax,eax *) 064H, 08BH, 000H, (* mov eax,fs:[eax] *) 08BH, 040H, 008H; (* mov eax,[eax+8] *) PROCEDURE [ code ] del_EXCP*() (* удаление блока try .. except .. end *) 033H, 0C0H, (* xor eax,eax *) 05AH, (* pop edx *) 064H, 089H, 010H, (* mov fs:[eax],edx *) 058H, (* pop eax *) 058H, (* pop eax *) 058H, (* pop eax *) 058H; (* pop eax *) PROCEDURE [noframe] set_EXCP*(); (* установка блока try .. except .. end *) BEGIN Pop_EDX; pushEXTD; instEXCP( TRYPROC ); PushEDX; ret; END set_EXCP; END bapiExcep. MODULE aaaaAaaaa; (* обертка в TRY-EXCEPT *) IMPORT bapiExcep, Out; PROCEDURE xxxx(par1,par2 : INTEGER); VAR arr : ARRAY 2 OF INTEGER; BEGIN bapiExcep.set_EXCP(); IF bapiExcep.get_CODE() = 0 THEN Out.String('шаг3='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; par1 := arr[par2+5]; Out.String('шаг4='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; ELSE Out.String('excp='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; END; bapiExcep.del_EXCP(); par1 := par1 DIV par2; par1 := arr[par2]; END xxxx; PROCEDURE TRYTEST*(); BEGIN bapiExcep.set_EXCP(); IF bapiExcep.get_CODE() = 0 THEN Out.String('шаг1='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; xxxx(1,0); Out.String('шаг2='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; ELSE Out.String('excp='); Out.Int(bapiExcep.get_CODE(),10); Out.Ln; END; bapiExcep.del_EXCP(); Out.Ln; END TRYTEST; END aaaaAaaaa. aaaaAaaaa.TRYTEST |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |