您的位置:首页 > 职场人生

一道嵌入式工程师面试题

2009-07-30 09:01 295 查看
嵌入式领域要有的软件意识
1. 你熟悉你所用的编译器吗?
比如说,做division 和modulus 运算时,怎么写效率足以高。
例:

对于ARMCC编译器就有以下结果:
typedef struct {
int x;
int y;
} point;
point getxy_v1(unsigned int offset, unsigned int bytes_per_line)
{
point p;
p.y = offset / bytes_per_line;
p.x = offset - p.y * bytes_per_line;
return p;
}
It appears that we have saved a division by using a subtract and multiply to calculate p.x,
but in fact, it is often more efficient to write the function with the modulus or remainder
operation.
point getxy_v2(unsigned int offset, unsigned int bytes_per_line)
{
point p;
p.x = offset % bytes_per_line;
p.y = offset / bytes_per_line;
return p;
}
There is only one division call here, as you can see in the following compiler output. In
fact, this version is four instructions shorter than getxy_v1. Note that this may not be the
case for all compilers and C libraries.
getxy_v2
STMFD r13!,{r4, r14} ; stack r4, lr
MOV r4,r0 ; move p to r4
MOV r0,r2 ; r0 = bytes_per_line
BL __rt_udiv ; (r0,r1) = (r1/r0, r1%r0)
STR r0,[r4,#4] ; p.y = offset / bytes_per_line
STR r1,[r4,#0] ; p.x = offset % bytes_per_line
LDMFD r13!,{r4,pc} ; return ■

对于IAR ARM 4.41A就没有这个功能,它的结果是:
typedef struct {
int x;
int y;
} point;
point getxy_v2(unsigned int offset, unsigned int bytes_per_line)
{
point p;
p.x = offset % bytes_per_line;
p.y = offset / bytes_per_line;
return p;
}

point getxy_v2(unsigned int offset, unsigned int bytes_per_line)
{

/ 00000000 30402DE9 PUSH {R4,R5,LR}
/ 00000004 08D04DE2 SUB SP,SP,#+8
/ 00000008 0030B0E1 MOVS R3,R0
/ 0000000C 0140B0E1 MOVS R4,R1
24 point p;
25 p.x = offset % bytes_per_line;
/ 00000010 0400B0E1 MOVS R0,R4
/ 00000014 0210B0E1 MOVS R1,R2
/ 00000018 ........ _BLF ??divu32_a,??rA??divu32_a
/ 0000001C 00008DE5 STR R0,[SP, #+0]
26 p.y = offset / bytes_per_line;
/ 00000020 0400B0E1 MOVS R0,R4
/ 00000024 0210B0E1 MOVS R1,R2
/ 00000028 ........ _BLF ??divu32_a,??rA??divu32_a
/ 0000002C 04108DE5 STR R1,[SP, #+4]
27 return p;
/ 00000030 0D00B0E1 MOVS R0,SP
/ 00000034 030090E8 LDM R0,{R0,R1}
/ 00000038 030083E8 STM R3,{R0,R1}
/ 0000003C 0300B0E1 MOVS R0,R3
/ 00000040 08D08DE2 ADD SP,SP,#+8 ;; stack cleaning
/ 00000044 3040BDE8 POP {R4,R5,LR}
/ 00000048 1EFF2FE1 BX LR ;; return
28 }
IAR用的是GCC编译器,所以同样的代码产生出来的结果就不一样!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: