2010-11-24 3 views
1

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

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

+0

Как насчет обратного адреса другой функции, если вы просто переходите к ней? – 2010-11-24 19:23:33

ответ

4

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

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

Также не забудьте прочитать отказ от ответственности в конце.

С этим из пути ...

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

arg1 
arg2 
return addr 

Давайте не будем придираться аргумента упорядочения (т.е. cdecl против 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 и др.)

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

+0

x86 требует, чтобы вызывающий пользователь очистился (вы обычно видите `add% esp` сразу после вызова, хотя умные компиляторы иногда будут их выгружать). Вы можете использовать только «хвост» с тем же числом или меньшим количеством аргументов. – 2010-11-24 20:49:17

Смежные вопросы