Необходимо преобразовать старый 32-битный код GAS в текущий ассемблер GAS (pushfl/popl)

Я пытаюсь скомпилировать старый проект на моей современной машине. Я знаю, что этот старый проект использовал старую (2.x) версию GCC/GAS, поэтому мне нужно очистить его, чтобы я мог скомпилировать его с текущей версией.

Код в вопросе:

__get_flags:
    pushfl
    popl %eax
    ret

gas жалуется что pushfl это не инструкция. Из того, что я прочитал, это старая устаревшая мнемоника GNU, но наверняка должен быть какой-то эквивалент x86_64?

В дополнение к ответу о том, как преобразовать этот код в газ x86_64, было бы замечательно, если бы кто-то мог объяснить, где мнемоника нравится pushfl а также pushfq и определены и задокументированы. Я совершенно уверен, что это творения ГАЗА...

Примечание: я хочу скомпилировать это на gcc 4.6.1 и gas 2.21

2 ответа

Следующие:

static inline u16 __get_flags(void) {
    u16 flags;
    asm ("pushf\n\t"
         "pop %0" : : "+r"(flags) : "cc");
    return flags;
}

на самом деле должен быть переносимым как для 64/32-битных, так и для x64/x86. Но он получает только коды условий, а не верхние части государственного реестра. Если вам требуется все содержимое регистра флагов при работе в 64-битном (длинном) режиме, используйте PUSHFQ название инструкции, с u64 (или другое 64-битное количество) операнд.

Я не могу добавить комментарий к ответу, потому что у меня нет 50 репутации. Тем не мение:

В ответ:

"pop %0" : : "+r"(flags) : "cc");

Должен прочесть:

"pop %0" : "=r"(flags) : : "cc");

Потому что синтаксис asm( code : outputs : inputs : clobbers ) и вы хотите, чтобы флаги были регистром, который выводится из блока asm, а не используется как вход. (Я проверил это, и это сработало для меня, я также использовал 64-битные целые)

Другие вопросы по тегам