Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Малко уроци за чудото указател и инициализиране на указатели
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=4709
Страница 1 от 1

Автор:  popo [ Пон Авг 27, 2007 11:12 pm ]
Заглавие:  Малко уроци за чудото указател и инициализиране на указатели

Мисля че всички знаем що е указател и как се инициализира. Но има неща които само добрите програмисти могат да направят, какво е то.
В микроконтролерите се оказва че с указатели се работи по бързо и всеки ги предпочита, пред това да извиква директно (вместо индиректно) променлива от SRAM-а. Виждам че тук в този форум има добри програмисти на асемблер и С, и ако може да споделят някой виртуозни изпълнения , и приложения на указатели с по прости обяснения защото някой когато трябваше да учат биха врабчета по улиците.

Автор:  zaphod [ Вто Авг 28, 2007 8:20 am ]
Заглавие: 

това че с указатели било по-бързо от де ти хрумна? указателите се ползват основно за две неща: динамични структури данни и предаване на аргумент подлежащ на промяна. за второто си има и референции, но указателът позволява да се предаде 0, което може да се интерпретира като незаинтересованост от дадения параметър и да се ускори малко кода. ако ползваш указатели за "по-бързо" яко се набутваш.

Автор:  Цецо [ Вто Авг 28, 2007 8:46 am ]
Заглавие: 

Нема по бързо от статични глобални променливи :) :) :) Всъщност има - регистрови, ама там лимита е сложен.

Автор:  miro_atc [ Вто Авг 28, 2007 10:25 am ]
Заглавие:  Re: Малко уроци за чудото указател и инициализиране на указа

avsrm написа:
В микроконтролерите се оказва че с указатели се работи по бързо и всеки ги предпочита, пред това да извиква директно (вместо индиректно) променлива от SRAM-а.


Не знам какви мухи бръмчат в главата ти, ама такова животно няма! От микроконтролер до микроконтролер разликата е като от небето до земята...
Нещо което е оптимално в един случай, може да е много кофти в друг. Всичко зависи от конкретната архитектура и подходите са два - или се съобразяваш с възможностите на архитектурата или пишеш универсален код. Кой от двата подхода да избереш зависи от това което правиш.
Сравнително по-често се избира универсалния подход, демек пишеш така че да се получи изчистен С-код. В тоя случай наистина се предпочитат указатели. Примерно ако имаш масив, вместо да използваш индексиране (адреса/името на масива + номера на елемента) се предпочита указател към i-тия елемент, който указател се инкрементира при обхождане.
Това се счита за "по-добрия" вариант. Да, ама не! Просто е станало "класика в жанра" защото С-стандартите са създадени основно върху х86 архитектури. При други микроконтролери/процесори (примерно АРМ) има асемблерски инструкции които позволяват регистрово индексиране и няма нужда да работиш с указатели. Въпреки всичко не е зле да ползваш "стандартните" концепции, защото компилаторите в повечето случаи разпознават циклите и си ги компилират добре.

А пък ако пишеш само за конкретна архитектура и си сигурен че същия код няма да го пуснеш на друга - ами просто погледни възможностите на дадената архитектура и тогава ще знаеш кое е най-добре. Специално за указателите трудно ще постигнеш огромни разлики. Всички процесори поддържат работа с указатели, така че кода ти винаги ще се компилира сравнително добре. Изключения са може би малките 8/16 битови контролери които имат директен достъп до паметта, тогава единична променлива е по-добре да си я ползваш директно вместо през указател.
Повече внимавай с концепцията за предаване на параметри на функции, защото от тук може да извлечеш повече файда. Обикновено имаш няколко параметъра които се предават регистрово, а другите през стека. Добре е така да си оптимизираш функциите, че те да си получават параметрите само по регистри. Примерно на АРМ имаш до 4 регистрови параметъра и ако имаш функция с 5 параметъра е добре да ги сведеш до 4. Един вариант е като групираш няколко в една структура и подаваш указател на структурата. Това е пак относително, защото зависи от характера на данните.
В общия случай ако искаш да пишеш оптимален код за конкретна архитектура задължително трябва да поназнайваш асемблера й и переодично да проверяваш какви ги върши компилатора ти. И от там да се ориентираш какъв С-код да използваш че да се получават добри резултати.

Автор:  MYXATA [ Вто Авг 28, 2007 12:04 pm ]
Заглавие: 

Цецо написа:
Нема по бързо от статични глобални променливи :) :) :) Всъщност има - регистрови, ама там лимита е сложен.

Цецо тук е много прав!
ама и другите са прави :) - зависи от хардуерната платформа, и от компилатора :!:
това дето miro_atc ти го каза може да се изпише така:
иначе например за сигнален процесор да се ползват регистрови променливи за често използвани промеливи по-бързо нема :!:, но там
има 4 до 7 регистри за указатели (registers for pointer register variables)
//***********************************************************************************
//смяна на един обект в паметта с друг
do
{
temp = *++src;
*src = *++dest;
*dest = temp;
}
while (--n);
//************************************************************************************
без регистрови променливи това отнема 12 инструкции и 19 цикъла. С регистрови променливи отнема 4 инструкции и 7 цикъла :)

