c - 为 Cortex-M0 优化 C 或汇编代码的大小

标签 c optimization cortex-m

我需要减少 Cortex-M0 微处理器的代码膨胀。

在启动时,必须将 ROM 数据复制到 RAM 数据一次。因此我有这段代码:

void __startup( void ){
  extern unsigned int __data_init_start;
  extern unsigned int __data_start;
  extern unsigned int __data_end;

  // copy .data section from flash to ram
  s = & __data_init_start;
  d = & __data_start;
  e = & __data_end;
  while( d != e ){ 
    *d++ = *s++;
  }
}

编译器生成的汇编代码如下所示:

  ldr   r1, .L10+8
  ldr   r2, .L10+12
  sub   r0, r1, r2
  lsr   r3, r0, #2
  add   r3, r3, #1
  lsl   r1, r3, #2
  mov   r3, #0
.L4:
  add   r3, r3, #4
  cmp   r3, r1
  beq   .L9
.L5:
  ldr   r4, .L10+16
  add   r0, r2, r3
  add   r4, r3, r4
  sub   r4, r4, #4
  ldr   r4, [r4]
  sub   r0, r0, #4
  str   r4, [r0]
  b .L4

如何优化此代码以使代码大小最小化?

最佳答案

编译器(或您!)没有意识到要复制的范围是end - start。似乎正在进行一些不必要的数据改组——循环中的 2 addsub。此外,在我看来,编译器确保要制作的副本数是 4 的倍数。然后,一个明显的优化是确保它是提前的!下面我假设它是(如果不是,bne 将失败并愉快地继续复制和践踏你的内存)。

使用我十年前的 ARM 汇编程序知识(是的,这是一个主要的免责声明)和后递增,我认为可以将其浓缩为以下简短片段。从 18 条指令减少到 8 条,还不错。如果有效。

  ldr   r1, __data_init_start
  ldr   r2, __data_start
  ldr   r3, __data_end
  sub   r4, r3, r2
.L1:
  ldr   r3, [r1], #4  ; safe to re-use r3 here
  str   r3, [r2], #4
  subs  r4, r4, #4
  bne   L1

关于c - 为 Cortex-M0 优化 C 或汇编代码的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27876416/

相关文章:

c - C中图形的一些链接

objective-c - 您可以从枚举元素的数值访问实际标识符吗?

自定义输入函数,奇怪的 '?'附加在字符串的末尾

javascript - 如何延迟加载 CSS 背景图片?

javascript - 隐藏与删除 DOM 元素

c - 混合 C 和 ASM,皮质 M4

STM32F4 (Cortex-M4) 上的 Ada

PHP处理大字符串

MySql 查询不使用索引集

ld - 如何使用 GNU ld 创建一个空部分?