GCC вставляет указатель в регистры eax и ebx

Мне нужно вставить указатель в EAX и один в регистр EBX. Я сначала решил это с:

register int eax asm("eax");
register int ebx asm("ebx");
int main()
{
eax = ptr1;
ebx = ptr2;
}

Который работал как шарм. Однако, когда я добавил это в свой другой код, я получил некоторые странные ошибки о том, что gcc не может найти регистр для разлива в классе AREG, в совершенно не связанной части кода. Я гуглил, и оказалось, что это действительно ошибка в gcc -.-. Итак, мне нужен другой способ, чтобы вставить два указателя в регистры eax и ebx. У кого-нибудь есть идеи? Спасибо!

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

Мне нужно изменить eax и ebx для некоторого ассемблерного кода, который я пытаюсь запустить в своей программе. Мне нужно выполнить этот ассемблерный код и дать указатель на параметр через регистры eax и ebx. Я выполняю ассемблерный код, нажимая указатель на него в ebx и вызывая ebx. Когда я не вызываю регистр, глобально, но локально, код ассемблера падает. Если я вызываю это глобально, я получаю эту странную ошибку в конце случайной функции. Когда я удаляю эти функции, он выдает ту же ошибку в другую случайную функцию. Пока у меня не закончились функции, тогда это работает, но потом я скучаю по остальной части кода: P

6

Решение

Если у вас есть (встроенный) код сборки, который требует определенных параметров в EAX/EBXспособ сделать это в gcc — использовать следующее:

__asm__("transmogrify %0, %1\n" : "+a"(val_for_eax), "+b"(val_for_ebx));

Это использует то, что gcc называет встроенной сборкой ограничения которые сообщают компилятору, что код сборки — какой бы он ни был — ожидает val_for_eax/val_for_ebx в EAX/EBX (это a/b часть), а также что он будет возвращать потенциально измененные версии этих переменных (это +) в этих регистрах также.

Помимо этого, фактический код в пределах asm() оператор не имеет значения для компилятора — ему нужно / нужно только знать, где параметры %0 а также %1 жить. Приведенный выше пример из-за transmogrify инструкция, не существующая в текущем наборе команд x86, завершается ошибкой при выполнении ассемблера; просто замените это чем-то действительным.

Объяснение того, почему gcc ведет себя так и что именно вы можете сказать, приведено в руководстве GCC по адресу:

Вы можете указать конкретный регистр для переменной, но из-за того, как работает gcc / как встроенная сборка реализована в gcc, делая это не значит (!) регистр с тех пор зарезервированный (вне области видимости) для gcc для использования в своих собственных целях. Это может быть достигнуто только с помощью ограничений, для asm() block — ограничения сообщают gcc, что записывать в эти регистры до размещение фактического кода сборки и что читать с них впоследствии.

5

Другие решения

Так как eax регистр необходим везде в действующей программе вашей архитектуры, ваша стратегия не может работать с глобальными переменными, которые связаны с конкретными регистрами. Не делайте этого, резервировать регистр по всему миру не очень хорошая идея.

Поместите переменные, которые связаны с регистрами в конкретной функции, как можно ближе к их использованию.

4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector