Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Вопросы начинающих

Вопросы начинающих Прежде чем задать вопрос, стоит воспользоваться поиском

Ответ
 
Опции темы Опции просмотра
Старый 05.01.2020, 13:31   #1
den4mc
Junior Member
 
Регистрация: 18.12.2014
Сообщений: 11
Вес репутации: 90/0
den4mc will become famous soon enough
Unhappy C vs Assembler, inline Assembler в C

Доброго времени суток всем присутствующим!

Предисловие:
Раньше я, как и многие, имхо, писал на assembler`е под 8-и битные pic-контроллеры.
С появлением более мощных pic24 и далее пришлось перейти на С.
Понятно, что приходится делать ассемблерные вставки, но каково было моё удивление, когда в дезассемблерном листинге я увидел не то, что я написал в inline ассемблерной вставке.
В данной теме я не хочу разжигать холивар или разводить филосовские рассуждения, прошу только рассматривать практические решения.

Мой первый вопрос:

На ПК в С или С++ возможна такая конструкция:
Var_a = Var_b = Var_c = const;
На ассемблере её реализовывал так:
movlw const
movwf Reg_Var_a
movwf Reg_Var_b
movwf Reg_Var_c

в MPlab C30 такая конструкция не допускается, приходится делать так:
Var_a = const;
Var_b = const;
Var_c = const;

Можно-ли заставить С30 запихать значение в несколько регистров без промежуточной загрузки?

Вопрос второй:
MPLAB IDE v8.43
MPLAB C30 v3.12
элементарная операция присвоения компилится в два MOV`а

пробовал описать локальную регистровую переменную, это ситуацию не изменило.
С код:
register unsigned char tmpU1RXREG asm ("w8");
tmpU1RXREG = U1RXREG;
RX_MB1.Res_Addr = tmpU1RXREG;

Ассемблерный листинг:
015E8 801130 mov.w 0x0226,0x0000
015EA 780400 mov.w 0x0000,0x0010
015EC 784008 mov.b 0x0010,0x0000
015EE B7ED4C mov.b 0x0000,0x0d4c

хотя ожидал следующего:
mov.b 0x0226,0x0008
mov.b 0x0008,0x0d4c

Смысл моих потуг следующий: я в прерывании получаю байт по UART, помещаю его в в переменную unsigned char Res_Addr, сравниваю со своим адресом, считаю по нему-же контрольную сумму.
при любом раскладе компилятор делает mov var1->w0 затем mov w0->var2 даже если var1 находится в w2.

пробовал делать так:
__asm__ ("mov.w %2, %0 \nmov.b %0, %1"
:"=r" (tmpU1RXREG),"=g" (RX_MB1.Res_Addr)
: "g" (U1RXREG) );
получается
Ассемблерный листинг:
015E8 801130 mov.w 0x0226,0x0000
015EA 780400 mov.w 0x0000,0x0010
015EC 784008 mov.b 0x0010,0x0000
015EE B7ED4C mov.b 0x0000,0x0d4c

Добрые люди подскажите, что я делаю не так или чего я не знаю.

Последний раз редактировалось den4mc; 05.01.2020 в 13:37.
den4mc вне форума   Ответить с цитированием
Старый 05.01.2020, 14:05   #2
den4mc
Junior Member
 
Регистрация: 18.12.2014
Сообщений: 11
Вес репутации: 90/0
den4mc will become famous soon enough
По умолчанию Re: C vs Assembler, inline Assembler в C

даже так:

unsigned char Res_Addr11;

register unsigned char tmpU1RXREG asm ("w0");


__asm__ ("mov %2, %0 \nmov %0, %1"
:"=r" (tmpU1RXREG),"=g" (Res_Addr11)
: "g" (U1RXREG) );
получается:
015EC 801130 mov.w 0x0226,0x0000
015EE 780000 mov.w 0x0000,0x0000
015F0 886B00 mov.w 0x0000,0x0d60


что-за бред!?
den4mc вне форума   Ответить с цитированием
Старый 05.01.2020, 15:03   #3
Марк
Senior Member
 
Аватар для Марк
 
Регистрация: 18.08.2007
Адрес: Московская область
Возраст: 60
Сообщений: 2,740
Вес репутации: 3796/110
Марк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond repute
По умолчанию Re: C vs Assembler, inline Assembler в C

