LINUX.ORG.RU

asm inline (?)


0

1

Добрый день. Помогите разобраться, как на asm inline в GCC написать код, где номер регистра процессора задаеться из переменной Си?... И читается значение в переменную си... Хочу сделать такое:

FMSR S0, [число из переменной СИ]

Но не просто сделать это, а сделать в цикле, чтобы вместо S0 можно было подставлять S1, S2, S3... в цикле. Заранее спасибо за ответы толковые. =)

#define my_define(reg) asm volatile ("команда параметр \t%%fmsrs" #reg);

Как-то так, не знаю, как у вас на арме

ttnl ★★★★★ ()

> где номер регистра процессора задаеться из переменной Си

самомодифицирующийся код? о_О

читайте все регистры в массив, потом выбирайте нужный :)

arsi ★★★★★ ()
Ответ на: комментарий от ttnl

Точнее так:


#define my_define(reg) asm volatile ("команда параметр, \t%%fmsrs" #reg);

...

for (i = 0; i < FMSRS_NUM; i ++) {
       my_define(i);
}

Это мой вариант.

Напиши, у кого из нас телепатические способности проявились сильнее.

ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

телепатия, похоже, лучше всего у anon_66... =) Прошу прощения за неточно поставленный вопрос. Да, я хочу читать регистры сопроцессора, пргра для ARMа Сейчас строка чтения регистра S0, например, выглядит так:

__asm__ __volatile__(«fmrs %0, s0»: «=r»(freg):);

Здесь я читаю регистр S0 в переменную Си freg. А теперь я хочу сделать чтение не конкретно указанного геристра S0, а регистра Sn, где n - номер регистра, задаваемый из переменной Си...

chechestor ()
Ответ на: комментарий от chechestor

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

anon_666 ()
Ответ на: комментарий от anon_666

Битами не получится, потому что я хочу читать в переменную Си, а командами получится передавать только в регистры главного процессора. А так не хочется.

chechestor ()
Ответ на: комментарий от ttnl

Дефайнами нельзя, так как они замещаются еще на этапе компиляции, а мне надо сделать в программном цикле перебор номеров регистров. То есть, надо в строке

1) __asm__ __volatile__(«fmrs %0, s0»: «=r»(freg):);

поменять пару символов на что-то вроде:

2) __asm__ __volatile__(«fmrs %0, s%[numb]»: «=r»(freg):[numb]«I»(i));

...только, разумеется, с правильным синтаксисом, чтобы он в 2) при i = 0 понимал так же как 1). Я не смог найти как туда подставить значение переменной i... =( Вот и прошу по-мощи...

anonymous ()
Ответ на: комментарий от anonymous

есть мнение, что и в случае с vfp номер регистра является частью опкода, так что либо switch-case, либо менять опкод в рантайме ;)

arsi ★★★★★ ()
Ответ на: комментарий от arsi

switch-case?!... но это же ужасно! не на много изящнее чем вручную перебрать 32 регистра.

chechestor ()

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

thesis ★★★★★ ()
Ответ на: комментарий от thesis

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

chechestor ()
Ответ на: комментарий от chechestor

компилятор хорошо оптимизирует switch-case, используя таблицу перехода. получится косвенный переход по таблице + чтение регистра + переход.

зы: 32 регистра — фигня. в х86 программная генерация прерывания тоже идёт инструкцией с номером прерывания в опкоде. и ничего, не поленились написать switch-case для 256 прерываний ;)

arsi ★★★★★ ()
Ответ на: комментарий от anonymous

Вот так попробуй:

#define DECLARE_MY_FUNC(reg)                                            \
static void my_func_##reg(unsigned long data)                           \
{                                                                       \
        __asm__ __volatile__("movl %0, %%"#reg "\n": :"r"(data));       \
}

DECLARE_MY_FUNC(eax)
DECLARE_MY_FUNC(ebx)
.......
ttnl ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.