Помощь в WinAvr
31.05.2012, 05:28
|
|
|
Прописка
Регистрация: 17.02.2009
Сообщений: 154
Сказал спасибо: 14
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Re: Помощь в WinAvr
Бывает так что, программа не всегда заходит в функцию. Считает, если ни чего не изменилось и не что не произошло,то и заходить туда не надо. А вот можно указать компилятору что заходить туда надо всегда при вызове функции, как нибудь при помощи ASM включения.
|
|
|
|
31.05.2012, 09:01
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,613
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от AGAT0365
|
|
Бывает так что, программа не всегда заходит в функцию. Считает, если ни чего не изменилось и не что не произошло,то и заходить туда не надо. А вот можно указать компилятору что заходить туда надо всегда при вызове функции, как нибудь при помощи ASM включения.
|
В каком месте дорисовать вопросительные знаки? Или этот пост - утверждение, чтобы другие знали и боялись? 
ps А вообще-то интересная повесть про жизнь программы. Работает она себе тайком, живет, как считает нужным. Не посчитала нужным, не вызвала функцию. Надо - так несколько сразу вызовет. Или зайдет куда не надо. Ох уж эти программы. Пишешь их, пишешь, и все напрасно...
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
01.06.2012, 19:26
|
|
|
Прописка
Регистрация: 17.02.2009
Сообщений: 154
Сказал спасибо: 14
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Re: Помощь в WinAvr
Ну, а всё таки возможно сделать так что бы программа заходила каждый раз при вызове?
|
|
|
|
01.06.2012, 20:03
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.12.2004
Сообщений: 3,168
Сказал спасибо: 11
Сказали Спасибо 691 раз(а) в 503 сообщении(ях)
|
Re: Помощь в WinAvr
Вынести функцию в отдельный файл.
|
|
|
|
28.07.2012, 15:48
|
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Re: Помощь в WinAvr
Прошу помощи по ассемблеру.
Не могу найти ошибку!!!
Имеется код на асме, который в CodeVision отлично работает.
|
Код:
|
#include ‹avr/io.h›
// Умножение (возведение в квадрат) 2-х 16-ти битных чисел (погрешность - 2 младших байта)
unsigned int mul16x16_square(unsigned int a, unsigned int b)
{
unsigned int result;
unsigned char tmp = 0;
asm volatile(
"clr %[TMP]" "\n\t"
"mul %B[A], %B[B]" ";Ah * Bh \n\t"
"movw %C[RES], r0" "\n\t"
"mul %A[A], %A[B]" ";Al * Bl \n\t"
"movw %A[RES], r0" "\n\t"
"fmul %B[A], %A[B]" ";Ah * Bl \n\t"
"adc %D[RES], %[TMP]" "\n\t"
"add %B[RES], r0" "\n\t"
"adc %C[RES], r1" "\n\t"
"adc %D[RES], %[TMP]" "\n\t"
: [RES]"=&r" (result), [TMP]"=&r" (tmp)
: [A]"a" (a), [B]"a" (b)
);
return result;
}
int main(void)
{
uint16_t qqq= 0x1234;
while(1)
{
mul16x16_square(qqq, qqq);
asm("nop"::);
}
} |
Это часть дизассемблера, которая интересует (без оптимизации):
|
Код:
|
+0000002E: 818C LDD R24,Y+4 Load indirect with displacement
+0000002F: 819D LDD R25,Y+5 Load indirect with displacement
+00000030: 812E LDD R18,Y+6 Load indirect with displacement
+00000031: 813F LDD R19,Y+7 Load indirect with displacement
+00000032: 01AC MOVW R20,R24 Copy register pair
+00000033: 24FF CLR R15 Clear Register
+00000034: 9F53 MUL R21,R19 Multiply unsigned
+00000035: 0190 MOVW R18,R0 Copy register pair
+00000036: 9F42 MUL R20,R18 Multiply unsigned
+00000037: 0180 MOVW R16,R0 Copy register pair
+00000038: 035A FMUL R21,R18 Fractional multiply unsigned
+00000039: 1D3F ADC R19,R15 Add with carry
+0000003A: 0D10 ADD R17,R0 Add without carry
+0000003B: 1D21 ADC R18,R1 Add with carry
+0000003C: 1D3F ADC R19,R15 Add with carry
+0000003D: 831B STD Y+3,R17 Store indirect with displacement
+0000003E: 830A STD Y+2,R16 Store indirect with displacement
+0000003F: 82F9 STD Y+1,R15 Store indirect with displacement |
А это - та же интересующая часть, только с полной оптимизацией:
|
Код:
|
+0000001C: 01AC MOVW R20,R24 Copy register pair
+0000001D: 2788 CLR R24 Clear Register
+0000001E: 9F57 MUL R21,R23 Multiply unsigned
+0000001F: 01A0 MOVW R20,R0 Copy register pair
+00000020: 9F46 MUL R20,R22 Multiply unsigned
+00000021: 0190 MOVW R18,R0 Copy register pair
+00000022: 035E FMUL R21,R22 Fractional multiply unsigned
+00000023: 1F58 ADC R21,R24 Add with carry
+00000024: 0D30 ADD R19,R0 Add without carry
+00000025: 1D41 ADC R20,R1 Add with carry
+00000026: 1F58 ADC R21,R24 Add with carry |
Соответствующий выделенным в тексте строкам код:
|
Код:
|
"movw %C[RES], r0"
"mul %A[A], %A[B]" |
Не обращая особо ваше внимание на алгоритм, у меня такой вопрос.
Почему в строках (в дизасме они выделены жирным) задействованы одинаковые регистры. Ведь в коде, вроде бы, все правильно стоит (имеется в виду вывод в новый регистр - модификатор '&' в строке вывода - : [RES]"=&r" (result), [TMP]"=&r" (tmp)), а используется один и тот же регистр. В данных случаях - это R18 и R20.
Соответственно результат, который должен быть равен: 1234h * 1234h = 14B 5A90h не получается правильным.
В моих случаях (и в одном и в другом мне интересны только старшие байты) такие результаты:
1(оптимизация откл.) - 1 4Dh
2(оптимизация вкл.) - 1 44h
Ассемблерный код рабочий (проверен в CV).
Где я ошибаюсь?
|
|
|
|
28.07.2012, 16:06
|
|
|
Гражданин KAZUS.RUN
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от hubble
|
// Умножение (возведение в квадрат) 2-х 16-ти битных чисел (погрешность - 2 младших байта)
unsigned int mul16x16_square(unsigned int a, unsigned int b)
|
Интересно, какой смысл передавать функции два параметра, если это возведение в квадрат?
И зачем это не асме писать?
|
|
|
|
28.07.2012, 18:56
|
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от _Артём_
|
|
Интересно, какой смысл передавать функции два параметра, если это возведение в квадрат?
|
Не вопрос. Пусть будет один. Допустим А. Это сильно изменит алгоритм?
Сообщение от _Артём_
|
|
И зачем это не асме писать?
|
Не поверишь, но я знаю, что делаю. Наверное для меня скорость вычисления достаточно критична, раз я пошел на такой шаг.
Эти два вопроса - это помощь?
Последний раз редактировалось hubble; 28.07.2012 в 19:08.
|
|
|
|
28.07.2012, 19:21
|
|
|
Заблокирован
Регистрация: 31.12.2011
Сообщений: 726
Сказал спасибо: 32
Сказали Спасибо 223 раз(а) в 162 сообщении(ях)
|
Re: Помощь в WinAvr
А может есть повод заглянуть в HELP... на предмет What registers are used by the C compiler? ???
|
|
|
|
28.07.2012, 20:46
|
|
|
Гражданин KAZUS.RUN
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от hubble
|
|
Наверное для меня скорость вычисления достаточно критична, раз я пошел на такой шаг.
|
Может тогда просто отбросить младший байт, а умножать старший в uint16_t? Тогда умножение - одна команда.
|
|
|
|
28.07.2012, 21:29
|
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от _Артём_
|
|
Может тогда просто отбросить младший байт, а умножать старший в uint16_t? Тогда умножение - одна команда.
|
Спасибо, но не подойдет. Это уже пробовал. При сумме 500 чисел uint16_t без младшего разряда набегает приличная погрешность в старших разрядах. Не подходит. Если учитывать и младшие разряды, то погрешность только в них. Этого достаточно (вернее - это то, что смог выжать при произведении двух 16-ти битных чисел).
Последний раз редактировалось hubble; 28.07.2012 в 22:05.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:48.
|
|