Все дело в байтовой пересылке непосредственно в ОЗУ.
В системе команд PIC24/30/33 байтовые пересылки из регистра в ОЗУ можно сделать только через W0. Кстати, синтаксис АСМа в этом случае будет такой:
Код:
mov.b  WREG, bufRAM
Обратите внимание, что вместо W0 нужно писать WREG.
Пересылка 16-разрядных слов возможна из любого РОНа, но только в первые 8KB ОЗУ (near сегмент). Байтные пересылки тоже ограничены этим адресным пространством.
ЗЫ. В догон. Эта особенность системы команд накладывается на применяемый уровень оптимизации. У Вас оптимизация включена?

Последний раз редактировалось Марк; 05.01.2020 в 15:09.
Марк на форуме   Ответить с цитированием
Старый 05.01.2020, 15:22   #4
Марк
Senior Member
 
Аватар для Марк
 
Регистрация: 18.08.2007
Адрес: Московская область
Возраст: 60
Сообщений: 2,740
Вес репутации: 3796/110
Марк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond repute
По умолчанию Re: C vs Assembler, inline Assembler в C

Цитата:
Сообщение от den4mc Посмотреть сообщение
Мой первый вопрос:

На ПК в С или С++ возможна такая конструкция:
Var_a = Var_b = Var_c = const;
На ассемблере её реализовывал так:
movlw const
movwf Reg_Var_a
movwf Reg_Var_b
movwf Reg_Var_c

в MPlab C30 такая конструкция не допускается, приходится делать так:
Var_a = const;
Var_b = const;
Var_c = const;

Можно-ли заставить С30 запихать значение в несколько регистров без промежуточной загрузки?
Сама по себе многострочная или однострочная запись присвоения НИКАК НЕ ВЛИЯЕТ на сгенерированный код. Код будет определяться, как я ранее уже написАл, системой команд и выбранным уровнем оптимизации.
На ASM30(ASM16) присвоение константы нескольким регистрам в ОЗУ делается ровно так же, как и в MPASM (8-битный АСМ):

Код:
mov  #const, W0
mov  W0, bufRAM_0
mov  W0, bufRAM_1
mov  W0, bufRAM_2
mov  W0, bufRAM_3
или для следующих подряд переменных в ОЗУ (массив):

Код:
mov  #const, W0
mov  #bufRAM, W1
repeat  #3
mov  W0, [W1++]
Марк на форуме   Ответить с цитированием
Старый 05.01.2020, 16:21   #5
den4mc
Junior Member
 
Регистрация: 18.12.2014
Сообщений: 11
Вес репутации: 90/0
den4mc will become famous soon enough
По умолчанию Re: C vs Assembler, inline Assembler в C

Спасибо за быстрый ответ, Марк

Цитата:
Сообщение от Марк Посмотреть сообщение
Сама по себе многострочная или однострочная запись присвоения НИКАК НЕ ВЛИЯЕТ на сгенерированный код. Код будет определяться, как я ранее уже написАл, системой команд и выбранным уровнем оптимизации.
На ASM30(ASM16) присвоение константы нескольким регистрам в ОЗУ делается ровно так же, как и в MPASM (8-битный АСМ):
[/CODE]
но вопрос как раз в том что когда пишу, например, следующее:
tmpU1RXREG = Res_Addr11 = 0x01;
то получаю ошибку компиляции... error: global register variable follows a function definition
т.е. компилятор не принимает однострочное присвоение.
Вопрос: компилятор это не умеет или синтаксис у меня неправильный?

Цитата:
Сообщение от Марк Посмотреть сообщение
Все дело в байтовой пересылке непосредственно в ОЗУ.
В системе команд PIC24/30/33 байтовые пересылки из регистра в ОЗУ можно сделать только через W0.
[/CODE]
Тут Вы не правы, практически через любой рабочий регистр например через w1,w2 и т.д.
но вопрос в том, что я пытаюсь переместить из w8 в регистр ОЗУ, а компилятор делает это через w0. т.е. w8->w0, w0->регистр озу.

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

Последний раз редактировалось den4mc; 05.01.2020 в 16:32.
den4mc вне форума   Ответить с цитированием
Старый 05.01.2020, 16:53   #6
Марк
Senior Member
 
