Поскольку такая тема активно развивается в Варезнике, предлагаю обсуждать работу программы здесь.
» Keil uVision
Да, только что то никто не хочет обсуждать, а было бы полезно!
Поскольку такая тема активно развивается в Варезнике, предлагаю обсуждать работу программы здесь.
Ну так давайте обсуждать!
Пакетом пользуюсь очень давно, еще с 5-й версии (когда IDE и в помине не было). Конечно, с тех пор много воды утекло, но все еще присутствуют недостатки, которые откровенно удивляют.
Один из них - генерация кода из "с"-текста. Особенно удивляют загрузки из регистра через другой промежуточный регистр типа
mov AR7, R4
mov A, R7
причем ни R4, ни R7 далее не используются. Один раз видел использование 2 (двух!) промежуточных регистров.
Нет, я конечно понимаю, что код генерируется компилятором, а не человеком пишется. Но! Во-первых, есть 9(!) уровней оптимизации. Во-вторых, они действительно работают Более того, я в своих ассемблерных фрагментах использую некоторые приемы, "подсмотренные" у компилятора С. И при этом такие странные и досадные проколы Кстати, не заметил разницы в результатах между вариантами оптимизации "по размеру" и "по скорости".
Что касается моего сообщения о проблемах с EPM900, то они были вызваны все же USB (другие устройства тоже ведут себя странно).
Пакетом пользуюсь очень давно, еще с 5-й версии (когда IDE и в помине не было). Конечно, с тех пор много воды утекло, но все еще присутствуют недостатки, которые откровенно удивляют.
Один из них - генерация кода из "с"-текста. Особенно удивляют загрузки из регистра через другой промежуточный регистр типа
mov AR7, R4
mov A, R7
причем ни R4, ни R7 далее не используются. Один раз видел использование 2 (двух!) промежуточных регистров.
Нет, я конечно понимаю, что код генерируется компилятором, а не человеком пишется. Но! Во-первых, есть 9(!) уровней оптимизации. Во-вторых, они действительно работают Более того, я в своих ассемблерных фрагментах использую некоторые приемы, "подсмотренные" у компилятора С. И при этом такие странные и досадные проколы Кстати, не заметил разницы в результатах между вариантами оптимизации "по размеру" и "по скорости".
Что касается моего сообщения о проблемах с EPM900, то они были вызваны все же USB (другие устройства тоже ведут себя странно).
Да, только что то никто не хочет обсуждать, а было бы полезно!
PapaKarlo
Оптимизация, конечно, далека от оптимальной... И если для больших братьев пентиумов-атлонов это не так уж и страшно, то для 51-серии, например, весьма существенно. Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме. Хотя, кстати, поддержка ассемблерных включений сделана тоже не особо. Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен. Пока делаю методом пробных компиляций и анализом кода.
А особенно удручают недочеты в среде программирования, которые от версии к версии меняются но, кажется, количество их не уменьшается. Но альтернативы пакету пока не вижу.
Оптимизация, конечно, далека от оптимальной... И если для больших братьев пентиумов-атлонов это не так уж и страшно, то для 51-серии, например, весьма существенно. Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме. Хотя, кстати, поддержка ассемблерных включений сделана тоже не особо. Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен. Пока делаю методом пробных компиляций и анализом кода.
А особенно удручают недочеты в среде программирования, которые от версии к версии меняются но, кажется, количество их не уменьшается. Но альтернативы пакету пока не вижу.
Ну так давайте обсуждать!
Пакетом пользуюсь очень давно, еще с 5-й версии (когда IDE и в помине не было). Конечно, с тех пор много воды утекло, но все еще присутствуют недостатки, которые откровенно удивляют.
Один из них - генерация кода из "с"-текста. Особенно удивляют загрузки из регистра через другой промежуточный регистр типа
mov AR7, R4
mov A, R7
причем ни R4, ни R7 далее не используются. Один раз видел использование 2 (двух!) промежуточных регистров.
Нет, я конечно понимаю, что код генерируется компилятором, а не человеком пишется. Но! Во-первых, есть 9(!) уровней оптимизации. Во-вторых, они действительно работают Более того, я в своих ассемблерных фрагментах использую некоторые приемы, "подсмотренные" у компилятора С. И при этом такие странные и досадные проколы Кстати, не заметил разницы в результатах между вариантами оптимизации "по размеру" и "по скорости".
Что касается моего сообщения о проблемах с EPM900, то они были вызваны все же USB (другие устройства тоже ведут себя странно).
Пакетом пользуюсь очень давно, еще с 5-й версии (когда IDE и в помине не было). Конечно, с тех пор много воды утекло, но все еще присутствуют недостатки, которые откровенно удивляют.
Один из них - генерация кода из "с"-текста. Особенно удивляют загрузки из регистра через другой промежуточный регистр типа
mov AR7, R4
mov A, R7
причем ни R4, ни R7 далее не используются. Один раз видел использование 2 (двух!) промежуточных регистров.
Нет, я конечно понимаю, что код генерируется компилятором, а не человеком пишется. Но! Во-первых, есть 9(!) уровней оптимизации. Во-вторых, они действительно работают Более того, я в своих ассемблерных фрагментах использую некоторые приемы, "подсмотренные" у компилятора С. И при этом такие странные и досадные проколы Кстати, не заметил разницы в результатах между вариантами оптимизации "по размеру" и "по скорости".
Что касается моего сообщения о проблемах с EPM900, то они были вызваны все же USB (другие устройства тоже ведут себя странно).
PapaKarlo
Оптимизация, конечно, далека от оптимальной... И если для больших братьев пентиумов-атлонов это не так уж и страшно, то для 51-серии, например, весьма существенно. Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме. Хотя, кстати, поддержка ассемблерных включений сделана тоже не особо. Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен. Пока делаю методом пробных компиляций и анализом кода.
А особенно удручают недочеты в среде программирования, которые от версии к версии меняются но, кажется, количество их не уменьшается. Но альтернативы пакету пока не вижу.
Оптимизация, конечно, далека от оптимальной... И если для больших братьев пентиумов-атлонов это не так уж и страшно, то для 51-серии, например, весьма существенно. Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме. Хотя, кстати, поддержка ассемблерных включений сделана тоже не особо. Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен. Пока делаю методом пробных компиляций и анализом кода.
А особенно удручают недочеты в среде программирования, которые от версии к версии меняются но, кажется, количество их не уменьшается. Но альтернативы пакету пока не вижу.
ddddF
Цитата:
Я просто собираю программу из "c"- и "asm"-модулей. В этом плане Keil сделал еще в 7-й версии очень важный шаг - ассемблерные файлы перед трансляцией обрабатываются тем же c-препроцессором. Это позволяет использовать #if, #include и #define общие для всех файлов проекта. "Недотянул" Keil только .lin файлы, а так было бы просто превосходно - полная условная обработка проекта.
Цитата:
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c", ручное же "вылизывание" несоответствий может оказаться плохо переносимым в новые версии компилятора. Хотя некоторые фрагменты "с"-модулей я бы сам с удовольствием написал бы именно на ассемблере.
Цитата:
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
Цитата:
Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме.
Я просто собираю программу из "c"- и "asm"-модулей. В этом плане Keil сделал еще в 7-й версии очень важный шаг - ассемблерные файлы перед трансляцией обрабатываются тем же c-препроцессором. Это позволяет использовать #if, #include и #define общие для всех файлов проекта. "Недотянул" Keil только .lin файлы, а так было бы просто превосходно - полная условная обработка проекта.
Цитата:
Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен.В описании компилятора С51 (которое, если я правильно понимаю, входит в виде PDF-файла в установочный комплект, начиная как минимум с 7-й версии) есть подробная информация об интрефейсе между "c"- и "asm"-функциями, о правилах построения имен программных секций и многое другое. Для этого анализ кода не обязателен, хотя бывает полезен. Если есть конкретные вопросы, могу (по мере наличия времени) поделиться опытом.
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c", ручное же "вылизывание" несоответствий может оказаться плохо переносимым в новые версии компилятора. Хотя некоторые фрагменты "с"-модулей я бы сам с удовольствием написал бы именно на ассемблере.
Цитата:
А особенно удручают недочеты в среде программирования... Но альтернативы пакету пока не вижу.Мне кажется, что и разработчики не видят, поэтому не очень стараются. Кроме того, усилия, по-видимому, сосредоточены преимущественно на поддержке новых версий процессоров (и новых, или просто других семейств), что вполне понятно - рынок надо не только удерживать, но и расширять.
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
Цитата:
Я просто собираю программу из "c"- и "asm"-модулей
Я это и имел ввиду.
Цитата:
Мне кажется, что и разработчики не видят, поэтому не очень стараются
Поэтому, я, например, начинаю понемногу искать альтернативу.
ddddF
Цитата:
Найдешь - поделись опытом. Хотя я уже в такой степени ориентировал свои разработки на Keil, что переключиться может оказаться трудновато (как-будто на иглу сел ).
В свое время был интересный пакет IAR, я даже работал какое-то время с ним, причем некоторые возможности, отстутствующие (до сих пор!) в Keil, мне очень нравились. Но в целом Keil тогда перевесил... А вообще-то говоря, нет в мире совершенства! (с) Лис о курах и охотниках.
Цитата:
Поэтому, я, например, начинаю понемногу искать альтерна
Найдешь - поделись опытом. Хотя я уже в такой степени ориентировал свои разработки на Keil, что переключиться может оказаться трудновато (как-будто на иглу сел ).
В свое время был интересный пакет IAR, я даже работал какое-то время с ним, причем некоторые возможности, отстутствующие (до сих пор!) в Keil, мне очень нравились. Но в целом Keil тогда перевесил... А вообще-то говоря, нет в мире совершенства! (с) Лис о курах и охотниках.
PapaKarlo
Цитата:
А что туть знать? создаешь несколько проектов. Затем создаешь multi-project workspace и добавляешь в нее созданые ранее проекты. Какой-либо из них делаешь активным
Цитата:
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
А что туть знать? создаешь несколько проектов. Затем создаешь multi-project workspace и добавляешь в нее созданые ранее проекты. Какой-либо из них делаешь активным
ddddF
Цитата:
Я просто собираю программу из "c"- и "asm"-модулей. В этом плане Keil сделал еще в 7-й версии очень важный шаг - ассемблерные файлы перед трансляцией обрабатываются тем же c-препроцессором. Это позволяет использовать #if, #include и #define общие для всех файлов проекта. "Недотянул" Keil только .lin файлы, а так было бы просто превосходно - полная условная обработка проекта.
Цитата:
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c", ручное же "вылизывание" несоответствий может оказаться плохо переносимым в новые версии компилятора. Хотя некоторые фрагменты "с"-модулей я бы сам с удовольствием написал бы именно на ассемблере.
Цитата:
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
Цитата:
Выход я нахожу только один (может быть, кто-нибудь подскажет альтнернативый) - написание критичных участков кода на асме.
Я просто собираю программу из "c"- и "asm"-модулей. В этом плане Keil сделал еще в 7-й версии очень важный шаг - ассемблерные файлы перед трансляцией обрабатываются тем же c-препроцессором. Это позволяет использовать #if, #include и #define общие для всех файлов проекта. "Недотянул" Keil только .lin файлы, а так было бы просто превосходно - полная условная обработка проекта.
Цитата:
Если кто-нибудь располагает подробной информацией о правилах, по которым компилятор располагает передаваемые параметры в функциях, и готов поделится, буду весьма благодарен.В описании компилятора С51 (которое, если я правильно понимаю, входит в виде PDF-файла в установочный комплект, начиная как минимум с 7-й версии) есть подробная информация об интрефейсе между "c"- и "asm"-функциями, о правилах построения имен программных секций и многое другое. Для этого анализ кода не обязателен, хотя бывает полезен. Если есть конкретные вопросы, могу (по мере наличия времени) поделиться опытом.
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c", ручное же "вылизывание" несоответствий может оказаться плохо переносимым в новые версии компилятора. Хотя некоторые фрагменты "с"-модулей я бы сам с удовольствием написал бы именно на ассемблере.
Цитата:
А особенно удручают недочеты в среде программирования... Но альтернативы пакету пока не вижу.Мне кажется, что и разработчики не видят, поэтому не очень стараются. Кроме того, усилия, по-видимому, сосредоточены преимущественно на поддержке новых версий процессоров (и новых, или просто других семейств), что вполне понятно - рынок надо не только удерживать, но и расширять.
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
Evgeny972
Цитата:
Все, конечно, просто. Но команда Project:Manage:Multi-Project Workspace в меню деактивирована. Подскажи, пожалуйста, как создать multi-project workspace. uVision3 v3.50
Цитата:
А что туть знать? ... создаешь multi-project workspace
Все, конечно, просто. Но команда Project:Manage:Multi-Project Workspace в меню деактивирована. Подскажи, пожалуйста, как создать multi-project workspace. uVision3 v3.50
Цитата:
Я просто собираю программу из "c"- и "asm"-модулей
Я это и имел ввиду.
Цитата:
Мне кажется, что и разработчики не видят, поэтому не очень стараются
Поэтому, я, например, начинаю понемногу искать альтернативу.
Цитата:
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c",
Представим, что можно было бы писать так:
void ExsamplFunc(char data1, char data2, char* addres)
{
asm {
mov a,data1
add a,data2
mov dptr,addres
movx @dptr,a
}
}
И не пришлось бы линковать модули... В Борланде я так и делал. А в Keil-е?
ddddF
Цитата:
Найдешь - поделись опытом. Хотя я уже в такой степени ориентировал свои разработки на Keil, что переключиться может оказаться трудновато (как-будто на иглу сел ).
В свое время был интересный пакет IAR, я даже работал какое-то время с ним, причем некоторые возможности, отстутствующие (до сих пор!) в Keil, мне очень нравились. Но в целом Keil тогда перевесил... А вообще-то говоря, нет в мире совершенства! (с) Лис о курах и охотниках.
Цитата:
Поэтому, я, например, начинаю понемногу искать альтерна
Найдешь - поделись опытом. Хотя я уже в такой степени ориентировал свои разработки на Keil, что переключиться может оказаться трудновато (как-будто на иглу сел ).
В свое время был интересный пакет IAR, я даже работал какое-то время с ним, причем некоторые возможности, отстутствующие (до сих пор!) в Keil, мне очень нравились. Но в целом Keil тогда перевесил... А вообще-то говоря, нет в мире совершенства! (с) Лис о курах и охотниках.
PapaKarlo
Цитата:
А что туть знать? создаешь несколько проектов. Затем создаешь multi-project workspace и добавляешь в нее созданые ранее проекты. Какой-либо из них делаешь активным
Цитата:
Кстати, где-то в HELP'е промелькнуло упоминание о multi-project workspace. Было бы интересно, но я имею ввиду именно multi-project, а не multi-target. Может, кто чего-нибудь знает?
А что туть знать? создаешь несколько проектов. Затем создаешь multi-project workspace и добавляешь в нее созданые ранее проекты. Какой-либо из них делаешь активным
Evgeny972
Цитата:
Все, конечно, просто. Но команда Project:Manage:Multi-Project Workspace в меню деактивирована. Подскажи, пожалуйста, как создать multi-project workspace. uVision3 v3.50
Цитата:
А что туть знать? ... создаешь multi-project workspace
Все, конечно, просто. Но команда Project:Manage:Multi-Project Workspace в меню деактивирована. Подскажи, пожалуйста, как создать multi-project workspace. uVision3 v3.50
ddddF
Цитата:
Не знаю, по-моему это не поддерживается. Можно компилировать "c"-файл в ассемблерный и делать свою вставку туда, но это извращение.
Цитата:
В случае изолированной функции это справедливо, хотя и здесь могут возникнуть проблемы с глобальной оптимизацией использования регистров. Однако очевидно, что если бы asm{} конструкция поддерживалась компилятором, то было бы странно ограничивать ее применение такими случаями, логично было бы допустить, что можно смешивать "c" и "asm" код. Теперь посмотрим на пример генерируемого компилятором (ассемблерного) кода:
Цитата:
Видно, что загрузка DPTR, выполненная для реализации 131-й строки, использована в коде реализации 135-й строки - совершенно нормальная оптимизация. Представим себе, что программист решил вставить между этими строками свой ассемблерный код. В этом случае компилятор скорее всего откажется от оптимизации.
Это, конечно, очень простой пример, здесь программист, зная о размещении данных, может предположить использование компилятором DPTR и, если это возможно, отказаться от ассемблерной вставки именно между этими строками. Другое возражение - компилятор с поддержкой asm{} тоже должен "понимать" эти вставки и предпринимать соответствующие шаги.
Но!
Во-первых, код и оптимизация использования регистров может быть значительно сложнее - я видел примеры трансляции своих программ с очень интересной и довольно сложной оптимизацией.
Во-вторых, я специально привел код, генерируемый для строки 129. Очень хорошо видно, что тут в DTPR загружается та же пара R1,R2, что и для строки 131! Потрясающий пример "оптимизации" по Keil Я прекрасно понимаю, что "c"-операторы извлекают данные из разных подструктур одной и той же структуры, очевидно, для компилятора оптимизация в этом случае оказалась не по зубам. Но можно ведь выполнить еще один проход по генерируемому коду и чисто формально избавиться от лишней загрузки DPTR, тем более, что для уровня оптимизации "3 Peephole Optimizing" в описании говорится: "Redundant MOV instructions are removed." (а у меня установлен уровень 9 с оптимизацией по размеру). Не тут-то было! Не говоря уже о том, что загрузка udata?041+0xH в R1,R2 с последующей загрузкой R1,R2 в DPTR в заявленном контексте "удаление излишних MOV" просто умиляет.
Следовательно, для такой реализации оптимизатора, как в Keil, задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может. Вообще, создается ощущение, что оптимизатор построен не систематически, а по принципу "оптимизируем определенные языковые конструкции". Хотя, как я уже упоминал, некоторые оптимизационные решения просто красивы, и я их использую в своих ассемблерных программах.
Ну, а по поводу
Цитата:
Цитата:
В Борланде я так и делал. А в Keil-е?
Не знаю, по-моему это не поддерживается. Можно компилировать "c"-файл в ассемблерный и делать свою вставку туда, но это извращение.
Цитата:
Представим, что можно было бы писать так:
void ExampleFunc(char data1, char data2, char* addres)
...
В случае изолированной функции это справедливо, хотя и здесь могут возникнуть проблемы с глобальной оптимизацией использования регистров. Однако очевидно, что если бы asm{} конструкция поддерживалась компилятором, то было бы странно ограничивать ее применение такими случаями, логично было бы допустить, что можно смешивать "c" и "asm" код. Теперь посмотрим на пример генерируемого компилятором (ассемблерного) кода:
Цитата:
; OutputCfg.i8val = PDscr->OutputCfg.i8val;
; SOURCE LINE # 129
MOV R2,udata?041+01H
MOV R1,udata?041+02H
MOV DPL,R1
MOV DPH,R2
MOV A,#04H
MOVC A,@A+DPTR
MOV OutputCfg,A
; cfg1.i8val = PDscr->Cfg1.i8val;
; SOURCE LINE # 131
MOV DPL,R1
MOV DPH,R2
MOV A,#05H
MOVC A,@A+DPTR
MOV cfg1?042,A
;
; B_HighCpuClk = (PDscr->ClkCPU==I_HIGH_CPU_CLK);
; SOURCE LINE # 135
MOV A,#07H
MOVC A,@A+DPTR
CJNE A,#030H,?C0005
...
Видно, что загрузка DPTR, выполненная для реализации 131-й строки, использована в коде реализации 135-й строки - совершенно нормальная оптимизация. Представим себе, что программист решил вставить между этими строками свой ассемблерный код. В этом случае компилятор скорее всего откажется от оптимизации.
Это, конечно, очень простой пример, здесь программист, зная о размещении данных, может предположить использование компилятором DPTR и, если это возможно, отказаться от ассемблерной вставки именно между этими строками. Другое возражение - компилятор с поддержкой asm{} тоже должен "понимать" эти вставки и предпринимать соответствующие шаги.
Но!
Во-первых, код и оптимизация использования регистров может быть значительно сложнее - я видел примеры трансляции своих программ с очень интересной и довольно сложной оптимизацией.
Во-вторых, я специально привел код, генерируемый для строки 129. Очень хорошо видно, что тут в DTPR загружается та же пара R1,R2, что и для строки 131! Потрясающий пример "оптимизации" по Keil Я прекрасно понимаю, что "c"-операторы извлекают данные из разных подструктур одной и той же структуры, очевидно, для компилятора оптимизация в этом случае оказалась не по зубам. Но можно ведь выполнить еще один проход по генерируемому коду и чисто формально избавиться от лишней загрузки DPTR, тем более, что для уровня оптимизации "3 Peephole Optimizing" в описании говорится: "Redundant MOV instructions are removed." (а у меня установлен уровень 9 с оптимизацией по размеру). Не тут-то было! Не говоря уже о том, что загрузка udata?041+0xH в R1,R2 с последующей загрузкой R1,R2 в DPTR в заявленном контексте "удаление излишних MOV" просто умиляет.
Следовательно, для такой реализации оптимизатора, как в Keil, задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может. Вообще, создается ощущение, что оптимизатор построен не систематически, а по принципу "оптимизируем определенные языковые конструкции". Хотя, как я уже упоминал, некоторые оптимизационные решения просто красивы, и я их использую в своих ассемблерных программах.
Ну, а по поводу
Цитата:
не пришлось бы линковать модули- да, если вся программа умещается в один исходный файл, то компоновка двух модулей - это лишние хлопоты Но для такой программы в подавляющем большинстве случаев оптимизация не будет являться жизненно важной (ИМХО). А там, где модулей N>1, там и N+1 не будет сильно в тягость. Ну, если N+1 слишком много, то хотя бы M+1
Цитата:
Что касается поддержки именно "asm"-включений в текст на "с", то теоретически может быть полезным, но практически - велика вероятность интерференции с кодом, генерируемым компилятором "c",
Представим, что можно было бы писать так:
void ExsamplFunc(char data1, char data2, char* addres)
{
asm {
mov a,data1
add a,data2
mov dptr,addres
movx @dptr,a
}
}
И не пришлось бы линковать модули... В Борланде я так и делал. А в Keil-е?
Цитата:
да, если вся программа умещается в один исходный файл, то компоновка двух модулей - это лишние хлопоты
Я имел ввиду - разнородные модули, написанные на разных языках. Это явно не способствует повышению качества программ.
Цитата:
Но для такой программы в подавляющем большинстве случаев оптимизация не будет являться жизненно важной
Это только в том случае, если не критичны требования к скорости работы программы.
Цитата:
задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может.
Да не нужно бы ему тут разбираться. Компилятор генерировал бы код входа в функцию - передачи параметров, например, в регистрах, в соответствии с правилами размещения параметров. Дальше я пишу сам тело функции и - все дела. Это позволило бы оптимизировать отдельные, критичные функции, не нарушаю общего стиля программы. Странно, что keil-овцы отказались от этого. Ну, им виднее. Модули линковать - я согласен, проблема не самая большая.
ddddF
Цитата:
Не знаю, по-моему это не поддерживается. Можно компилировать "c"-файл в ассемблерный и делать свою вставку туда, но это извращение.
Цитата:
В случае изолированной функции это справедливо, хотя и здесь могут возникнуть проблемы с глобальной оптимизацией использования регистров. Однако очевидно, что если бы asm{} конструкция поддерживалась компилятором, то было бы странно ограничивать ее применение такими случаями, логично было бы допустить, что можно смешивать "c" и "asm" код. Теперь посмотрим на пример генерируемого компилятором (ассемблерного) кода:
Цитата:
Видно, что загрузка DPTR, выполненная для реализации 131-й строки, использована в коде реализации 135-й строки - совершенно нормальная оптимизация. Представим себе, что программист решил вставить между этими строками свой ассемблерный код. В этом случае компилятор скорее всего откажется от оптимизации.
Это, конечно, очень простой пример, здесь программист, зная о размещении данных, может предположить использование компилятором DPTR и, если это возможно, отказаться от ассемблерной вставки именно между этими строками. Другое возражение - компилятор с поддержкой asm{} тоже должен "понимать" эти вставки и предпринимать соответствующие шаги.
Но!
Во-первых, код и оптимизация использования регистров может быть значительно сложнее - я видел примеры трансляции своих программ с очень интересной и довольно сложной оптимизацией.
Во-вторых, я специально привел код, генерируемый для строки 129. Очень хорошо видно, что тут в DTPR загружается та же пара R1,R2, что и для строки 131! Потрясающий пример "оптимизации" по Keil Я прекрасно понимаю, что "c"-операторы извлекают данные из разных подструктур одной и той же структуры, очевидно, для компилятора оптимизация в этом случае оказалась не по зубам. Но можно ведь выполнить еще один проход по генерируемому коду и чисто формально избавиться от лишней загрузки DPTR, тем более, что для уровня оптимизации "3 Peephole Optimizing" в описании говорится: "Redundant MOV instructions are removed." (а у меня установлен уровень 9 с оптимизацией по размеру). Не тут-то было! Не говоря уже о том, что загрузка udata?041+0xH в R1,R2 с последующей загрузкой R1,R2 в DPTR в заявленном контексте "удаление излишних MOV" просто умиляет.
Следовательно, для такой реализации оптимизатора, как в Keil, задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может. Вообще, создается ощущение, что оптимизатор построен не систематически, а по принципу "оптимизируем определенные языковые конструкции". Хотя, как я уже упоминал, некоторые оптимизационные решения просто красивы, и я их использую в своих ассемблерных программах.
Ну, а по поводу
Цитата:
Цитата:
В Борланде я так и делал. А в Keil-е?
Не знаю, по-моему это не поддерживается. Можно компилировать "c"-файл в ассемблерный и делать свою вставку туда, но это извращение.
Цитата:
Представим, что можно было бы писать так:
void ExampleFunc(char data1, char data2, char* addres)
...
В случае изолированной функции это справедливо, хотя и здесь могут возникнуть проблемы с глобальной оптимизацией использования регистров. Однако очевидно, что если бы asm{} конструкция поддерживалась компилятором, то было бы странно ограничивать ее применение такими случаями, логично было бы допустить, что можно смешивать "c" и "asm" код. Теперь посмотрим на пример генерируемого компилятором (ассемблерного) кода:
Цитата:
; OutputCfg.i8val = PDscr->OutputCfg.i8val;
; SOURCE LINE # 129
MOV R2,udata?041+01H
MOV R1,udata?041+02H
MOV DPL,R1
MOV DPH,R2
MOV A,#04H
MOVC A,@A+DPTR
MOV OutputCfg,A
; cfg1.i8val = PDscr->Cfg1.i8val;
; SOURCE LINE # 131
MOV DPL,R1
MOV DPH,R2
MOV A,#05H
MOVC A,@A+DPTR
MOV cfg1?042,A
;
; B_HighCpuClk = (PDscr->ClkCPU==I_HIGH_CPU_CLK);
; SOURCE LINE # 135
MOV A,#07H
MOVC A,@A+DPTR
CJNE A,#030H,?C0005
...
Видно, что загрузка DPTR, выполненная для реализации 131-й строки, использована в коде реализации 135-й строки - совершенно нормальная оптимизация. Представим себе, что программист решил вставить между этими строками свой ассемблерный код. В этом случае компилятор скорее всего откажется от оптимизации.
Это, конечно, очень простой пример, здесь программист, зная о размещении данных, может предположить использование компилятором DPTR и, если это возможно, отказаться от ассемблерной вставки именно между этими строками. Другое возражение - компилятор с поддержкой asm{} тоже должен "понимать" эти вставки и предпринимать соответствующие шаги.
Но!
Во-первых, код и оптимизация использования регистров может быть значительно сложнее - я видел примеры трансляции своих программ с очень интересной и довольно сложной оптимизацией.
Во-вторых, я специально привел код, генерируемый для строки 129. Очень хорошо видно, что тут в DTPR загружается та же пара R1,R2, что и для строки 131! Потрясающий пример "оптимизации" по Keil Я прекрасно понимаю, что "c"-операторы извлекают данные из разных подструктур одной и той же структуры, очевидно, для компилятора оптимизация в этом случае оказалась не по зубам. Но можно ведь выполнить еще один проход по генерируемому коду и чисто формально избавиться от лишней загрузки DPTR, тем более, что для уровня оптимизации "3 Peephole Optimizing" в описании говорится: "Redundant MOV instructions are removed." (а у меня установлен уровень 9 с оптимизацией по размеру). Не тут-то было! Не говоря уже о том, что загрузка udata?041+0xH в R1,R2 с последующей загрузкой R1,R2 в DPTR в заявленном контексте "удаление излишних MOV" просто умиляет.
Следовательно, для такой реализации оптимизатора, как в Keil, задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может. Вообще, создается ощущение, что оптимизатор построен не систематически, а по принципу "оптимизируем определенные языковые конструкции". Хотя, как я уже упоминал, некоторые оптимизационные решения просто красивы, и я их использую в своих ассемблерных программах.
Ну, а по поводу
Цитата:
не пришлось бы линковать модули- да, если вся программа умещается в один исходный файл, то компоновка двух модулей - это лишние хлопоты Но для такой программы в подавляющем большинстве случаев оптимизация не будет являться жизненно важной (ИМХО). А там, где модулей N>1, там и N+1 не будет сильно в тягость. Ну, если N+1 слишком много, то хотя бы M+1
ddddF
Цитата:
Цитата:
Цитата:
Теперь по поводу
Цитата:
Выдержка из Help C51, uVision v3:
Цитата:
Цитата:
разнородные модули, написанные на разных языках. Это явно не способствует повышению качества программ.Ну почему же? И чем это принципиально отличается от использования ассемблерных вставок, тем более в предложенном тобой ниже варианте, когда компилятор генерирует только заголовок функции? Впрочем, см. ниже.
Цитата:
Это только в том случае, если не критичны требования к скорости работы программы.Это правильно. Я имел ввиду следующее соображение: если программа небольшая (простая) и критична к скорости работы, можно ее полностью реализовать на ассемблере в одном файле. Если реализация в одном файле неудобна (по разным причинам, например, если сложность решаемой задачи все же требует разбиения на модули), то без компоновки не обойтись, т.е. мы возвращаемся к случаю
Цитата:
Модули линковать - я согласен, проблема не самая большая.
Теперь по поводу
Цитата:
Компилятор генерировал бы код входа в функцию - передачи параметров, например, в регистрах, в соответствии с правилами размещения параметров. Дальше я пишу сам тело функции и - все дела.
Выдержка из Help C51, uVision v3:
Цитата:
Function Parameters
Passing in Registers
C functions may pass parameters in registers and fixed memory locations. A maximum of 3 parameters may be passed in registers. All other parameters are passed using fixed memory locations. The following tables define what registers are used for passing parameters.
Arg Number char,1-byte ptr int,2-byte ptr long,float generic ptr
Цитата:
да, если вся программа умещается в один исходный файл, то компоновка двух модулей - это лишние хлопоты
Я имел ввиду - разнородные модули, написанные на разных языках. Это явно не способствует повышению качества программ.
Цитата:
Но для такой программы в подавляющем большинстве случаев оптимизация не будет являться жизненно важной
Это только в том случае, если не критичны требования к скорости работы программы.
Цитата:
задача ассемблерных вставок может оказаться непосильной, если он со своим, "собственноручно" генерируемым кодом разобраться не всегда может.
Да не нужно бы ему тут разбираться. Компилятор генерировал бы код входа в функцию - передачи параметров, например, в регистрах, в соответствии с правилами размещения параметров. Дальше я пишу сам тело функции и - все дела. Это позволило бы оптимизировать отдельные, критичные функции, не нарушаю общего стиля программы. Странно, что keil-овцы отказались от этого. Ну, им виднее. Модули линковать - я согласен, проблема не самая большая.
Цитата:
Ну почему же? И чем это принципиально отличается от использования ассемблерных вставок, тем более в предложенном тобой ниже варианте, когда компилятор генерирует только заголовок функции?
Принципивально отличие в том, что в варианте asm {} просто пишется код функции на ассемблере и все. А если писать в отдельном модуле, то необходимы (например):
NAME MODASM ; Name of the program module
?PR?FUNCASM?MODASM SEGMENT CODE ; Seg for program code in 'functions'
PUBLIC "имена функций и проч"
RSEG ?PR?FUNCASM?MODASM ; Program segment
Вот и вся разница. Хотя при ближайшем рассмотрении возможны и другие навороты. Прошу понять меня правильно - я не утверждаю, что без этого не обойтись. Но если я подберу компилятор, который это умеет, я буду считать это несомненым достоинством, поскольку краткость и лаконичность программ и обеспечивает их эффективность и надежность.
ddddF
Цитата:
Цитата:
Цитата:
Теперь по поводу
Цитата:
Выдержка из Help C51, uVision v3:
Цитата:
Цитата:
разнородные модули, написанные на разных языках. Это явно не способствует повышению качества программ.Ну почему же? И чем это принципиально отличается от использования ассемблерных вставок, тем более в предложенном тобой ниже варианте, когда компилятор генерирует только заголовок функции? Впрочем, см. ниже.
Цитата:
Это только в том случае, если не критичны требования к скорости работы программы.Это правильно. Я имел ввиду следующее соображение: если программа небольшая (простая) и критична к скорости работы, можно ее полностью реализовать на ассемблере в одном файле. Если реализация в одном файле неудобна (по разным причинам, например, если сложность решаемой задачи все же требует разбиения на модули), то без компоновки не обойтись, т.е. мы возвращаемся к случаю
Цитата:
Модули линковать - я согласен, проблема не самая большая.
Теперь по поводу
Цитата:
Компилятор генерировал бы код входа в функцию - передачи параметров, например, в регистрах, в соответствии с правилами размещения параметров. Дальше я пишу сам тело функции и - все дела.
Выдержка из Help C51, uVision v3:
Цитата:
Function Parameters
Passing in Registers
C functions may pass parameters in registers and fixed memory locations. A maximum of 3 parameters may be passed in registers. All other parameters are passed using fixed memory locations. The following tables define what registers are used for passing parameters.
Arg Number char,1-byte ptr int,2-byte ptr long,float generic ptr
ddddF
Цитата:
А если еще и инструкции кодировать , то надо писать что-то типа mov DPTR,#Array и т.п. тогда как при кодировании на "с" требуется в N>>1 раз меньше строк, хотя и там придется объявить extern void ExampleFunc(char data1, char data2, char* addres) и включать это объявление во все модули, использующие ExampleFunc, хотя и не надо писать RSEG, а еще не надо писать END в конце файла, а с другой стороны... Треп, конечно Любое решение имеет свои преимущества и недостатки.
Цитата:
Цитата:
А если писать в отдельном модуле, то необходимы (например):
А если еще и инструкции кодировать , то надо писать что-то типа mov DPTR,#Array и т.п. тогда как при кодировании на "с" требуется в N>>1 раз меньше строк, хотя и там придется объявить extern void ExampleFunc(char data1, char data2, char* addres) и включать это объявление во все модули, использующие ExampleFunc, хотя и не надо писать RSEG, а еще не надо писать END в конце файла, а с другой стороны... Треп, конечно Любое решение имеет свои преимущества и недостатки.
Цитата:
о правилах, по которым компилятор располагает передаваемые параметры в функцияхОтветил ли я на вопрос, или надо более подробно? Если да, пиши в ПМ. И успехов!
Цитата:
Ответил ли я на вопрос, или надо более подробно?
Да, спасибо! Я смотрел файл с51.chm - там это описано.
Цитата:
А если еще и инструкции кодировать
Вообщем-то, частично, я так и делал: написал макроассемблер который позволял писать:
R7 = 4, DPTR++, и т.д. В результате имел краткость, похожую на си и эффективность ассемблера.
Кстати, ассемблер для ADSP от Analog Devices тоже такое позволяет.
Вообщем, хотя мы и нафлудили тут маленько, но тема все-таки ожила. Надеюсь на ее продолжение .
А почему нафлудили? Для этого она (тема) и создана.
PapaKarlo
Цитата:
У меня версия 3.51 (С51 8.08а), но думаю это суть дела не меняет:
1. создаешь новую Multi-Project Workspace: Project:New:Multi-Project Workspace
Сохраняешь ее (я сделал Examples.mpw в папке C:\Keil\C51\Examples)
2. Открывается окно Create New Multi-Project Workspace
3. Доавляешь в нем СУЩЕСТВУЮЩИЕ проекты (я взял проекты из папки см. выше).
4. Все
Добавлено:
Открываешь полученную Multi-Project Workspace той же командой Project: Open, только смени в окне открытия Files of type на Multi Project Workspace
PapaKarlo
Цитата:
Все, конечно, просто. Но команда Project:Manage:Multi-Project Workspace в меню деактивирована.
У меня версия 3.51 (С51 8.08а), но думаю это суть дела не меняет:
1. создаешь новую Multi-Project Workspace: Project:New:Multi-Project Workspace
Сохраняешь ее (я сделал Examples.mpw в папке C:\Keil\C51\Examples)
2. Открывается окно Create New Multi-Project Workspace
3. Доавляешь в нем СУЩЕСТВУЮЩИЕ проекты (я взял проекты из папки см. выше).
4. Все
Добавлено:
Открываешь полученную Multi-Project Workspace той же командой Project: Open, только смени в окне открытия Files of type на Multi Project Workspace
Предыдущая тема: Бесплатный софт, Freeware
Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.