друго :
използвай *++ да обхожаш масивите с данни, вместо индекс да преизчисляваш текущият адрес в масива всеки път в цикъла
//************************************************************************************
//бавен начин 19 цикъла
main()
{
float a[10], b[10];
int i;
register float *p = a, *q = b;

for (i = 0; i < 10; ++i)
a[i] = (a[i] * 20) + b[i];
}

///************************************************************************************
//по-бърз начин 12 цикъла
main()
{
float a[10], b[10];
int i; int i;
register float *p = a, *q = b;

for (i = 0; i < 10; ++i)
*p++ = (*p * 20) + *q++;
}
//************************************************************************************
и пак да напомня това е по-ефективен код но при съответната архитектура на процесора :!:

Автор:  popo [ Вто Авг 28, 2007 12:22 pm ]
Заглавие: 

Май нещо съм се заблудил.

.DSEG
.ORG 0x80

mas:
.BYTE 0x7


.CSEG


LDI R30,LOW(mas)
MOV R3,R30

;Първи начин директно 3 цикъла

LDI R30,LOW(97)
STS mas,R30
;Втори начин индиректно 3 цикъла

MOV R26,R3
ST X,R30
nop
nop
Тогава каде се използваха указателите и кода ставаше по компактен искам да знам повече за структурите.
Интересуват ме малките микроконтролери а не специализирани, тези които използват банки или 2-ки регистри за да достигнат по големи адреси в рама. Даааа бе забравих това е за Tiny-тата на АТМЕЛ

Автор:  MYXATA [ Вто Авг 28, 2007 12:28 pm ]
Заглавие: 

avsrm,
хубаво си драснал код ама кажи за кой процесор е, все пак

Автор:  popo [ Вто Авг 28, 2007 1:04 pm ]
Заглавие: 

за първи път когато започнах да се занимавам микрухи, исках да си направя едно устройство да трие MACROVISION - на видеофилмите на александра видео (беше преди 96 година) бяха сложили едни импулси на 2-3 реда преди кадровия импулс и на самия кадрови гасящ .
бях започнал да правя делители за броя на редовете... абе голем проект ама се оказа много голям броя на логическите схеми .
та това за по лесно се заех да го напиша на един PIC 16F84, и до като навлезна в асемблера и докато схвана за какво става на въпрос
та отне доста време. Но го направих . След това си написах и една програмка за 12с508 която служеше да добавя едно повикване на звъненето на факсовете . ( някой искаха позваняване на 5 секунди а не на 10сек) и така нататък......
От 2 години започнах да чета сам за С езика за програмиране и то защото се появиха добри, поне за мен С компилатори
като CodeVision и CCS PCWH иначе се занимавам с ремонт на TV-та и разкодиране на радиокасетофони.

Автор:  popo [ Вто Авг 28, 2007 6:10 pm ]
Заглавие: 

защо така се получава при 2 вида адресиране на масиви и промяна на масив.
тва e ATtiny (извинете за грешките но до сега сам писал само праволинеен код без масиви без sram използвал сам само регистрите за променливите
а и езика не ми е професионален но сещайте се за какво става на въпрос "незаинтересованост от дадения параметърми звучи станно")

.DSEG ;определям каде да се разположат променливите
.ORG 0x80 ; да са след адрес 80 защото от там почва SRAM

mas:
.BYTE 0x7 ;определям 7 байта за масив от 6 елемента щото трябвало последния да е 0 (при char)


.CSEG ; започва ми разположението на програмния код


; point=mas;
LDI R30,LOW(mas) ;зареждам адреса на 1 елемент на масива mas[0]
MOV R3,R30 ;запазвам този адрес в R3
;direktno mas[0]='a'; 7 instr а==0x61==97
LDI R30,LOW(97)
STS mas,R30

;mas[1]='b' b==0x62==98

LDI R30,LOW(mas+1)
LDI R26,LOW(98)
STD Z+0,R26
;s pointer point[2]='a'; 10 instr
MOV R30,R3
SUBI R30,-LOW(2)
LDI R26,LOW(97)
STD Z+0,R26
;point[3]='b';
MOV R30,R3
SUBI R30,-LOW(3)
LDI R26,LOW(98)
STD Z+0,R26



lp:
rjmp lp

Автор:  Реконструктор [ Вто Авг 28, 2007 8:13 pm ]
Заглавие: 

zaphod написа:
това че с указатели било по-бързо от де ти хрумна? указателите се ползват основно за две неща: динамични структури данни и предаване на аргумент подлежащ на промяна. за второто си има и референции, но указателът позволява да се предаде 0, което може да се интерпретира като незаинтересованост от дадения параметър и да се ускори малко кода. ако ползваш указатели за "по-бързо" яко се набутваш.


Има си процесори (много са!) с хардуерна подръжка на указатели. ;) А референцията е чист указател, направен да не изглежда като такъв, за да не се плашат децата.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/