use*_*143 20 c linux recursion gcc
在/ prog /上找到了这个.我实际上是GDB它,是的,它确实是一个递归.但它是如何发生的?
// This works on 32-bit x86 Linux with gcc as long as you don't enable optimization.
#include <stdio.h>
#include <stdlib.h>
static void factorial(int in, int *out)
{
*(&in-1)-=5-5*(1/in);
*out*=in--;
}
int main(int argc, char **argv)
{
int result=1;
int number=0;
if (argc!=2)
exit(1);
number=atoi(argv[1]);
if (number<1)
exit(2);
factorial(number, &result);
printf("%d! = %d\n", number, result);
return 0;
}
$ ./factorial 3
3! = 6
$ ./factorial 5
5! = 120
Run Code Online (Sandbox Code Playgroud)
Mar*_*n B 22
甜.;)
这是非常不可移植的代码,仅适用于x86.它正在做的是更改堆栈上的返回地址,以便if in>1,函数不返回指令后面的call指令,而是返回调用指令本身.x86上的调用指令是五个字节(一个操作码加上调用目标的4字节地址),因此需要从返回地址中减去五个字节.
这个
*(&in-1)-=5-5*(1/in);
Run Code Online (Sandbox Code Playgroud)
只是一种混淆的说法
if(in>1)
*(&in-1)-=5;
Run Code Online (Sandbox Code Playgroud)
并且&in-1是返回地址存在于堆栈中的位置.
它破坏了堆栈上的返回地址,导致递归发生.
*(&in-1)-=5-5*(1/in);
Run Code Online (Sandbox Code Playgroud)
&in-1可能是推送的返回地址.其余的只是令人不快的魔力.
| 归档时间: |
|
| 查看次数: |
901 次 |
| 最近记录: |