Чтение регистра оценивает в переменную C

Я не забываю видеть способ использовать расширенный gcc встроенный ассемблерный код, чтобы считать значение регистра и сохранить его в переменную C.

Я не могу, хотя ни за что в жизни помнят, как сформировать asm оператор.

40
задан Peter Cordes 14 August 2019 в 09:54
поделиться

6 ответов

Вот способ получить EBX:

int main()
{
    int i;
    asm("\t movl %%ebx,%0" : "=r"(i));
    return i + 1;
}

Результат:

main:
    subl    $4, %esp
    #APP
             movl %ebx,%eax
    #NO_APP
    incl    %eax
    addl    $4, %esp
    ret


Редактировать:

«= R» (I) - это выходное ограничение, сообщая компилятору о том, что первый вывод (% 0) является реестром, который должен быть помещен в переменной «I». На этом уровне оптимизации (-O5) переменная я никогда не хранятся в памяти, но удерживается в регистре EAX, который также происходит для регистрации реестра возврата.

20
ответ дан 27 November 2019 в 01:43
поделиться

Я не знаю, о НКУ , но в против, это то, как:

int data = 0;   
__asm
{
    mov ebx, 30
    mov data, ebx
}
cout<<data;

по сути, я переместил данные в EBX к вашей переменной данные .

6
ответ дан 27 November 2019 в 01:43
поделиться

Это будет перемещать указатель стека в переменную SP.

intptr_t sp;
asm ("movl %%esp, %0" : "=r" (sp) );

Просто замените «ESP» с фактическим регистрам, который вы заинтересованы в (но убедитесь, что не потерять %%) и «SP» с вашей переменной.

3
ответ дан 27 November 2019 в 01:43
поделиться

не это то, что вы ищете

Синтаксис:

 asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));
-1
ответ дан 27 November 2019 в 01:43
поделиться

Примечание редактора: Этот способ использования локальной переменной регистров-асм теперь документирован GCC как «не поддерживается» . Это все еще обычно происходит для работы на GCC, но разрывается с Clang. (Эта формулировка в документации была добавлена ​​после того, как этот ответ был опубликован, я думаю.)

Глобальная версия переменных фиксированной регистрации имеет большую стоимость производительности для 32-битного X86, которая имеет только 7 GP-целочисленных регистров (не подсчитание указатель стека). Это уменьшит, что к 6. Учтитесь только если у вас есть глобальная переменная, что весь ваш код использует в значительной степени.


Идет в другое направление, чем другие ответы, так как я не уверен, что вы хотите.

Руководство GCC § 5.40 Переменные в указанных регистрах

 Регистрация Int * Foo ASM («A5»);
 

Здесь A5 a5 - это имя реестра, которое следует использовать ...

Естественно, что имя регистра - зависит от процессора, но это не проблема, поскольку определенные регистры чаще всего полезны с явными Инструкции ассемблера (см. расширенные ASM ). Обе эти вещи, как правило, требуют, чтобы вы окружали свою программу в соответствии с типом ЦП.

Определение такой переменной регистров не оставляет регистр; Он остается доступным для других применений в местах, где контроль потока определяет значение переменной не вживую.

Руководство GCC § 3.18 Опции для конвенций генерации кода

-FIXED- REG

Обратите внимание на регистр с именем Reg как фиксированный регистр; Сгенерированный код никогда не должен ссылаться на него (за исключением, возможно, как указатель стека, указатель кадра или в какой-либо другой фиксированной роли).

Это может реплицировать ответ Ричарда более проще,

int main() {
    register int i asm("ebx");
    return i + 1;
}

, хотя это довольно бессмысленно, так как вы не имеете представления, что в EBX регистр.

Если вы объединили эти два, составление этого с помощью GCC -FIFICED-EBX ,

#include <stdio.h>
register int counter asm("ebx");
void check(int n) {
    if (!(n % 2 && n % 3 && n % 5)) counter++;
}
int main() {
    int i;
    counter = 0;
    for (i = 1; i <= 100; i++) check(i);
    printf("%d Hamming numbers between 1 and 100\n", counter);
    return 0;
}

Вы можете убедиться, что переменная C всегда использует в реестре для быстрого доступа, а также не будет нагруженными другой генерированный код. (Устранено, EBX - это Callee-Sake под обычными призывами X86, поэтому, даже если он будет нагруженными звонками на другие функции, скомпилированные без -FFIXED - * , он должен быть восстановлен тоже. )

С другой стороны, это определенно не портативно, и обычно не является преимуществом производительности, так как вы ограничиваете свободу компилятора.

31
ответ дан 27 November 2019 в 01:43
поделиться
2
ответ дан 27 November 2019 в 01:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: