procedure x64call у RemObjectPascalScript

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

procedure x64call у RemObjectPascalScript

Сообщение stikriz »

Здравствуйте, знатоки ASM_а или PascalScript_а!

Решил поставить - посмотреть. В модуле x64.inc Есть процедура для Винды:
procedure x64call
Так вот, из-за того, что push[rdx] - не компилится. Беда, что я не понимаю как оно работает.
Ну, вообще, странно, да? А куда проц положит, то, что по адресу rdx, чтобы потом пихнуть в стек? Или я уже давно устарел и так можно?
Вот кусок кода:

Код: Выделить всё

...
  mov rdx, aStack
  jmp @compareitems
@work:
//push [rdx]
  push rdx
...


Недалеко от начала модуля. Заремил - я. И убрал скобки. А теперь думаю, надо было дописать как по смыслу со скобками или это такая шутка автора? :-) И просто скобки убрать и все тогда.
Вся процедура, на всякий случай:

Код: Выделить всё

procedure x64call(
  Address: Pointer;
  out _RAX: IPointer;
  _RCX, _RDX, _R8, _R9: IPointer;
  var _XMM0: Double;
  _XMM1, _XMM2, _XMM3: Double;
  aStack: Pointer; aItems: IntPtr); assembler; {$IFDEF FPC}nostackframe;{$ENDIF}
asm
(* Registers:
    RCX: Address
    RDX: *_RAX
    R8: _RCX
    R9: _RDX

    fpc inserts an 20h emty space
*)
{$IFDEF FPC}
  push rbp
  mov rbp,rsp
{$ENDIF}
//  call debugbreak
  push rcx  // address
  push rdx  // _rax
  push r8   // _rcx
  push r9   // _rdx
  mov rcx, aItems
  mov rdx, aStack
  jmp @compareitems
@work:
//push [rdx]
  push rdx
  dec rcx
  sub rdx,8
@compareitems:
  or rcx, rcx
  jnz @work

  // copy registers
{$IFDEF FPC}
  movd xmm0,[_XMM0]
  movd xmm1,_XMM1
  movd xmm2,_XMM2
  movd xmm3,_XMM3
  {$ELSE}
  movsd xmm0,[_XMM0]
  movsd xmm1,_XMM1
  movsd xmm2,_XMM2
  movsd xmm3,_XMM3
  {$ENDIF}
  mov RAX, [rbp-8]
  mov RCX, [rbp-24]
  mov RDX, [rbp-32]
  mov R8, _R8
  mov R9, _R9

  // weird thing on windows, it needs 32 bytes in the CALLEE side to do whatever in
  sub RSP, 32

  call RAX

  add RSP, 32 // undo the damage done earlier

  // copy result back
  mov RDX, [rbp-16]
  mov [RDX], RAX
{$IFDEF FPC}
  movd [_XMM0],xmm0
{$ELSE}
  movsd [_XMM0],xmm0
{$ENDIF}

  pop r9
  pop r8
  pop rdx
  pop rcx
  leave
  ret
end;
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Попробуйте

Код: Выделить всё

  push qword ptr[rdx]
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

Спасибо, скомпилилось!
И смысл остался прежним.
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

В переводе с мумбу-юмбу это означает буквально -
запихать в стек 8 байт(qword ptr), адрес которых лежит в rdx.
В старших версия FPC по умолчанию подразумевался размер слова процессора.
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

А почему не размер регистра?

Добавлено спустя 1 минуту 58 секунд:
еще, а вот так можно:

move rdx, [rdx]
push rdx

Чисто по паскалевски :-)
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Слово процессора - это его регистр. :wink:
stikriz писал(а):move rdx, [rdx]
push rdx

Это будет уже две команды. :)
Ну и содержимое rdx затрётся.
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

iskander писал(а):Слово процессора - это его регистр. :wink:

Да, но RDX - 64 бита, а значит 8 байт(qword ptr)... Зачем еще указывать приведение типов?
Понятно, что адрес - 64 бита, которые лежит в RDX, слово - 64 бита, и в стек надо положить 64 бита.
Наверное, это такая бага амса фрипаскаля...
Это чисто теоритический интерес.

Добавлено спустя 1 минуту 17 секунд:
iskander писал(а):В старших версия FPC по умолчанию подразумевался размер слова процессора.

В ранних? А сейчас что по умолчанию?
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

stikriz писал(а):Да, но RDX - 64 бита, а значит 8 байт(qword ptr)... Зачем еще указывать приведение типов?

[rdx] это указатель, а сколько оттуда байт читать - 2, 4, 8?
Раэ компилятор ругается, скорее всего не определено.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

По умолчанию ничего не подразумевается, но, если один из операндов команды - регистр, и он однозначно определяет размер, то дополнительно указывать размер не требуется. Например,
mov [rdx], rax -- rax задает qword ptr
mov [rdx], eax -- eax задает dword ptr
movzx byte ptr [rdx], eax -- разные размеры источника и приемника, eax определяет только приемник, а размер источника надо указывать.

ps. Вообще этот код - ужас-ужас-ужас. В x64 указатель стека должен быть выровнен на 16 байт и его изменение в середине процедуры недопустимо.
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

Sergei I. Gorelkin писал(а):В x64 указатель стека должен быть выровнен на 16 байт и его изменение в середине процедуры недопустимо

Говорят, в Delphi ASM не ругается на push [RDX]. Видимо, там разработчики думают в точности как Вы.
Аватара пользователя
BadBoyAlex
постоялец
Сообщения: 119
Зарегистрирован: 08.06.2010 12:42:23
Откуда: Россия, Белгород
Контактная информация:

Сообщение BadBoyAlex »

Вопрос в тему: у меня Lazarus 1.0.2 х64 ругается на скажите, как вылечить...
Kitayets
постоялец
Сообщения: 174
Зарегистрирован: 05.05.2010 21:15:24

Сообщение Kitayets »

а как ругается?
Аватара пользователя
BadBoyAlex
постоялец
Сообщения: 119
Зарегистрирован: 08.06.2010 12:42:23
Откуда: Россия, Белгород
Контактная информация:

Сообщение BadBoyAlex »

Kitayets писал(а):а как ругается?

Код: Выделить всё

D:\Programs\Programming\Lazarus\external_components\Pascal Script for Delphi\Source\x64.inc(7,34) Error: Identifier not found "IntPtr"
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

Identifier not found "IntPtr"

Ну, так найдите где оно объявлено в Дельфи и объявите так же. IntPtr не может найти.
Ответить