我想对我系统上不同机器指令使用的循环次数进行基准测试(对于此示例,它是ARM Cortex-M4)。所以我使用一个宏,它重复多次目标指令,在此之前和之后,我读取了控制器的循环计数器。在asm-dump中,我看到在某个位置,const数据(我的循环计数器寄存器的地址)被填入(位置8003140到8003150,标有">"):
08002d58 <testThis>:
8002d58: 48fa ldr r0, [pc, #1000] ; (8003144 <testThis+0x3ec>)
8002d5a: 49fb ldr r1, [pc, #1004] ; (8003148 <testThis+0x3f0>)
8002d5c: 4bfb ldr r3, [pc, #1004] ; (800314c <testThis+0x3f4>)
8002d5e: 4afc ldr r2, [pc, #1008] ; (8003150 <testThis+0x3f8>)
8002d60: 6800 ldr r0, [r0, #0]
8002d62: 6008 str r0, [r1, #0]
8002d64: 681b ldr r3, [r3, #0]
8002d66: 6812 ldr r2, [r2, #0]
8002d68: fa82 f183 qadd r1, r3, r2
8002d6c: fa82 f183 qadd r1, r3, r2
..
8003138: fa82 f183 qadd r1, r3, r2
800313c: fa82 f183 qadd r1, r3, r2
> 8003140: e008 b.n 8003154 <testThis+0x3fc>
> 8003142: bf00 nop
> 8003144: e0001004 .word 0xe0001004
> 8003148: 20000598 .word 0x20000598
> 800314c: 20000594 .word 0x20000594
> 8003150: 200002e4 .word 0x200002e4
8003154: fa82 f183 qadd r1, r3, r2
8003158: fa82 f183 qadd r1, r3, r2
..
8003b84: fa82 f183 qadd r1, r3, r2
8003b88: fa82 f383 qadd r3, r3, r2
8003b8c: 4803 ldr r0, [pc, #12] ; (8003b9c <testThis+0xe44>)
8003b8e: 4904 ldr r1, [pc, #16] ; (8003ba0 <testThis+0xe48>)
8003b90: 6003 str r3, [r0, #0]
8003b92: 4b04 ldr r3, [pc, #16] ; (8003ba4 <testThis+0xe4c>)
8003b94: 680a ldr r2, [r1, #0]
8003b96: 601a str r2, [r3, #0]
8003b98: 4770 bx lr
8003b9a: bf00 nop
8003b9c: 2000058c .word 0x2000058c
8003ba0: e0001004 .word 0xe0001004
8003ba4: 20000338 .word 0x20000338
为什么一开始没有填写? 我能控制住这个吗?
GCC版本:
gcc版本4.8.3 20140228(发布)[ARM / embedded-4_8-branch revision 208322]
C代码:
#define READCYCCNT() *((volatile unsigned int *)0xE0001004)
uint32_t cyc_begin, cyc_end;
int c, a, b;
void testThis(void *obj)
{
cyc_begin = READCYCCNT();
REP(9,0,0, c, __QADD, a, b);
cyc_end = READCYCCNT();
}
REP-macro有点冗长。它只增加了900次调用
c = __QADD(a,b)
编译器调用:
arm-atollic-eabi-gcc -c -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -std=gnu90 -DDEBUG=1 -I../Inc -I../CoreSupport -I../DeviceSupport -Ofast -ffunction-sections -fdata-sections -g -Wall -o Application\Main.o ..\Application\Main.c
答案 0 :(得分:1)
编译器使用ldr指令生成代码,并使用相对于PC的寻址。这些指令只有5位来存储相对地址,因此它们只能访问当前程序计数器位置0-124字范围内的数据。这就是编译器将数据放在代码中间的原因。这是quick reference card的拇指说明。
有几种方法可以避免这种情况。您可以通过使用不同寻址模式的手写程序集替换宏。您可以用常量替换变量,并完全避免寻址。您可以减少调用宏的次数。您可以删除-mthumb标志以生成32位指令,这些指令具有更多用于寻址的位。这实际上取决于您希望通过测试评估的内容。