Идеальная пересылка - в сборе - PullRequest
1 голос
/ 24 ноября 2010

Как можно написать функцию в ассемблере, которая просто пересылает свои аргументы в другую функцию и добавляет пару дополнительных?

До сих пор я нажимал на два дополнительных аргумента, а затем просто jmped другомуфункция.Это действительно?Предполагая, что я делаю это голой функцией, без пролога / эпилога.Я в x86.

1 Ответ

4 голосов
/ 24 ноября 2010

Если вы хотите сделать это, вам нужно вытолкнуть адрес возврата, выдвинуть два аргумента, вернуть адрес возврата обратно в стек, а затем выполнить переход.

В приведенном ниже обсуждении предполагается, что выВы делаете это в среде, которая не резервирует регистры, с которыми я возиться, и вы используете соглашение о вызовах на основе чистого стека.Если есть зарезервированные регистры (например, если вы пишете функцию ASM для вызова программой на C) или соглашение о вызовах основано на регистрах, то все должно быть несколько иначе.

Также, обязательно прочитайте заявление об отказе в конце.

С этим в стороне ...

Представьте, что у вас есть функция, которая вызывается с двумя параметрами в стеке.Кадр стека при входе в вашу функцию будет выглядеть следующим образом:

arg1
arg2
return addr

Давайте не будем спорить о порядке аргументов (т. Е. cdecl vs stdcall).

Теперь выхочу передать управление другой функции, которая ожидает эти два аргумента и еще два.При входе в эту функцию стековый фрейм должен выглядеть следующим образом:

arg1
arg2
arg3
arg4
return addr

Таким образом, ваша первая функция должна получить адрес возврата, добавить два новых параметра, нажать адрес возврата и выполнить переход:

passthrough:
    ; save the return address
    pop ax
    ; Do stuff here to load values in BX and CX
    ; now push BX and CX (other parameters)
    push bx
    push cx
    ; restore the return address
    push ax
    ; Branch to the new function.
    ; The new function's RETurn will return to the caller of this function
    jmp new_function

(Да, я сделал это с помощью 16-битных инструкций. Просто измените ax на eax и т. Д.)

Кроме того, и это очень важно: это толькоработает, если ожидается, что callee очистит стек.Если ожидается, что вызывающий объект очистит стек (обычно с помощью pop ing или путем добавления к указателю стека), этот метод завершится ошибкой, так как вызывающий будет ожидать удаления 2 параметров из стека, когда их фактически 4.В результате будет получен поврежденный кадр стека, и когда вызывающая сторона попытается выполнить инструкцию ret, она уйдет в сорняки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...