花样繁多:函数到底能怎么返回值?

eax返回值不假,但是eax 不就4个字节吗,各种代码通过eax返回时到底有多少花样? have a try:

1、 long long
f1.png

Dump of assembler code for function fun():
=> 0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
   0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

edx小伙加入了。

2、 真 long long。

事实上又拉了一个战友过来
f2.png

->->post-prompt
Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
=> 0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)  <==注意这里
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

->->pre-prompt
(gdb) 
->->prompt

->->post-prompt
Dump of assembler code for function fun():
   0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

3、 超long long long long
ecx参战的感觉。
f33.png

用Intel的吧,大家也方便看一点

fun():
   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0xc
=> 0x00401506 <+6>: mov    eax,0xab33bc40
   0x0040150b <+11>:    mov    edx,0x89119a22
   0x00401510 <+16>:    mov    ecx,0x403b
   0x00401515 <+21>:    mov    DWORD PTR [ebp-0xc],eax
   0x00401518 <+24>:    mov    DWORD PTR [ebp-0x8],edx
   0x0040151b <+27>:    mov    DWORD PTR [ebp-0x4],ecx
   0x0040151e <+30>:    fld    TBYTE PTR [ebp-0xc]
   0x00401521 <+33>:    leave  
   0x00401522 <+34>:    ret    

4、 真· 超long long long long
f4.png

long128构造函数:

   0x00415fb0 <+0>: push   ebp
   0x00415fb1 <+1>: mov    ebp,esp
   0x00415fb3 <+3>: sub    esp,0x18
   0x00415fb6 <+6>: mov    DWORD PTR [ebp-0x4],ecx
   0x00415fb9 <+9>: mov    eax,DWORD PTR [ebp+0x8]
   0x00415fbc <+12>:    mov    DWORD PTR [ebp-0x10],eax
   0x00415fbf <+15>:    mov    eax,DWORD PTR [ebp+0xc]
   0x00415fc2 <+18>:    mov    DWORD PTR [ebp-0xc],eax
   0x00415fc5 <+21>:    mov    eax,DWORD PTR [ebp+0x10]
   0x00415fc8 <+24>:    mov    DWORD PTR [ebp-0x18],eax
   0x00415fcb <+27>:    mov    eax,DWORD PTR [ebp+0x14]
   0x00415fce <+30>:    mov    DWORD PTR [ebp-0x14],eax
   0x00415fd1 <+33>:    mov    ecx,DWORD PTR [ebp-0x4]  <== this
   0x00415fd4 <+36>:    mov    eax,DWORD PTR [ebp-0x10]
   0x00415fd7 <+39>:    mov    edx,DWORD PTR [ebp-0xc]
   0x00415fda <+42>:    mov    DWORD PTR [ecx],eax      <== eax, edx合起来就是一个long long
   0x00415fdc <+44>:    mov    DWORD PTR [ecx+0x4],edx
   0x00415fdf <+47>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x00415fe2 <+50>:    mov    eax,DWORD PTR [ebp-0x18]
   0x00415fe5 <+53>:    mov    edx,DWORD PTR [ebp-0x14]
   0x00415fe8 <+56>:    mov    DWORD PTR [ecx+0x8],eax   <== 同上,另一个赋值操作
   0x00415feb <+59>:    mov    DWORD PTR [ecx+0xc],edx
=> 0x00415fee <+62>:    leave  
   0x00415fef <+63>:    ret    0x10

fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0x10 <==本地的缓冲区
   0x00401506 <+6>: mov    DWORD PTR [esp+0x8],0x44332211
   0x0040150e <+14>:    mov    DWORD PTR [esp+0xc],0x88776655
   0x00401516 <+22>:    mov    DWORD PTR [esp],0x55667788
   0x0040151d <+29>:    mov    DWORD PTR [esp+0x4],0x11223344  <==把这几个倒霉数字存进去
   0x00401525 <+37>:    mov    ecx,DWORD PTR [ebp+0x8] <==ebp+0x8,这个临时的long128变量地址
   0x00401528 <+40>:    call   0x415fb0 <long128::long128(long long, long long)>
   0x0040152d <+45>:    sub    esp,0x10  <==栈上的缓冲区释放掉
=> 0x00401530 <+48>:    mov    eax,DWORD PTR [ebp+0x8]   <==变量的地址返回eax……
   0x00401533 <+51>:    leave  
   0x00401534 <+52>:    ret    

main():

   0x00401535 <+0>: push   ebp
   0x00401536 <+1>: mov    ebp,esp
   0x00401538 <+3>: and    esp,0xfffffff0
   0x0040153b <+6>: sub    esp,0x20
   0x0040153e <+9>: call   0x409680 <__main>
   0x00401543 <+14>:    lea    eax,[esp+0x10] <==long128的内存
   0x00401547 <+18>:    mov    DWORD PTR [esp],eax
   0x0040154a <+21>:    call   0x401500 <fun()> <==别忘了这时候已经赋值给long128 tempA了
=> 0x0040154f <+26>:    mov    eax,0x0  <== return 0;
   0x00401554 <+31>:    leave  
   0x00401555 <+32>:    ret    

call = push + jmp,

esp => [ EAX ]

aftercall:

esp =>  [ retnaddr ]
        [   EAX    ]

1st instruction:

esp =>  [   ebp    ] 
        [ retnaddr ]
        [   EAX    ]  <= esp+8

上一层预留空间了,学会废物利用了。

5、假·超long long long long
f5.png
fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
=> 0x00401503 <+3>: mov    eax,DWORD PTR [ebp+0x8] <==long128的地址
   0x00401506 <+6>: mov    DWORD PTR [eax],0x55667788  <==第一次赋值
   0x0040150c <+12>:    mov    DWORD PTR [eax+0x4],0x11223344
   0x00401513 <+19>:    mov    eax,DWORD PTR [ebp+0x8] 
   0x00401516 <+22>:    mov    DWORD PTR [eax+0x8],0x44332211 <==第二次赋值
   0x0040151d <+29>:    mov    DWORD PTR [eax+0xc],0x88776655
   0x00401524 <+36>:    nop
   0x00401525 <+37>:    mov    eax,DWORD PTR [ebp+0x8]
   0x00401528 <+40>:    pop    ebp
   0x00401529 <+41>:    ret    

main():

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409670 <__main>
   0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
=> 0x00401544 <+26>:    mov    eax,0x0
   0x00401549 <+31>:    leave  
   0x0040154a <+32>:    ret    

看来跟之前一样。

6、 terminated
多加一句varA.h1++;

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409680 <__main>
=> 0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
   0x00401544 <+26>:    mov    eax,DWORD PTR [esp+0x10]
   0x00401548 <+30>:    mov    edx,DWORD PTR [esp+0x14]
   0x0040154c <+34>:    add    eax,0x1
   0x0040154f <+37>:    adc    edx,0x0
   0x00401552 <+40>:    mov    DWORD PTR [esp+0x10],eax
   0x00401556 <+44>:    mov    DWORD PTR [esp+0x14],edx
   0x0040155a <+48>:    mov    eax,0x0
   0x0040155f <+53>:    leave  
   0x00401560 <+54>:    ret    

ok done.有空再研究研究其他的。

标签:none

添加新评论

captcha
请输入验证码