Хотя вызов указателя функции с соответствующими аргументами во встроенной сборке не должен вызывать особых проблем, я не думаю, что наивный перекодирование в x64 поможет вам, потому что очень вероятно использовать используемые соглашения о вызовахразные (по умолчанию для 32-битной и 64-битной Linux определенно разные).Посмотрите здесь для деталей.Поэтому, я думаю, если в этом случае вам удастся обойтись без встроенной сборки (см. Другой ответ), будет проще портировать.
Edit : ОК, я вижу, вы можетедолжны использовать сборку.Вот несколько указателей.
Согласно документу Агнера Фога, в Linux x64 для передачи параметров используются RDI, RSI, RDX, RCX, R8, R9 и XMM0-XMM7.Это означает, что для достижения того, что вы хотите (без учета использования чисел с плавающей запятой), ваша функция должна будет:
(1) сохранить все регистры, которые должны быть сохранены (RBX, RBP, R12-R15):Выделите место в стеке и переместите туда эти регистры.Это будет что-то вроде (синтаксис Intel):
sub rsp, 0xSomeNumber1
mov [rsp+i*8], r# ; insert appropriate i for each register r# to be moved
(2) Оцените количество аргументов, которые вам придется передавать по стеку целевой функции.Используйте это, чтобы выделить необходимое пространство в стеке (sub rsp, 0xSomeNumber2
), принимая во внимание 0xSomeNumber1
, так что в конце стека будет выровнено по 16 байт, т.е. rsp
должно быть кратно 16. Don 't изменяйте rsp
после этого до тех пор, пока ваша вызванная функция не вернется.
(3) Загрузите аргументы вашей функции в стек (при необходимости) и в регистры, используемые для передачи параметров.На мой взгляд, проще всего, если вы начнете с параметров стека и загрузите параметры регистра последними.
;loop over stack parameters - something like this
mov rax, qword ptr [AddrOfFirstStackParam + 8*NumberOfStackParam]
mov [rsp + OffsetToFirstStackParam + 8*NumberOfStackParam], rax
В зависимости от того, как вы настроили свою подпрограмму, смещение к первому параметру стека и т. Д. Может быть непредвиденным.Затем установите количество переданных регистром аргументов (пропуская те, которые вам не нужны):
mov r9, Param6
mov r8, Param5
mov rcx, Param4
mov rdx, Param3
mov rsi, Param2
mov rdi, Param1
(4) Вызовите целевую функцию, используя регистр, отличный от указанного выше:
call qword ptr [r#] ; assuming register r# contains the address of the target function
(5) Восстановите сохраненные регистры и восстановите rsp
до значения, которое оно имело при входе в вашу функцию.Если необходимо, скопируйте возвращаемое значение вызываемой функции туда, где вы хотите их иметь.Вот и все.
Примечание : вышеприведенный эскиз не учитывает значения с плавающей запятой, которые должны быть переданы в регистрах XMM, но применяются те же принципы. Отказ от ответственности : Я сделал что-то похожее на Win64, но никогда на Linux, поэтому, возможно, некоторые детали я пропускаю.Хорошо читайте, тщательно пишите код и хорошо тестируйте.