Чтение регистра RSP из Microsoft C ++ - PullRequest
6 голосов
/ 18 июля 2011

Поскольку встроенный ассемблер недоступен в Microsoft C ++ при компиляции для архитектуры x64, я не могу понять, как получить доступ к регистру RSP (указатель стека).Я знаю, что могу прочитать его с помощью RtlCaptureContext, но это также будет выполнять много нежелательных операций.Также это будет в несколько тысяч раз медленнее (для моих целей не приемлемо).Если я напишу отдельную функцию ASM, RSP, очевидно, изменится, так что это тоже не альтернатива.

Так как же прочитать содержимое регистра x64 RSP с помощью Microsoft C ++?

Ответы [ 5 ]

5 голосов
/ 18 июля 2011

Ладно, у меня с этим была скрипка, и она заработала; вы не можете заставить компилятор встроить его, но, к счастью, вам это не нужно, просто поместите его в файл .s или .asm и скомпилируйте с помощью `ml64 / c yourasm.s" и передайте файл .obj линкер.

.CODE

     getRSP PROC
     mov rax, rsp
     add rax, 8
     ret
     getRSP ENDP
     END

тогда на стороне C все, что вам нужно, это extern "C" __int64 getRSP();

5 голосов
/ 18 июля 2011

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

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

2 голосов
/ 18 июля 2011

Знаете ли вы о _AddressOfReturnAddress присущем?Это не регистр RSP, но он сам по себе несколько нестабилен.

1 голос
/ 18 июля 2011

Есть только два способа сделать это:

1) создайте файл ASM с инструкцией, чтобы переместить rsp в rax и вернуться, а затем посмотреть, сможете ли вы заставить компилятор встроить его.

2) если вышеупомянутое не допускается, объявите переменную энергозависимого указателя и используйте встроенную переменную __nop(), чтобы оставить себе достаточно места для исправления необходимой инструкции в пост-сборке (или, черт возьми, просто присвойте значение вашему volatile указатель несколько раз и замените это)

0 голосов
/ 18 июля 2011

__getCFS, __getPSP, возможно __getReg?

Вы также можете связать объект MinGW-w64файл, который делает ассемблер встроенным.

...