| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| GCC (ARM) инструкции на асемблер в C кода - как? http://mcu-bg.com/mcu_site/viewtopic.php?f=16&t=6830 |
Страница 1 от 1 |
| Автор: | Цецо [ Сря Май 20, 2009 10:02 am ] |
| Заглавие: | GCC (ARM) инструкции на асемблер в C кода - как? |
Как се вмъкват асемблерски инструкции в C код под GCC? Трябва да нахакам едни микрозакъснения, т.е. за няколко NOP-a иде реч. А пуста документация на GCC.... |
|
| Автор: | FiTTiLA [ Сря Май 20, 2009 10:20 am ] | |||||||||
| Заглавие: | Re: GCC (ARM) инструкции на асемблер в C кода - как? | |||||||||
asm("NOP"); |
||||||||||
| Автор: | Цецо [ Сря Май 20, 2009 10:33 am ] |
| Заглавие: | |
Екстра. А как да вкарам малко повече инструкции, с някой етикет/джъмп евентуално? И къде въобще е документирано това? В GCC документацията не го откривам? |
|
| Автор: | miro_atc [ Сря Май 20, 2009 10:55 am ] | |||||||||||||||||||||||||||
| Заглавие: | ||||||||||||||||||||||||||||
да asm()... но има доста подробности. Имаше документация, ама сега не ми се рови - ще го обясня с пример:
В случая това е функция дето съм я направил изцяло на асемблер щото GCC няма друг начин за поддръжка на SWI, както и да е асемблер може да се вгражда *навсялъде*... Първо asm, после volatile за да не си прави шегички при оптимазия, после в кавички колкото на брой искаш асемблерски инструкции и накрая трите реда с ":", които имат следното значение: Първия ред описва "изхода" на асемблера като променливи и/или регистри. Втория ред описва входните параметри, а третия ред описва обекти дето асемблера може и да омаже... Ако параметъра е изходен трябва да започва с "=" след това с "r" ако е регистров, ако е типът е imidiate (константа) се описва с "I". Всички парамтери получават номерца и после с тия номерца се ползват в асемблерския код. Примерно аз ползвам %2 в кода на SWI инструкцията - това е втори номер, т.е. usr_send_signal_swi Една особеност - ако един параметър е едновременно входен и изходен, първо си се декларира като изходен, а после се изброява номера му. Така са ми _task и _signal - първо ги декларирам с "=r", т.е. като регистър който ще получи стойност, и после ги повтарям и като входни параметри само че без % - деректно номерчето като параметър. Други особености: * Пази се много от оптимизациите.... Избягвай да ползваш директно С-променливи, понеже в зависимост от оптимизацията компилатора може да ги разположи в стека или да ги направи регистрови. А в асемблера все пак трябва да знаеш дали е регистър или памет. Затова най-добре да си направиш собствени променливи дето знаеш какви са, както примерно:
В случая имам Ц-променлива "task" и за да не завися от това каква е, си правя "копие" на променливата в регистрова и то точно определен регистър. Като volatile е задължителен ако не искаш да гониш духове... Не се притеснявай за тези междинни присвоявания - компилатора не е толкова глупав и не прави излишен код. Просто ти му казваш да не пипа твойта версия и съптветно той оптимизира "оригинала". Ето пък пример с повечко инструкции:
Това е код, който обаче няма входни параметри и затова не се налага защита от оптимизациите на компилатора... |
||||||||||||||||||||||||||||
| Автор: | Цецо [ Сря Май 20, 2009 11:10 am ] |
| Заглавие: | |
Благодарско. Засега ми трябва съвсем праволинеен код, без предаване на параметри. |
|
| Автор: | miro_atc [ Сря Май 20, 2009 11:18 am ] |
| Заглавие: | |
Всъщност малко поизлъгах с входните и изходните параметри... Като му кажеш, че искаш да ползваш като параметър в регистър някаква променлива с "r"(foo) - компилатора се грижи да намери някой своден регистър и да ти качи стойността на тази променлива в този регистър. Същото е и при изхода, като му кажеш че изкарваш резултат, то ще ти го запише където трябва. Проблемът в моя случай със SWI функциите е, че по разни причини искам да са static функция, а при static функциите GCC се прави на тарикат и заебава calling конвенцията, т.е. няма гаранция че функцията ще получава параметрите си точно с R0-R3 +стек. Може да си избере други регистри. Но от друга страна аз при SWI викам хендлъри и асемблерски код, който не е inline и ми трябва първия параметър да е в R0, втория в R1 и т.н. както си е по arm calling convention. Та затова трябваше да минавам с тия междинни volatile register променливи... Ако на асемблера не му пука кой параметър в кой регистър, май спокойно може да е простичко както във втория пример.... |
|
| Автор: | Zdrav [ Сря Май 20, 2009 4:42 pm ] |
| Заглавие: | |
http://www.ethernut.de/en/documents/arm-inline-asm.html |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|