2014-02-07 4 views
0

Я работаю над программой, которая использует встроенную сборку для выполнения прыжка в длину. Насколько я понимаю, все, что мне нужно сделать, это заменить FP и ПК на сохраненные FP и ПК. Используя сборку, я могу изменить указатель кадра (% ebp), но я не могу сделать это на ПК.Изменить счетчик программ (ПК) на сохраненный адрес

int jump(int x) 
{ 
    int oldFP = getebp(); //the FP of the calling function 
    int oldPC = getebp()+4; //the PC of the calling function 

    ljump(); //uses assembly to change FP (works) but can't figure out PC 

    return x; 
} 

и мой ljump() является

ljump: # return stack frame pointer FP 
     movl savedFP, %ebp 
     ret 

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

Любой вход будет оценен.

+0

Не знаете, что такое ответ, но вы можете посмотреть, как «setjmp» и «longjmp» реализованы для вашей платформы и пытаются что-то подобное. –

+1

Вместо того, чтобы пытаться переопределить 'longjmp', просто используйте' longjmp'. Нелокальный перенос сложнее, чем кажется. Лучше позволить библиотеке времени выполнения сделать это за вас. Он понимает различные требования ABI для нелокального переноса. (На x86 вам также необходимо восстановить энергонезависимые регистры.) –

+0

спасибо за предложения. Я посмотрел исходный код для longjmp, но мне трудно его прочитать. изменение указателя рамки было достаточно простым и работает, но смена ПК оказалась намного сложнее – Kosz

ответ

1

Если вы хотите, чтобы ваш код, чтобы продолжить на некоторый предопределенный адрес вы можете сделать это, как это в ассемблерный код (псевдокод):

push myNewAddress 
ret 

или, если вы предпочитаете это по-другому, с помощью регистра:

mov eax, myNewAddress 
jmp eax 

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

+0

спасибо! к сожалению, я продолжаю получать «ошибку сегментации» при попытке прыгать, но я думаю, что вы на правильном пути – Kosz

+0

Какой из них вы попробовали? если вы используете 'ret', тогда проверьте, есть ли у вас правильный размер инструкции для push и ret. – Devolus

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