18598浏览
查看: 18598|回复: 15

给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倍,相当给力~~
  1. #define Sqrt32(intRes, longIn1) \
  2. asm volatile ( \
  3. "ldi   R27,0xc0 \n\t" \
  4. "clr   R26 \n\t" \
  5. "ldi   %B0,0x40 \n\t" \
  6. "sub   %A0,%A0  \n\t" \
  7. "_sq32_1%=:    brcs  _sq32_2%= \n\t" \
  8. "cp    %C1,%A0 \n\t" \
  9. "cpc   %D1,%B0 \n\t" \
  10. "brcs  _sq32_3%= \n\t" \
  11. "_sq32_2%=:    sub   %C1,%A0 \n\t" \
  12. "sbc   %D1,%B0  \n\t" \
  13. "or    %A0,R26 \n\t" \
  14. "or    %B0,R27 \n\t" \
  15. "_sq32_3%=:    lsr   R27 \n\t" \
  16. "ror   R26 \n\t" \
  17. "eor   %B0,R27 \n\t" \
  18. "eor   %A0,R26 \n\t" \
  19. "rol   %A1 \n\t" \
  20. "rol   %B1 \n\t" \
  21. "rol   %C1 \n\t" \
  22. "rol   %D1 \n\t" \
  23. "sbrs  %A1,0 \n\t" \
  24. "rjmp  _sq32_1%= \n\t" \
  25. "brcs  _sq32_4%= \n\t" \
  26. "cp    %A0,%C1 \n\t" \
  27. "cpc   %B0,%D1 \n\t" \
  28. "brcc  _sq32_5%= \n\t" \
  29. "_sq32_4%=:    sbc   %B1,R27 \n\t" \
  30. "sbc   %C1,%A0 \n\t" \
  31. "sbc   %D1,%B0 \n\t" \
  32. "inc   %A0 \n\t" \
  33. "_sq32_5%=:    lsl   %B1 \n\t" \
  34. "rol   %C1 \n\t" \
  35. "rol   %D1 \n\t" \
  36. "brcs  _sq32_6%=  \n\t" \
  37. "cp    %A0,%C1 \n\t" \
  38. "cpc   %B0,%D1 \n\t" \
  39. "_sq32_6%=:    adc   %A0,R27 \n\t" \
  40. "adc   %B0,R27 \n\t" \
  41. : \
  42. "=&r" (intRes) \
  43. : \
  44. "d" (longIn1) \
  45. : \
  46. "r26" , "r27" \
  47. )
  48. int result;
  49. unsigned long num;
  50. int i;
  51. unsigned long timer;
  52. void setup() {
  53.   srandom(analogRead(0));
  54.   Serial.begin(115200);
  55. }
  56. void loop() {
  57.   num=random();
  58.   timer=millis();
  59.   for (i=0; i<1000; i++) {
  60. //      result=sqrt(num);
  61.   Sqrt32(result, num);
  62.   }
  63.   timer=millis()-timer;
  64.   Serial.println(timer);
  65. }
复制代码




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  NPC

发表于 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单片机时的汇编?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail