Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > С -> Delphi


Автор: Aster!x 13.10.2004, 12:20
Как этот код будет выглядеть на Delphi?
Естественно без использования asm вставок.

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext )
{
ContextRecord->Eip = seh.SafeEip;
ContextRecord->Esp = seh.PrevEsp;
ContextRecord->Ebp = seh.PrevEbp;
// Tell the OS to restart the faulting instruction
return ExceptionContinueExecution;
}

Автор: <Spawn> 13.10.2004, 12:50
Примерно так, тебе остается лишь выяснить что есть EXCEPTION_DISPOSITION и ExceptionContinueExecution:

Код
function _except_handler(ExceptionRecord: PExceptionRecord;
   EstablisherFrame: Pointer;
   ContextRecord: PContext;
   DispatcherContext: Pointer): EXCEPTION_DISPOSITION; cdecl;
begin
   ContextRecord.Eip := seh.SafeEip;
   ContextRecord.Esp := seh.PrevEsp;
   ContextRecord.Ebp := seh.PrevEbp;
   // Tell the OS to restart the faulting instruction
   Result := ExceptionContinueExecution;
end;

Автор: p0s0l 13.10.2004, 14:20
Код
type
 EXCEPTION_DISPOSITION = (
   ExceptionContinueExecution,
   ExceptionContinueSearch,
   ExceptionNestedException,
   ExceptionCollidedUnwind);

Автор: Aster!x 13.10.2004, 14:44
<Spawn>

Спасибо, всё получилось, а то я сначала запутался в этих поинтерах %)

Автор: Aster!x 13.10.2004, 15:13
p0s0l

А вот если использовать этот enum что-то не получается,
вот такой код генерит компилятор:
Код
CODE:004033FC 55                                            push    ebp
CODE:004033FD 8B EC                                         mov     ebp, esp
CODE:004033FF 51                                            push    ecx
CODE:00403400 A1 64 56 40 00                                mov     eax, ds:dword_405664
CODE:00403405 8B 55 10                                      mov     edx, [ebp+arg_8]
CODE:00403408 89 82 B8 00 00 00                             mov     [edx+0B8h], eax
CODE:0040340E A1 68 56 40 00                                mov     eax, ds:dword_405668
CODE:00403413 8B 55 10                                      mov     edx, [ebp+arg_8]
CODE:00403416 89 82 C4 00 00 00                             mov     [edx+0C4h], eax
CODE:0040341C A1 6C 56 40 00                                mov     eax, ds:dword_40566C
CODE:00403421 8B 55 10                                      mov     edx, [ebp+arg_8]
CODE:00403424 89 82 B4 00 00 00                             mov     [edx+0B4h], eax
CODE:0040342A C6 45 FF 00                                   mov     [ebp+var_1], 0
CODE:0040342E 8A 45 FF                                      mov     al, [ebp+var_1]
CODE:00403431 59                                            pop     ecx
CODE:00403432 5D                                            pop     ebp
CODE:00403433 C3                                            retn


Как бы ему указать что нужно DWORD возвращать?

Автор: p0s0l 13.10.2004, 15:29
Переопредели тип так:
Код
type
 EXCEPTION_DISPOSITION = (
   ExceptionContinueExecution,
   ExceptionContinueSearch,
   ExceptionNestedException,
   ExceptionCollidedUnwind,
   ExceptionDWORD = $7fffffff
   );

Добавлено @ 15:29
Или так:
Код
type
 EXCEPTION_DISPOSITION = DWORD;

const
 ExceptionContinueExecution = 0;
 ExceptionContinueSearch = 1;
 ExceptionNestedException = 2;
 ExceptionCollidedUnwind = 3;

Автор: Aster!x 13.10.2004, 15:46
Да уж, Дельфи есть Дельфи, никакой гибкости wink.gif
теперь код генерится такой:
Код
...............................................................
CODE:0040342A 33 C0                                         xor     eax, eax
CODE:0040342C 89 45 FC                                      mov     [ebp+var_4], eax
CODE:0040342F 8B 45 FC                                      mov     eax, [ebp+var_4]
CODE:00403432 59                                            pop     ecx
CODE:00403433 5D                                            pop     ebp
CODE:00403434 C3                                            retn


Эти строчки явно лишние :-)
Код
CODE:0040342C 89 45 FC                                      mov     [ebp+var_4], eax
CODE:0040342F 8B 45 FC                                      mov     eax, [ebp+var_4]

Автор: p0s0l 13.10.2004, 16:17
Может у тебя оптимизация вырублена ? Посмотри Project->Options->Compiler...
У меня нормально без этих строк компилится... И какая у тебя Delphi ?

Иначе, если уж для тебя эти лишние пары тактов критичны, то пиши процедуру полностью asm-вставкой...

Автор: Aster!x 13.10.2004, 17:10
p0s0l
Да, ты прав, оптимизация отключена, иначе компилятор не даёт два раза присвоить переменную, удаляет первое присваивание из кода:
Код
begin
lpText := szOccured;
asm
  push  OFFSET _except_handler
  push  DWORD PTR fs:[0]                 // address of next ERR structure
  mov   fs:[0], esp                      // give FS:[0] the ERR address just made

  mov   __seh.SafeEip, OFFSET _SafePlace
  mov   __seh.PrevEsp, esp
  mov   __seh.PrevEbp, ebp
end;
asm
  db 0CCh
end;
lpText := szNotOccured;
_SafePlace:
asm
  pop   DWORD PTR fs:[0]                 // restore next ERR structure to FS:[0]
  add   esp, 4                           // throw away rest of ERR structure
end;
MessageBox(0, lpText, szCaption, MB_OK or MB_ICONINFORMATION);
end.


Автор: p0s0l 13.10.2004, 17:14
Можешь в нужных местах отрубать оптимизацию, а потом включать:
{$O-} и {$O+}
Только учти, что можно включить/выключать оптимизацию целых функций/процедур, а не отдельных команд...
То бишь делай так:
Код
{$O-}
procedure ...
begin
...
end;
{$O+}


PS: а зачем тебе там первое присваивание ?

Автор: Aster!x 13.10.2004, 17:34
Цитата(p0s0l @ 13.10.2004, 17:14)
PS: а зачем тебе там первое присваивание ?

Во, и компилятор тоже видимо не понимает wink.gif
Если SEH не сработал то в MessageBox попадёт второе присваивание,
иначе первое.

Спасибо за совет, про оптимизацию теперь понял.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)