首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

可变参数, 它依赖于堆栈-小话c语言(23)

2012-09-03 
可变参数, 它依赖于堆栈----小话c语言(23)作者:陈曦日期:2012-7-28 12:20:17 环境:[Mac 10.7.1 Lion Intel

可变参数, 它依赖于堆栈----小话c语言(23)

作者:陈曦

日期:2012-7-28 12:20:17 

环境:[Mac 10.7.1 Lion Intel i3 支持64位指令 gcc4.2.1 xcode4.2]  

转载请注明出处


Q1: 可变参数的函数调用能够被正确执行的本质原因是什么?

A: 可变参数的一个重要特点就是参数个数不确定,但是最终可以被正确执行一般需要堆栈以及参数类型的确定性支持。如果参数类型都无法确定是某种或者某个范围内,那么可变参数函数是无法实现的。


Q2: 举个可变参数的例子吧。

A: 比如,求一组整形数的平均数:

      get_average(2,  100,  1000),  第一个参数表示求平均数的整数个数为2个,后面跟着2个整数100和1000; 

       如果是求3个数的平均数,调用如下:

      get_average(2,  100, 1000,  200).

      代码如下:

0x0009276c <get_average+0>:subsp, #120x0009276e <get_average+2>:push{r4, r7, lr}0x00092770 <get_average+4>:addr7, sp, #40x00092772 <get_average+6>:subsp, #280x00092774 <get_average+8>:movr4, sp0x00092776 <get_average+10>:bic.wr4, r4, #7; 0x70x0009277a <get_average+14>:movsp, r40x0009277c <get_average+16>:strr3, [r7, #16]0x0009277e <get_average+18>:strr2, [r7, #12]0x00092780 <get_average+20>:strr1, [r7, #8]0x00092782 <get_average+22>:addr1, sp, #200x00092784 <get_average+24>:movsr2, #00x00092786 <get_average+26>:movtr2, #0; 0x00x0009278a <get_average+30>:vldrd16, [pc, #104]; 0x927f6 <get_average+138>0x0009278e <get_average+34>:strr0, [sp, #24]0x00092790 <get_average+36>:vstrd16, [sp, #8]0x00092794 <get_average+40>:ldrr0, [sp, #24]0x00092796 <get_average+42>:strr0, [sp, #4]0x00092798 <get_average+44>:add.wr0, r7, #8; 0x80x0009279c <get_average+48>:strr0, [r1, #0]0x0009279e <get_average+50>:strr2, [sp, #0]0x000927a0 <get_average+52>:movsr0, #00x000927a2 <get_average+54>:movtr0, #0; 0x00x000927a6 <get_average+58>:ldrr1, [sp, #24]0x000927a8 <get_average+60>:cmpr1, r00x000927aa <get_average+62>:ble.n0x927d2 <get_average+102>0x000927ac <get_average+64>:ldrr0, [sp, #20]0x000927ae <get_average+66>:addsr1, r0, #40x000927b0 <get_average+68>:strr1, [sp, #20]0x000927b2 <get_average+70>:ldrr0, [r0, #0]0x000927b4 <get_average+72>:fmsrs0, r00x000927b8 <get_average+76>:fsitodd16, s00x000927bc <get_average+80>:vldrd17, [sp, #8]0x000927c0 <get_average+84>:fadddd16, d17, d160x000927c4 <get_average+88>:vstrd16, [sp, #8]0x000927c8 <get_average+92>:ldrr0, [sp, #24]0x000927ca <get_average+94>:add.wr0, r0, #4294967295; 0xffffffff0x000927ce <get_average+98>:strr0, [sp, #24]0x000927d0 <get_average+100>:b.n0x927a0 <get_average+52>0x000927d2 <get_average+102>:vldrd16, [sp, #8]0x000927d6 <get_average+106>:fldss0, [sp, #4]0x000927da <get_average+110>:fsitodd17, s00x000927de <get_average+114>:fdivdd16, d16, d170x000927e2 <get_average+118>:vmovr0, r1, d160x000927e6 <get_average+122>:subsr4, r7, #40x000927e8 <get_average+124>:movsp, r40x000927ea <get_average+126>:ldmia.wsp!, {r4, r7, lr}0x000927ee <get_average+130>:addsp, #120x000927f0 <get_average+132>:bxlr0x000927f2 <get_average+134>:nop0x000927f4 <get_average+136>:lslsr0, r0, #00x000927f6 <get_average+138>:lslsr0, r0, #00x000927f8 <get_average+140>:lslsr0, r0, #00x000927fa <get_average+142>:lslsr0, r0, #0

在这里,我们可以看到,里面使用了堆栈寄存器sp,并从sp相关的内存中取参数操作,可以确定,依然采用堆栈方式传递参数的。


一些看起来动态的东西,在c语言那里是使用较为静态的东西来实现。


作者:陈曦

日期:2012-7-28 12:20:17 

环境:[Mac 10.7.1 Lion Intel i3 支持64位指令 gcc4.2.1 xcode4.2]  

转载请注明出处


    

热点排行