Страница 1 из 1
GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Пн мар 25, 2019 18:12:54
paskal
Мне нужно сделать ассемблерную вставку в GCC код. В ассемблерный код передается 32 битная константа, которая загружается в регистр. Процессор - кортекс-м1. В чистом ассемблере загрузка идет как то так:
Но если я то же самое делаю во встроенном ассемблере:
И вызываю вставку - myasm(0x12345678), то вместо .word 0x12345678 компилятор подставляет константу с решеткой - .word #0x12345678, что является ошибкой. Решетка в этом месте совсем не нужна.
Как мне заставить ассемблер не писать эту решетку?
Или еще какой способ введения константы в регистр подскажите.
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Вт мар 26, 2019 14:34:22
viiv
[uquote="paskal",url="/forum/viewtopic.php?p=3600537#p3600537"]Или еще какой способ введения константы в регистр подскажите.[/uquote]
Я не сильно понял, что Вы хотите, но:
Спойлер
Код: Выделить всё
#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))) для того, чтобы не выдавать лишнего (что не важно для понимания данного вопроса) в выходной ассемблерный файл.
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Вт мар 26, 2019 20:37:27
paskal
[uquote="viiv",url="/forum/viewtopic.php?p=3601127#p3601127"]Я не сильно понял, что Вы хотите, но:[/uquote]
Конкретно, мне нужно формировать точные задержки. Для этого загрузить параметр в регистр, а потом прокрутить цикл. Короче, аналог _delay_us() от WinAVR.
Ваш код работает, фигурные скобки в push/pop добавить только. Но одна проблема, регистр я не выбираю. А это скрытая бомба.
Также работает такой код:
Здесь регистр контролируется, но опять лишние команды, а это лишние такты. Поэтому хотелось бы получить чистый код.
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Ср мар 27, 2019 00:27:55
viiv
[uquote="paskal",url="/forum/viewtopic.php?p=3601405#p3601405"]Конкретно, мне нужно формировать точные задержки.[/uquote]
Насколько точные? SysTick Current Value Register не подходит для этих целей?
[uquote="paskal",url="/forum/viewtopic.php?p=3601405#p3601405"]Но одна проблема, регистр я не выбираю. А это скрытая бомба.[/uquote]
Скрытая бомба, это когда Вы выбираете регистр и его же использует компилятор, не зная что он портится в Вашем asm-коде.
[uquote="paskal",url="/forum/viewtopic.php?p=3601405#p3601405"]Также работает такой код:
Здесь регистр контролируется, но опять лишние команды, а это лишние такты. Поэтому хотелось бы получить чистый код.[/uquote]
Опять Вы загадки задаете. Раз уверены, что это можно сделать циклом (никакие кэши/pipeline и прочее не помешают Вам - я не читал Cortex-M1 Technical Reference Manual - мне не надо было), напишите без загадок, какой ассемблерный код должен быть сгенерен. В конце концов можно эту фунцию сделать на чистом asm (не inline).
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Ср мар 27, 2019 19:26:50
paskal
[uquote="viiv",url="/forum/viewtopic.php?p=3601546#p3601546"]Насколько точные? SysTick Current Value Register не подходит для этих целей?[/uquote]
Меньше микросекунды. 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
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Ср мар 27, 2019 19:48:12
viiv
[uquote="paskal",url="/forum/viewtopic.php?p=3602455#p3602455"]Меньше микросекунды. SysTick задействован на другие цели.[/uquote]
Я говорю, не про прерывния. А про счетчик. Какая на него подана частота? Если у Вас SysTick "тикает", то можно вычислить значение сетчика, при котором надо выходить из цикла ожидания.
[uquote="paskal",url="/forum/viewtopic.php?p=3602455#p3602455"]Вы неправы. Компилятор все знает. Для этого в clobber листе прописываются регистры которые задействованы в ассемблерной вставке.[/uquote]
Хм. И где же в Вашем коде указано, что r0 портится?
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Ср мар 27, 2019 21:42:22
paskal
[uquote="viiv",url="/forum/viewtopic.php?p=3602485#p3602485"]Хм. И где же в Вашем коде указано, что r0 портится?[/uquote]
Глупый вопрос задаете. Это не рабочий код. Вопрос я спрашивал про константу, а уж с клобер листом я сам разберусь.
Re: GCC Inline ассемблер, загрузить константу в регистр
Добавлено: Пт мар 29, 2019 11:21:49
Z_h_e
paskal писал(а):Конкретно, мне нужно формировать точные задержки. Для этого загрузить параметр в регистр, а потом прокрутить цикл.
Вы не можете знать точное время выполнения той или иной инструкции в STM32 с его арбитражем шин, временем доступа к памяти программ и регистром предвыборки (не помню его аббревиатуру).