Как получить функцию Аргумент из стека - Сборка - PullRequest
0 голосов
/ 01 марта 2020

Я всегда пытался поместить значение в передаваемый адресный аргумент. Это где-то в стеке.

Функция вызывается через программу на C ++, связанную с программой сборки. Он передает 8 аргументов, один из которых является float. Первый аргумент находится в RDI, а второй и последний - в r9. Последний аргумент, который я пытаюсь получить, находится где-то в стеке.

Я пробовал каждое возможное смещение, которое кажется, и ни один из них не работает. Мне удалось изменить значение другой переданной переменной, но не ту, которую я хочу! Профессор написал [rbp + 16] рядом с ним, подразумевая, что через него можно получить доступ к адресу, но это не меняет значение вообще, когда я пытаюсь изменить значение:

movss [rbp+16], xmm0

В данный момент я нажимаю RBP в начале функции, перемещаю 100 в eax, помещаю eax в xmm0 (cvtsi2ss), а затем перемещаю xmm0 в rbp + whatOffset.

Я что-то упускаю? Спасибо за понимание, спасибо!

РЕДАКТИРОВАТЬ:

Это сделано в Ubuntu. Вот код сборки:

global  Error
Error:

push rbp

mov eax, 100
cvtsi2ss xmm0, eax
movss [rbp+16], xmm0```


ret

Это вызывается с использованием этого кода C ++:

Error(array, length, PrValue, &One, &Two, &Three, &Four, &Five);

Переменная, к которой я хочу получить доступ, - это «Пять», я хочу переместить значение в адрес памяти, который перемещен. Все значения являются числами с плавающей запятой, кроме секунды, который является целым числом, массив является массивом с плавающей точкой.


extern "C" void Error(float[], unsigned int, float,
        float *, float *, float *, float *, float *);

1 Ответ

0 голосов
/ 02 марта 2020

При вводе функции первый аргумент стека имеет значение [rsp + 8].

Ваша функция делает push rbp, чтобы сохранить RBP вызывающего абонента, но вы не сделали mov rbp, rsp сделать RBP указателем кадра. Вы также не pop rbp в конце.

После установки RBP в качестве традиционного указателя кадра, первый аргумент стека будет в [rbp + 16].

movss [rbp+16], xmm0 сохраняет xmm0 где-то в фрейме стека вашего вызывающего, если ваш вызывающий был скомпилирован с -fno-omit-frame-pointer (по умолчанию в -O0). т. е. он использует любое значение, которое ваш вызывающий абонент оставил в RBP, а не собственный указатель кадра.

Если вы хотите использовать аргумент-указатель, переданный в стек, вам необходимо сначала загрузить его в регистр целых чисел и затем разыменовываете это. Вы не хотите просто переписать аргумент типа argfive = float, вы хотите *argfive = float.

...