Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: volatile
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Jat
Вот примерчик ошибки в генерации кода для cortex

код такой

volatile int *p;
void proc(void) { *p = 1; }

здесь чтения переменной быть *p быть не должно!
только запись!
а генерится и чтение тоже

CODE

proc:
movw r3, #:lower16:p
movt r3, #:upper16:p
ldr r3, [r3, #0] !!!!!!!!!!!!!!!!! Во это совсем не надо!
mov r2, #1
str r2, [r3, #0]
bx lr
.size proc, .-proc
.comm p,4,4
.ident "GCC: (Klen's GCC package (KGP) for ARM/elf platform) 4.6.0 20101212 (experimental)"



adnega
вроде все ок.
сначала в r3 заносится адрес слова в памяти программ, где лежит адрес на p.
затем этот адрес извлекается и по нему производится запись.
Jat
Да, прошу прощения, это я попутался!
Сомнения у меня возникли вот из этого куска листинга

CODE
226:Lib/StdPeriph/src/stm32f10x_rcc.c **** void RCC_DeInit(void)
227:Lib/StdPeriph/src/stm32f10x_rcc.c **** {
26 .loc 1 227 0
27 .cfi_startproc
28 @ args = 0, pretend = 0, frame = 0
29 @ frame_needed = 0, uses_anonymous_args = 0
30 @ link register save eliminated.
228:Lib/StdPeriph/src/stm32f10x_rcc.c **** /* Set HSION bit */
229:Lib/StdPeriph/src/stm32f10x_rcc.c **** RCC->CR |= (uint32_t)0x00000001;
31 .loc 1 229 0
32 0000 104B ldr r3, .L2
33 0002 1A68 ldr r2, [r3, #0]
34 0004 1968 ldr r1, [r3, #0]
35 0006 42F00102 orr r2, r2, #1
36 000a 1A60 str r2, [r3, #0]
230:Lib/StdPeriph/src/stm32f10x_rcc.c ****
231:Lib/StdPeriph/src/stm32f10x_rcc.c **** /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
232:Lib/StdPeriph/src/stm32f10x_rcc.c **** #ifndef STM32F10X_CL
233:Lib/StdPeriph/src/stm32f10x_rcc.c **** RCC->CFGR &= (uint32_t)0xF8FF0000;
37 .loc 1 233 0
38 000c 5968 ldr r1, [r3, #4]
39 000e 0E4A ldr r2, .L2+4
40 0010 0A40 ands r2, r2, r1
41 0012 5968 ldr r1, [r3, #4]
42 0014 5A60 str r2, [r3, #4]
ReAl
Ну так а тут идёт операция чтение-модификация-запись, что запрошено, то и делается.
Цитата
var op= expression;
это то же самое, что и
Цитата
var = var op (expression);
Т.е. чтение var тут как ни крути, а есть.
Ну, если строго, то за исключением того, что адрес объекта var, в данном случае RCC->CR, вычисляется один раз (тонкость проявляется в случае, если лично сам указатель volatile, например, int * volatile p;, а как квалифицировано то, на что он указывает - не важно).
Впрочем, это вопрос не по этой теме, а где-то в разъяснениях тонкостей языков С/С++.
GetSmart
Цитата(Jat @ Dec 16 2010, 12:22) *
Да, прошу прощения, это я попутался!
Сомнения у меня возникли вот из этого куска листинга

А почему в листинге двойное чтение памяти/периферии?
Смысла я не понимаю.

Цитата(ReAl @ Dec 16 2010, 14:52) *
Т.е. чтение var тут как ни крути, а есть.

Чтение одинарное есть. А двойное для волатила это как бы перебор. Можно и на грабли нарваться.
IgorKossak
Jat, я вынес Ваш вопрос из другой темы. Не следует с частными вопросами вклиниваться в чужую тему.
Модератор
ReAl
Цитата(GetSmart @ Dec 16 2010, 12:02) *
Чтение одинарное есть. А двойное для волатила это как бы перебор. Можно и на грабли нарваться.
Ой, точно. Увлёкся вопросом "а почему чтение" и не заметил, что их по два.
Странно.
sergeeff
Цитата(Jat @ Dec 16 2010, 10:51) *
Вот примерчик ошибки в генерации кода для cortex

код такой

volatile int *p;
void proc(void) { *p = 1; }

здесь чтения переменной быть *p быть не должно!
только запись!
а генерится и чтение тоже

CODE

proc:
movw r3, #:lower16:p
movt r3, #:upper16:p
ldr r3, [r3, #0] !!!!!!!!!!!!!!!!! Во это совсем не надо!
mov r2, #1
str r2, [r3, #0]
bx lr
.size proc, .-proc
.comm p,4,4
.ident "GCC: (Klen's GCC package (KGP) for ARM/elf platform) 4.6.0 20101212 (experimental)"


Нет тут никакой ошибки. Вы же хотите чо-то записать по адресу, на который указывает p (кстати, у вас он указывает на неопределенную память!). Таким образом:
- первое чтение - получаем сам указатель (p),
- второе чтение - получаем адрес, на который указывает p,
- записываем то, что хотим по этому адресу.
ReAl
Цитата(Jat @ Dec 16 2010, 09:22) *
Сомнения у меня возникли вот из этого куска листинга
У меня компилируется нормально. Но у меня давненько уже выложенная Klen-ом линуксовая версия
Цитата
arm-kgp-eabi-gcc (Klen's GCC package (KGP) for ARM/elf platform) 4.6.0 20100525 (experimental)

CODE
6:main.c **** void RCC_DeInit()
7:main.c **** {
31 .loc 1 7 0
32 .cfi_startproc
33 @ args = 0, pretend = 0, frame = 0
34 @ frame_needed = 0, uses_anonymous_args = 0
35 @ link register save eliminated.
8:main.c **** RCC->CR |= (uint32_t)0x00000001;
36 .loc 1 8 0
37 0000 054B ldr r3, .L2
38 0002 1A68 ldr r2, [r3, #0]
39 0004 42F00102 orr r2, r2, #1
40 0008 1A60 str r2, [r3, #0]
9:main.c **** #ifndef STM32F10X_CL
10:main.c **** RCC->CFGR &= (uint32_t)0xF8FF0000;
41 .loc 1 10 0
42 000a 5968 ldr r1, [r3, #4]
43 000c 034A ldr r2, .L2+4
44 000e 01EA0202 and r2, r1, r2
45 0012 5A60 str r2, [r3, #4]
11:main.c **** #endif
12:main.c **** }
46 .loc 1 12 0
47 0014 7047 bx lr
48 .L3:
49 0016 00BF .align 2
50 .L2:
51 0018 00100240 .word 1073876992
52 001c 0000FFF8 .word -117506048
А в Вашем листинге таки читается по два раза, причём использутся первое чтение, а результат ворого отбрасывается.
Jat
Цитата(GetSmart @ Dec 16 2010, 16:02) *
А почему в листинге двойное чтение памяти/периферии?
Смысла я не понимаю.


А его и нет... laughing.gif
Это ошибка кодогенерации...

Цитата(GetSmart @ Dec 16 2010, 16:02) *
Чтение одинарное есть. А двойное для волатила это как бы перебор. Можно и на грабли нарваться.


Именно... нарвался... crying.gif

Разобрался как это обойти.
Такой эффект вызывает ключ -fpack-struct
Без него все генерится нормально. Никаких лишних чтений.

_Pasha
Цитата(Jat @ Dec 18 2010, 15:05) *
Такой эффект вызывает ключ -fpack-struct
Без него все генерится нормально. Никаких лишних чтений.

Цитата(ГЦЦ4.5.1)
Warning: the -fpack-struct switch causes GCC to generate code that is not binary compatible with code generated without that switch. Additionally, it makes the code suboptimal. Use it to conform to a non-default application binary interface.

То ли бага, то ли фича... smile3046.gif
GetSmart
Цитата(Jat @ Dec 18 2010, 16:05) *
Это ошибка кодогенерации...

Я конечно так и понял. Не понял зачем оно так "ошибается".
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.