2014-10-23 3 views
2

Я пытаюсь интегрировать свой код сборки в c-программы, чтобы упростить доступ. я пытаюсь запустить следующий код (я на разрядной архитектуре x64 64)Inline Assembly Stack Behavior

void push(long address) { 
     __asm__ __volatile__("movq %0, %%rax;" 
          "push %%rax"::"r"(address)); 
} 

значение $ RSP, кажется, не меняется (ни делает особа по этому вопросу). Я пропустил что-то очевидное о том, как работают ограничения? rax правильно распределяется с адресом, но адрес никогда не попадает в стек?

+0

Я предполагаю, что компилятор генерирует пролог и эпилог для вашей функции, которая сохраняет и восстанавливает указатель стека. Вероятно, вам нужно отметить его ['naked'] (https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) –

ответ

3

Вы не можете этого сделать.

Inline asm должен документировать компилятору необходимые ему входы, выходы, которые он производит, и любое другое состояние, которое оно сжимает как часть его выполнения. Вы не можете этого сделать, но, возможно, более того, вам не удастся разрезать указатель стека, как вы это делаете, поскольку окружающий код, когда он восстанавливает контроль после блока asm, не будет иметь способ найти любую из своих данных - даже если бы он сохранил его в стеке, зная, что это будет сбито, у него не получится вернуть его.

Я не уверен, что вы пытаетесь сделать, но что бы это ни было, это не способ сделать это.

+0

Когда вы говорите, что это clobbering, это означает, что в этом случае я должен написать rax, rsp как сбитый? (предполагая, что я в порядке с моей программой segfaulting пока. Я просто хочу понять поведение. Мое понимание заключалось в том, что блок asm не был функцией, поэтому не было фрейма стека или обратного адреса.) – user1018513

+0

Как я уже сказал нет абсолютно никакого способа делать то, что вы пытаетесь сделать. Даже если вы могли бы указать, что вы собираетесь клонировать указатель стека, окружающий код не будет иметь возможности продолжить его сбой. И если у него действительно есть способ восстановить его, он отменит действие, которое вы пытаетесь выполнить. –

+1

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