历史上的今天
今天是:2025年01月06日(星期一)
2020年01月06日 | ARM 调用约定 calling convention
2020-01-06 来源:eefocus
int bar( int a, int b, int c, int d, int e, int f, int g )
{
int array2[ 7 ];
array2[ 0 ] = a + b;
array2[ 1 ] = b + c;
array2[ 2 ] = c + d;
array2[ 3 ] = d + e;
array2[ 4 ] = e + f;
array2[ 5 ] = f + g;
array2[ 6 ] = g + a;
return array2[ 0 ] + array2[ 1 ] + array2[ 2 ] + array2[ 3 ] + array2[ 4 ]
+ array2[ 5 ] + array2[ 6 ];
}
int foo( int a, int b, int c, int d, int e, int f, int g )
{
int array1[ 7 ];
array1[ 0 ] = a + b;
array1[ 1 ] = b + c;
array1[ 2 ] = c + d;
array1[ 3 ] = d + e;
array1[ 4 ] = e + f;
array1[ 5 ] = f + g;
array1[ 6 ] = g + a;
return bar( array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ], array1[ 4 ],
array1[ 5 ], array1[ 6 ] );
}
int func( int * buffer )
{
int a, b, c, d, e, f, g, h;
a = 1 + buffer[ 0 ];
b = 2 + buffer[ 1 ];
c = 3 + buffer[ 2 ];
d = 4 + buffer[ 3 ];
e = 5 + buffer[ 4 ];
f = 6 + buffer[ 5 ];
g = 7 + buffer[ 6 ];
h = foo( a, b, c, d, e, f, g );
return h;
}
int main( )
{
int array0[ 7 ];
array0[ 0 ] = 0;
array0[ 1 ] = 1;
array0[ 2 ] = 2;
array0[ 3 ] = 3;
array0[ 4 ] = 4;
array0[ 5 ] = 5;
array0[ 6 ] = 6;
while ( func( array0 ) )
{
}
}

int main( )
{
main:
0x8070252: 0xb500 PUSH {LR}
0x8070254: 0xb087 SUB SP, SP, #0x1c
array0[0] = 0;
0x8070256: 0x2000 MOVS R0, #0
0x8070258: 0x9000 STR R0, [SP]
array0[1] = 1;
0x807025a: 0x2001 MOVS R0, #1
0x807025c: 0x9001 STR R0, [SP, #0x4]
array0[2] = 2;
0x807025e: 0x2002 MOVS R0, #2
0x8070260: 0x9002 STR R0, [SP, #0x8]
array0[3] = 3;
0x8070262: 0x2003 MOVS R0, #3
0x8070264: 0x9003 STR R0, [SP, #0xc]
array0[4] = 4;
0x8070266: 0x2004 MOVS R0, #4
0x8070268: 0x9004 STR R0, [SP, #0x10]
array0[5] = 5;
0x807026a: 0x2005 MOVS R0, #5
0x807026c: 0x9005 STR R0, [SP, #0x14]
array0[6] = 6;
0x807026e: 0x2006 MOVS R0, #6
0x8070270: 0x9006 STR R0, [SP, #0x18]
while ( func(array0) )
??main_0:
0x8070272: 0xa800 ADD R0, SP, #0x0
0x8070274: 0xf7ff 0xffc3 BL func ; 0x80701fe
0x8070278: 0x2800 CMP R0, #0
0x807027a: 0xd1fa BNE.N ??main_0 ; 0x8070272
}


int main( )
{
main:
0x8070252: 0xb500 PUSH {LR}
0x8070254: 0xb087 SUB SP, SP, #0x1c
执行 PUSH {LR} 之前, SP = 0x20000400, 执行 PUSH {LR} 之后, LR 入栈, SP = 0x200003FC
接着执行 SUB SP, SP, #0x1c, 为局部变量分配空间 28 bytes, SP = 0x200003E0
0x8070272: 0xa800 ADD R0, SP, #0x0
0x8070274: 0xf7ff 0xffc3 BL func ; 0x80701fe
调用 func()
int func(int * buffer)
{
func:
0x80701fe: 0xe92d 0x4ff0 PUSH.W {R4-R11, LR}
0x8070202: 0xb085 SUB SP, SP, #0x14
0x8070204: 0x0004 MOVS R4, R0
... ... ... ...
h = foo(a, b, c, d, e, f, g);
PUSH .W {R4-R11, LR}, SUB SP, SP, #0x14, 保存寄存器, 为局部变量分配空间 a, 其他变量b,c,d,e,f,g 使用寄存器R5-R10
h 使用寄存器 R11 <图中没有显示>
同时分配3个变量的空间, 用于通过堆栈传递参数, 调用 foo(a, b, c, d, e, f, g)

h = foo(a, b, c, d, e, f, g);
0x8070230: 0xf8cd 0xa008 STR.W R10, [SP, #0x8] g
0x8070234: 0xf8cd 0x9004 STR.W R9, [SP, #0x4] f
0x8070238: 0xf8cd 0x8000 STR.W R8, [SP] e
0x807023c: 0x003b MOVS R3, R7 d
0x807023e: 0x0032 MOVS R2, R6 c
0x8070240: 0x0029 MOVS R1, R5 b
0x8070242: 0x9803 LDR R0, [SP, #0xc] a
0x8070244: 0xf7ff 0xffad BL foo ; 0x80701a2
0x8070248: 0x4683 MOV R11, R0
return h;
0x807024a: 0x4658 MOV R0, R11
0x807024c: 0xb005 ADD SP, SP, #0x14
0x807024e: 0xe8bd 0x8ff0 POP.W {R4-R11, PC}
foo(a, b, c, d, e, f, g) : a -> R0, b -> R1, c -> R2, d -> R3, e -> [SP, #0x00], f -> [SP, #0x04], e -> [SP, #0x08]

foo:
0x80701a2: 0xe92d 0x47f0 PUSH.W {R4-R10, LR}
0x80701a6: 0xb08a SUB SP, SP, #0x28
0x80701a8: 0x0004 MOVS R4, R0 a 通过寄存器传递
0x80701aa: 0x000d MOVS R5, R1 b 通过寄存器传递
0x80701ac: 0x0016 MOVS R6, R2 c 通过寄存器传递
0x80701ae: 0x001f MOVS R7, R3 d 通过寄存器传递
0x80701b0: 0xf8dd 0x8048 LDR.W R8, [SP, #0x48] e 通过堆栈传递
0x80701b4: 0xf8dd 0x904c LDR.W R9, [SP, #0x4c] f 通过堆栈传递
0x80701b8: 0xf8dd 0xa050 LDR.W R10, [SP, #0x50] g 通过堆栈传递
PUSH .W {R4-R10, LR}, SUB SP, SP, #0x28, 保存寄存器, 为局部变量分配空间 array1[7], 同时分配3个变量的空间, 用于通过堆栈传递参数, 调用
bar( array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ], array1[ 4 ], array1[ 5 ], array1[ 6 ] );
foo (a, b, c, d, e, f, g ) : a, b, c, d 通过寄存器传递, e, f, g 通过堆栈传递
获取参数, 运算之后, 存入局部变量 array1[7], 然后准备调用 bar()
array1[ 0 ], array1[ 1 ], array1[ 2 ], array1[ 3 ] 通过寄存器传递
array1[ 4 ], array1[ 5 ], array1[ 6 ] 通过堆栈传递
return bar( array1[0], array1[1], array1[2], array1[3], array1[4], array1[5], array1[6] );
0x80701e0: 0x9809 LDR R0, [SP, #0x24] array1[6]
0x80701e2: 0x9002 STR R0, [SP, #0x8]
0x80701e4: 0x9808 LDR R0, [SP, #0x20] array1[5]
0x80701e6: 0x9001 STR R0, [SP, #0x4]
0x80701e8: 0x9807 LDR R0, [SP, #0x1c] array1[4]
0x80701ea: 0x9000 STR R0, [SP]
0x80701ec: 0x9b06 LDR R3, [SP, #0x18] array1[3]
0x80701ee: 0x9a05 LDR R2, [SP, #0x14] array1[2]
0x80701f0: 0x9904 LDR R1, [SP, #0x10] array1[1]
0x80701f2: 0x9803 LDR R0, [SP, #0xc] array1[0]
0x80701f4: 0xf7ff 0xffa5 BL bar ; 0x8070142
0x80701f8: 0xb00a ADD SP, SP, #0x28
0x80701fa: 0xe8bd 0x87f0 POP.W {R4-R10, PC}

bar:
史海拾趣
|
section lma overlaps previous sections 大家好!最近因为某种原因,换了交叉编译工具链,以前是3.4.3,现在是4.2.3。 同样的源码,在编译应用程序模块时部分模块出现了类似如下的错误信息。 BFD: /home/***/HG553V100R001/targets/fs.src/bin/stALGP14: section .interp lma 0x4000f4 o ...… 查看全部问答> |
|
今天第一次发帖求助,有不恰当的地方,请各位见谅现在在做一个恒流源和恒压源,电流0-20MA,电压0-10V,分别有7个档位。我用LM124和2.5V基准源LM4140搭了一个,电压源没什么问题,但是恒流源接上公司的专用负载就会出现一个振铃,峰峰值大概300-400m ...… 查看全部问答> |
|
怎样才能实现一个串口接收数据 然后另一个串口发送接收到的数据 怎样才能在M3上实现从一个串口接收数据 然后再将接收到的数据从另一个串口发送出去 而且完全是由中断自动触发完成 本质即如何由一个串口的接收中断去触发另一个串口的发送中断呢 请大家抽空给点建议 谢谢~… 查看全部问答> |
|
想法是这样的:使用无线实现类似于以太网中的PTP时钟同步协议,想用zigbee来做无线收发部分。现在已经有了以太网转zigbee的产品,但是它的zigbee模块是整合在单芯片上的,那么就没法在类似于MII接口的接近硬件处取得数据。 所以,请问,有 ...… 查看全部问答> |
|
灵魂自行车的“心脏”——链条发电机及摩电发电机的原理 自行车骑行作为一项“绿色”环保的旅行方式,已经被越来越多的户外旅行爱好者所推崇。而在我的上一篇博文《把旅行变成修行--TI销售工程师的15天绿色环岛骑行梦》中也特别强调了这是 ...… 查看全部问答> |
|
作者:Chris Hossack 博士,德州仪器 (TI) Biricha 电源总监和 Richard Poley,TI 现场应用工程师 近几年,使用微处理器控制开关式电源不断发展。在数字电源相比模拟电源的优点方面仍存在许多争议,两大阵营你来我往、争论激烈。 实际上,每一种 ...… 查看全部问答> |
|
EEworld下载中心鼎力奉献--proteus教程专辑(二) 本帖最后由 tiankai001 于 2014-1-4 11:10 编辑 EEworld下载中心鼎力奉献--proteus教程专辑(二) 说明:上接《EEworld下载中心鼎力奉献--proteus教程专辑(一)》,由于EEWORLD下载中心关于proteus的教程资源实在是太丰富了,并且这些教程都各 ...… 查看全部问答> |




