Есть ли способ заставить gcc передать параметры функции в стеке?Заставить gcc передать параметры в стеке
Я не хочу использовать регистры для передачи параметров.
Обновление: I'am с помощью рычага-GCC от CodeSourcery
Есть ли способ заставить gcc передать параметры функции в стеке?Заставить gcc передать параметры в стеке
Я не хочу использовать регистры для передачи параметров.
Обновление: I'am с помощью рычага-GCC от CodeSourcery
В соответствии с: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
Первые четыре регистра r0-r3 (а1-а4) используются для передачи значений аргументов в a подпрограмма и вернуть результат значение от функции. Они также могут использовать для хранения промежуточных значений в рамках обычной (но, вообще говоря, только между вызовами подпрограмм).
В ARM нет других соглашений о вызовах, но по умолчанию, о которых я знаю. И вот почему:
Да, вы правы. Это необычная вещь, особенно из-за причин, о которых вы упомянули. Идея состоит в том, что определенная функция была основной частью потока - в пользовательской среде (ОС). Пользовательская ОС будет вызывать аргумент потока в стеке. Чтобы уважать ABI, существует два метода обхода: поместите аргумент в r0 или объявите * thread_func (uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, void * param) *. Благодаря! – cojocar
Почему бы не поместить их в регистры? Вам нужно будет сохранять регистры по потокам, но вам все равно - представьте, если вы переключили потоки во время выполнения, а значения регистра старой функции остались на месте ... если бы ОС это сделали, это было бы очень грязно. –
Нить создается из пользовательского пространства, и нет API (syscall) для установки значения регистра для вновь созданного потока. – cojocar
Вы можете попробовать обернуть параметры в структуре; например, если ваша функция int calc_my_sum(int x, int y) {return x+y;}
вы можете изменить его следующим образом (некрасиво):
struct my_x_y {
int x, y;
my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD
};
int calc_my_sum(my_x_y x_and_y) {
// passing non-POD object by value forces to use the stack
return x_and_y.x + x_and_y.y;
}
В качестве альтернативы, вы можете просто добавить 4 параметра фиктивных израсходовать регистры, так и другие параметры будут использовать стек:
struct force_stack_usage {
int dummy0, dummy1, dummy2, dummy3;
}
int calc_my_sum(force_stack_usage, int x, int y) {
return x + y;
}
Хороший взлом! Первое решение - только C++, я забыл упомянуть, что мне нужен C-решение. Благодарю. – cojocar
Нет необходимости в причудливом конструкторе C++ для достижения того, чего вы хотите. В C-структурах просто копируются в стек. В C99 вы могли бы даже вызвать функцию с помощью 'calc_my_sum ((my_x_y) {.x = 5, .y = 7})' или обернуть такую вещь в макрос без проблем. –
Где хранить локальную переменную зависит от того, как ее использовать. Если вам нужно получить адрес локальной переменной, локальная переменная может быть сохранена только в стеке. Поэтому, когда вы передаете свою подпрограмму указателю, этот параметр будет передан через стек.
Я не уверен, что это касается вопроса или нет ... – Nanomurf
Почему параметры в регистрах плохо? –
Неплохо. Я просто хочу, чтобы параметры передавались таким образом, потому что I'am // emulating // процедура создания потока (и распределения стека). – cojocar
Какая архитектура/ABI? – ephemient