Angelo 发表于 2014-2-28 17:57:36

给Arduino嵌入汇编语言,提高开方效率~

本帖最后由 Angelo 于 2014-2-28 18:00 编辑

前两天在做一个软件项目,里面需要用到很多的整数开方运算,即使Mega2560,跑起来也有点累。AVR库文件里面的确提供sqrt()这个函数用于开方,但是由于其为double类型,对于整数开方,很大的程度上浪费了资源。
之后自然而然的就想到了嵌入式汇编,找了一些相关的资料,供大家参考一下:


英文的教程,讲的比较细:http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
中文版教程,特别是其中的汇编语言支持章节:      http://www.chipart.cn/doc/caavrgccv.pdf
汇编代码的源头: http://members.chello.nl/j.beentjes3/Ruud/sqrt32avr.htm#Sqrt32R

最后上代码,实测速度为sqrt()的2.5倍,相当给力~~
#define Sqrt32(intRes, longIn1) \
asm volatile ( \
"ldi   R27,0xc0 \n\t" \
"clr   R26 \n\t" \
"ldi   %B0,0x40 \n\t" \
"sub   %A0,%A0\n\t" \
"_sq32_1%=:    brcs_sq32_2%= \n\t" \
"cp    %C1,%A0 \n\t" \
"cpc   %D1,%B0 \n\t" \
"brcs_sq32_3%= \n\t" \
"_sq32_2%=:    sub   %C1,%A0 \n\t" \
"sbc   %D1,%B0\n\t" \
"or    %A0,R26 \n\t" \
"or    %B0,R27 \n\t" \
"_sq32_3%=:    lsr   R27 \n\t" \
"ror   R26 \n\t" \
"eor   %B0,R27 \n\t" \
"eor   %A0,R26 \n\t" \
"rol   %A1 \n\t" \
"rol   %B1 \n\t" \
"rol   %C1 \n\t" \
"rol   %D1 \n\t" \
"sbrs%A1,0 \n\t" \
"rjmp_sq32_1%= \n\t" \
"brcs_sq32_4%= \n\t" \
"cp    %A0,%C1 \n\t" \
"cpc   %B0,%D1 \n\t" \
"brcc_sq32_5%= \n\t" \
"_sq32_4%=:    sbc   %B1,R27 \n\t" \
"sbc   %C1,%A0 \n\t" \
"sbc   %D1,%B0 \n\t" \
"inc   %A0 \n\t" \
"_sq32_5%=:    lsl   %B1 \n\t" \
"rol   %C1 \n\t" \
"rol   %D1 \n\t" \
"brcs_sq32_6%=\n\t" \
"cp    %A0,%C1 \n\t" \
"cpc   %B0,%D1 \n\t" \
"_sq32_6%=:    adc   %A0,R27 \n\t" \
"adc   %B0,R27 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (longIn1) \
: \
"r26" , "r27" \
)

int result;
unsigned long num;
int i;
unsigned long timer;

void setup() {
srandom(analogRead(0));
Serial.begin(115200);
}

void loop() {
num=random();
timer=millis();
for (i=0; i<1000; i++) {
//      result=sqrt(num);
Sqrt32(result, num);
}
timer=millis()-timer;
Serial.println(timer);
}





Holiday 发表于 2014-3-3 15:43:51

这么好的帖子,话说右斜杠的作用是什么。。。

Angelo 发表于 2014-3-3 16:47:00

Holiday 发表于 2014-3-3 15:43
这么好的帖子,话说右斜杠的作用是什么。。。

预编译如果要分行的话必须要下一个右斜杠~~

lisper 发表于 2014-3-4 00:14:01

AT&T格式的啊

Youyou 发表于 2014-3-4 00:48:40

Angelo 发表于 2014-3-3 16:47
预编译如果要分行的话必须要下一个右斜杠~~

是不是叫续行符?
貌似要求很严格的,后面连空格都不能有。

nemon 发表于 2014-3-4 08:35:46

\t 是做什么用的?

Angelo 发表于 2014-3-4 09:53:24

Youyou 发表于 2014-3-4 00:48
是不是叫续行符?
貌似要求很严格的,后面连空格都不能有。

对的,连注释都不行。。。这点很郁闷。。。
但是现在内联函数基本能够和宏定义的效率相当,但是碰到汇编就只能用宏了~

Angelo 发表于 2014-3-4 09:54:33

nemon 发表于 2014-3-4 08:35
\t 是做什么用的?

这个是“制表符”,内嵌汇编的标准格式~~

Holiday 发表于 2014-3-5 12:04:18

Uno上运行,54对18,好吊:lol:lol:lol

lauren 发表于 2014-3-5 18:04:43

我了个去的神贴啊。。。大师请教运算效率提高多少?

Angelo 发表于 2014-3-5 23:56:20

lauren 发表于 2014-3-5 18:04
我了个去的神贴啊。。。大师请教运算效率提高多少?
哥们儿~~
给我回去仔细看贴:curse:


Phoebe 发表于 2014-3-6 09:22:48

想当刚接触单片机,学汇编,真是头疼啊,感谢楼主分享:lol

Youyou 发表于 2014-3-6 09:53:42

看了楼主的帖子,想到刚刚接触51单片机时学的汇编语言,瞬间又激发起了对汇编的兴趣。
在需要高效率的场合,确实需要汇编啊!

Rockets 发表于 2014-3-6 15:21:08

和机器说话很累。
但机器能听懂人说话,干活很快

Grey 发表于 2014-3-12 10:13:39

汇编还能这么玩? 好帖,收下了

Youyou 发表于 2014-3-12 11:27:31

Grey 发表于 2014-3-12 10:13
汇编还能这么玩? 好帖,收下了

汇编玩的好了,程序可以写的很牛逼。是不是很怀念当时学51单片机时的汇编?
页: [1]
查看完整版本: 给Arduino嵌入汇编语言,提高开方效率~