Аватар для Марк
 
Регистрация: 18.08.2007
Адрес: Московская область
Возраст: 60
Сообщений: 2,740
Вес репутации: 3796/110
Марк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond repute
По умолчанию Re: C vs Assembler, inline Assembler в C

Цитата:
Сообщение от den4mc Посмотреть сообщение
т.е. компилятор не принимает однострочное присвоение.
Я ничего не говорил про возможность однострочного написания. Я говорил про то, что это не имеет никакого значения, кроме внешнего вида. Ни в каком компиляторе. Даже в том, в котором это допустимо.

Цитата:
Сообщение от den4mc Посмотреть сообщение
Тут Вы не правы, практически через любой рабочий регистр например через w1,w2 и т.д.
Может все таки Вам стоит открыть мануал по программированию для 16-разрядной платформы, а не возражать в вопросах, в которых Вы не разбираетесь?
http://ww1.microchip.com/downloads/e.../70000157g.pdf
Читаем на странице 299-300 описание команды mov(.b) f, WREG/mov(.b) WREG, f и сравниваем его с описанием на странице 301-302 несколько ДРУГОЙ команды mov f, Wns/mov Wns, f.
У Вас БАЙТОВАЯ пересылка, поскольку Вы сами определили тип переменной как char. Из этого следует, что применять вторую пару команд НЕВОЗМОЖНО.
Учите матчасть, а не фантазируйте.
Марк на форуме   Ответить с цитированием
Старый 05.01.2020, 18:04   #7
den4mc
Junior Member
 
Регистрация: 18.12.2014
Сообщений: 11
Вес репутации: 90/0
den4mc will become famous soon enough
По умолчанию Re: C vs Assembler, inline Assembler в C

Цитата:
Сообщение от Марк Посмотреть сообщение
Может все таки Вам стоит открыть мануал по программированию для 16-разрядной платформы, а не возражать в вопросах, в которых Вы не разбираетесь?
На мой взгляд эта фраза несколько грубовато звучит...
Я читал PIC24FJ256GB110 Family Data Sheet 39897c
там из байт ориентированных команд mov описана только: MOV.b #lit8,Wn
из чего сделал данный вывод.


Ещё раз спасибо за быстрый и полный ответ.


ps. пробовал включать оптимизацию, довольно хорошо оптимизировало switch..case
убрало лишние команды пересылки при присвоении, но в другом месте вставило косвенную адресацию вместо прямой что увеличило длину определённого куска, хот обща длина программы сократилась.
den4mc вне форума   Ответить с цитированием
Старый 05.01.2020, 18:16   #8
Марк
Senior Member
 
Аватар для Марк
 
Регистрация: 18.08.2007
Адрес: Московская область
Возраст: 60
Сообщений: 2,740
Вес репутации: 3796/110
Марк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond repute
По умолчанию Re: C vs Assembler, inline Assembler в C

Цитата:
Сообщение от den4mc Посмотреть сообщение
На мой взгляд эта фраза несколько грубовато звучит...
Не более грубо, чем заслуживает Ваше бестактное возражение. Бестактность состоит не в форме, а в содержании....
Тем более, что про Ваши фантазии я оказался прав. С чего бы?
ЗЫ. При работе с МК, стоит читать ВСЮ публикуемую на него документацию, а не выборочно. Мануал по программированию приведен абсолютно со всеми МК 16 разрядной платформы прежде референсных мануалов, сразу за эрратой. Там не только система команд, но и программная модель МК. Если Вы пытаетесь писать на АСМе (даже вставки), то этот документ нужно изучить вдоль и поперек. А так же мануал на компилятор, кстати. А то Ваши АСМ тексты выглядят, мягко говоря, странно...
Марк на форуме   Ответить с цитированием
Старый 05.01.2020, 18:30   #9
Марк
Senior Member
 
Аватар для Марк
 
Регистрация: 18.08.2007
Адрес: Московская область
Возраст: 60
Сообщений: 2,740
Вес репутации: 3796/110
Марк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond reputeМарк has a reputation beyond repute
По умолчанию Re: C vs Assembler, inline Assembler в C

