Delphi XE2 + ASM (x64-компиляция) из asm-куска вызвать exception

lordvampir

Premium
Регистрация
9 Дек 2010
Сообщения
45
Реакции
15
Credits
326
собственно такая задача необходимо на б-асме (x64) написать функцию которая проверяла бы некоторые значения, и, если эти значения не соответствуют требованиям, вызывала бы exception.

вот примерный код:
Код:
procedure CreateIndexOutOfBoundsException(const Index, Bounds: Byte); //процедура генерации exception
begin
  raise EBinaryException.Create(Format(LoadResString(@SBinaryIndexOutOfBounds), [Index, Bounds]));
end;

function MyFunc(const Value: Int64; Index: Byte): Byte;
asm
  CMP       DL, 50             //сравниваем Index с максимумом дозволенного
  JBE       @BeginGet        //если не выходит за рамки дозволенного, переходим к выполнению необходимых действий 
  MOV       CL, DL            //передаём процедуре CreateIndexOutOfBoundsException полученный индекс
  MOV       DL, 50            //передаём процедуре CreateIndexOutOfBoundsException предел допустимого
  CALL      CreateIndexOutOfBoundsException   //вызываем процедуру генерации exception
@BeginGet:
   // делаем необходимое
end;
на x86 этот код работает отлично (единственное отличие в используемых регистрах), на x64 падает с ошибкой: Access violation at address 0000000077790895 in module 'ntdll.dll'. Read of address FFFFFFFFFFFFFFFF.

ни хэлпе XE2, ни в нете ничего толкового найти не могу, очень прошу помощи... заранее спасибо...
 

JCDenton

Местный
Регистрация
15 Фев 2013
Сообщения
15
Реакции
3
Credits
28
Дак ведь в x64 должен быть обязательный фрейм, а все вызовы должны быть выровнены по стеку. Запиши MyFunc на Паскале и посмотри листинг дизассемблера в x64 - удивишься. Короче, изучай соглашение вызова x64.

Кстати, исключения на x64 - табличные, в exe-нике лежит мета-информация по всем блокам try, а для динамически создаваемого кода эту инфу нужно регистрировать вручную.