Например TDA7294

Форум РадиоКот :: Просмотр темы - GCC Inline ассемблер, загрузить константу в регистр
Форум РадиоКот
https://radiokot.ru/forum/

GCC Inline ассемблер, загрузить константу в регистр
https://radiokot.ru/forum/viewtopic.php?f=59&t=161837
Страница 1 из 1

Автор:  paskal [ Пн мар 25, 2019 18:12:54 ]
Заголовок сообщения:  GCC Inline ассемблер, загрузить константу в регистр

Мне нужно сделать ассемблерную вставку в GCC код. В ассемблерный код передается 32 битная константа, которая загружается в регистр. Процессор - кортекс-м1. В чистом ассемблере загрузка идет как то так:
Код:
    LDR R0,[DAT]
DAT:
    .WORD 0x12345678

Но если я то же самое делаю во встроенном ассемблере:
Код:
    asm(".word %0"
    ::"i"(k)
    );

И вызываю вставку - myasm(0x12345678), то вместо .word 0x12345678 компилятор подставляет константу с решеткой - .word #0x12345678, что является ошибкой. Решетка в этом месте совсем не нужна.
Как мне заставить ассемблер не писать эту решетку?
Или еще какой способ введения константы в регистр подскажите.

Автор:  viiv [ Вт мар 26, 2019 14:34:22 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Или еще какой способ введения константы в регистр подскажите.


Я не сильно понял, что Вы хотите, но:
Спойлер
Код:
#define MY_ASM(x)                              \
asm volatile (                                 \
        "Здесь Ваш код\n\t"                    \
        "%0 - регистр с константой\n\t"        \
        "регистр выберет компилятор\n\t"       \
        "Для примера:   \n\t"                  \
        "push %0\n\t"                          \
        "pop %0\n\t"                           \
        : : "r" (x)                            \
);

void __attribute__((naked)) foo (void)
{
        MY_ASM (0x12345678);
}
генерит такой ассемблерный код:
Спойлер
Код:
        .file   "test.c"
        .text
        .align  2
        .global foo
        .type   foo, %function
foo:
        @ Naked Function: prologue and epilogue provided by programmer.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 1, uses_anonymous_args = 0
        ldr     r3, .L3
@ 17 "test.c" 1
        Здесь Ваш код
        r3 - регистр с константой
        регистр выберет компилятор
        Для примера:
        push r3
        pop r3

@ 0 "" 2
.L4:
        .align  2
.L3:
        .word   305419896
        .size   foo, .-foo
 


Это не то, что Вы хотите?

Да, пролог и эпилог я убрал (__attribute__((naked))) для того, чтобы не выдавать лишнего (что не важно для понимания данного вопроса) в выходной ассемблерный файл.

Автор:  paskal [ Вт мар 26, 2019 20:37:27 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Я не сильно понял, что Вы хотите, но:

Конкретно, мне нужно формировать точные задержки. Для этого загрузить параметр в регистр, а потом прокрутить цикл. Короче, аналог _delay_us() от WinAVR.
Ваш код работает, фигурные скобки в push/pop добавить только. Но одна проблема, регистр я не выбираю. А это скрытая бомба.
Также работает такой код:
Код:
asm("ldr r0,%0\n\t"::"m"(n));

Здесь регистр контролируется, но опять лишние команды, а это лишние такты. Поэтому хотелось бы получить чистый код.

Автор:  viiv [ Ср мар 27, 2019 00:27:55 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Конкретно, мне нужно формировать точные задержки.

Насколько точные? SysTick Current Value Register не подходит для этих целей?

Но одна проблема, регистр я не выбираю. А это скрытая бомба.

Скрытая бомба, это когда Вы выбираете регистр и его же использует компилятор, не зная что он портится в Вашем asm-коде.

Также работает такой код:
Код:
asm("ldr r0,%0\n\t"::"m"(n));

Здесь регистр контролируется, но опять лишние команды, а это лишние такты. Поэтому хотелось бы получить чистый код.


Опять Вы загадки задаете. Раз уверены, что это можно сделать циклом (никакие кэши/pipeline и прочее не помешают Вам - я не читал Cortex-M1 Technical Reference Manual - мне не надо было), напишите без загадок, какой ассемблерный код должен быть сгенерен. В конце концов можно эту фунцию сделать на чистом asm (не inline).

Автор:  paskal [ Ср мар 27, 2019 19:26:50 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Насколько точные? SysTick Current Value Register не подходит для этих целей?

Меньше микросекунды. SysTick задействован на другие цели.

Цитата:
Скрытая бомба, это когда Вы выбираете регистр и его же использует компилятор, не зная что он портится в Вашем asm-коде.

Вы неправы. Компилятор все знает. Для этого в clobber листе прописываются регистры которые задействованы в ассемблерной вставке.

Цитата:
Опять Вы загадки задаете. Раз уверены, что это можно сделать циклом (никакие кэши/pipeline и прочее не помешают Вам - я не читал Cortex-M1 Technical Reference Manual - мне не надо было), напишите без загадок, какой ассемблерный код должен быть сгенерен. В конце концов можно эту фунцию сделать на чистом asm (не inline).

На чистом asm я не смогу вставить inline код. Только в виде вызова подпрограммы, а в ARMах на вызов и возврат тратится огромное количество тактов, что не приемлемо. А еще придется перед каждым вызовом считать на лету тики,частоты. А в inline коде я это посчитаю на этапе компиляции в дефайнах. Короче идея не годится.
Код если без обвязки, выглядит как то так:
Спойлерldr r0,time
delay:
subs r0,#1
bne delay

time: .word 1000

Автор:  viiv [ Ср мар 27, 2019 19:48:12 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Меньше микросекунды. SysTick задействован на другие цели.

Я говорю, не про прерывния. А про счетчик. Какая на него подана частота? Если у Вас SysTick "тикает", то можно вычислить значение сетчика, при котором надо выходить из цикла ожидания.

Вы неправы. Компилятор все знает. Для этого в clobber листе прописываются регистры которые задействованы в ассемблерной вставке.


Цитата:
Код:
asm("ldr r0,%0\n\t"::"m"(n));

Хм. И где же в Вашем коде указано, что r0 портится?

Автор:  paskal [ Ср мар 27, 2019 21:42:22 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

Хм. И где же в Вашем коде указано, что r0 портится?

Глупый вопрос задаете. Это не рабочий код. Вопрос я спрашивал про константу, а уж с клобер листом я сам разберусь.

Автор:  Z_h_e [ Пт мар 29, 2019 11:21:49 ]
Заголовок сообщения:  Re: GCC Inline ассемблер, загрузить константу в регистр

paskal писал(а):
Конкретно, мне нужно формировать точные задержки. Для этого загрузить параметр в регистр, а потом прокрутить цикл.
Вы не можете знать точное время выполнения той или иной инструкции в STM32 с его арбитражем шин, временем доступа к памяти программ и регистром предвыборки (не помню его аббревиатуру).

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/