Цитата:
Сообщение от den4mc Посмотреть сообщение
ps. пробовал включать оптимизацию, довольно хорошо оптимизировало switch..case
убрало лишние команды пересылки при присвоении, но в другом месте вставило косвенную адресацию вместо прямой что увеличило длину определённого куска, хот обща длина программы сократилась.
Оптимизация приводит к невозможности пошаговой отладки. Ну и выглядит для тех, кто не пытается разобраться в программной модели МК, как откровенное шаманство.
На самом деле, локальные переменные, например, открываются через фрейм, который располагается прямо впереди вершины стека с помощью инструкции lnk #N и закрываются инструкцией ulnk. В результате все операции с локальными переменными идут через указатель фрейма W14, то есть через косвенно-индексную адресацию.
ЗЫ. И еще один момент. Та самая байтная команда с 8-битным литералом имеет НЕБАЙТНУЮ альтернативу, где литерал уже 10-битный. А причина очень проста. Байтные пересылки требуют на один бит больше в адресном поле команды....

Последний раз редактировалось Марк; 05.01.2020 в 18:36.
Марк на форуме   Ответить с цитированием
Старый 05.01.2020, 19:02   #10
den4mc
Junior Member
 
Регистрация: 18.12.2014
Сообщений: 11
Вес репутации: 90/0
den4mc will become famous soon enough
По умолчанию Re: C vs Assembler, inline Assembler в C

Интересная информация про фрейм, но в моём случае:


до оптимизации:
0179E BFCD4B mov.b 0x0d4b,0x0000
017A0 684008 xor.b 0x0000,0x0010,0x0000
017A2 B7ED48 mov.b 0x0000,0x0d48

017A4 20D4A2 mov.w #0xd4a,0x0004
017A6 784112 mov.b [0x0004],0x0004
017A8 BFCD48 mov.b 0x0d48,0x0000
017AA FB8080 ze 0x0000,0x0002
017AC 20A080 mov.w #0xa08,0x0000
017AE 408000 add.w 0x0002,0x0000,0x0000
017B0 784010 mov.b [0x0000],0x0000
017B2 694000 xor.b 0x0004,0x0000,0x0000
017B4 B7ED4B mov.b 0x0000,0x0d4b
434: intend:
017B6 BFCD48 mov.b 0x0d48,0x0000
017B8 FB8080 ze 0x0000,0x0002
017BA 20B080 mov.w #0xb08,0x0000
017BC 408000 add.w 0x0002,0x0000,0x0000
017BE 784010 mov.b [0x0000],0x0000
017C0 B7ED4A mov.b 0x0000,0x0d4a

после:
01CDE 20D570 mov.w #0xd57,0x0000
01CE0 6C4410 xor.b 0x0010,[0x0000],0x0010
01CE2 780008 mov.w 0x0010,0x0000
01CE4 B7ED54 mov.b 0x0000,0x0d54

01CE6 FB8408 ze 0x0010,0x0010
01CE8 20B080 mov.w #0xb08,0x0000
01CEA 7840E8 mov.b [0x0010+0x0000],0x0002
01CEC BFCD56 mov.b 0x0d56,0x0000
01CEE 684001 xor.b 0x0000,0x0002,0x0000
01CF0 B7ED57 mov.b 0x0000,0x0d57
434: intend:
01CF2 20A080 mov.w #0xa08,0x0000
01CF4 784068 mov.b [0x0010+0x0000],0x0000
01CF6 B7ED56 mov.b 0x0000,0x0d56
den4mc вне форума   Ответить с цитированием
Ответ

Метки
c vs assembler, inline assembler в c


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SIM900 не отвечает на команды rengen Cетевые протоколы и технологии 40 24.10.2013 19:52
ищу 500-1000 штук "single inline strips" типа SIB-132-S001-9х Gera82 Общетехнические вопросы 1 12.07.2011 16:20
Proteus PIC18 и Assembler проблемы моделирования zver-diman Вопросы начинающих 18 01.02.2010 07:56
inline в C18 militrik Продукция MICROCHIP 10 10.10.2009 21:38
Изучение CCS PIC compile - вопросы к знатокам. Amateur Продукция MICROCHIP 33 26.08.2008 12:35


Часовой пояс GMT +3, время: 12:42.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot