runaway深度递归函数测试及相关汇编指令

这是一个深度递归的例子。 

#include <stdio.h>
#include <stdlib.h>

int recurse(int x) {
    int a[1<<15];  /* 4 * 2^15 =  64 KiB */
    printf("x = %d.  a at %p\n", x, a); 
    a[0] = (1<<14)-1;
    a[a[0]] = x-1;
    if (a[a[0]] == 0)
	return -1;
    return recurse(a[a[0]]) - 1;
}

int main(int argc, char *argv[]) {
    int x = 100;
    if (argc > 1)
	x = atoi(argv[1]);
    int v = recurse(x);
    printf("x = %d.  recurse(x) = %d\n", x, v);
    return 0;
}
1<<15

无符号数a的左移相当于将该数用二进制表示,左移n位就是把最高位n位移出,低位添加n个0的操作,左移操作相当于将该数乘以2^n次方。
无符号数a的左移相当于将该数用二进制表示,右移n位就是把低位n位移出,高位添加n个0的操作,右移操作相当于将该数除以2^n次方。
注意:上述两种操作对于有符号数不满足,因为有符号数最高位为符号位,进行左移或右移操作会使改变数的符号。
 

简单来说:

左移,后空缺自动补0;

右移,分为逻辑右移和算数右移

1)逻辑右移 不管是什么类型,空缺自动补0;

2)算数右移 若是无符号数,则空缺补0,若是负数,空缺补1;

 

int a[1<<15];  /* 4 * 2^15 =  64 KiB */

 因为int整数型占4bytes,所以int a[1<<15]数组的大小为:4*2^15=64*2^10B=64KB

 

存储容量:是该存储设备上可以存储数据的最大数量,通常使用千字节(kb kilobyte)、兆字节(MB megabyte)、吉字节(GB, gigabyte)、太字节(TB ,terabyte)和PB(Petabyte)、EB(Exabyte)等来衡量。 
1KB=2(10)B=1024B; 括号中的数字为2的指数(即多少次方) 
1MB=2(10)KB=1024KB=2(20)B; 
1GB=2(10)MB=1024MB=2(30)B。 
1TB=2(10) GB=1024GB=2(40)B 
1PB=2(10) TB=1024TB=2(50)B 
1EB=2(10) PB=1024PB=2(60)B 
1Byte(相当於一个英文字母,您的名字相当6Bytes(6B)。 
Kilobyte(KB)=1024B相当於一则短篇故事的内容。 
Megabyte(MB)=l024KB相当於一则短篇小说的文字内容。 
Gigabyte(GB)=1024MB相当於贝多芬第五乐章交响曲的乐谱内容。 
Terabyte(TB)=1024GB相当於一家大型医院中所有的X光图片资讯量。 
Petabyte(PB)=l024TB相当於50%的全美学术研究图书馆藏书资讯内容。 
Exabyte (EB)=1024PB;5EB相当於至今全世界人类所讲过的话语。 
Zettabyte(ZB)=1024EB如同全世界海滩上的沙子数量总和。 
Yottabyte(YB)=1024ZB相当於7000位人类体内的微细胞总和。

printf("x = %d.  a at %p\n", x, a); 

 打印输出x的大小和它的地址

a[0] = (1<<14)-1;

对于二维数组a[3][3]中a,&a,a[0],&a[0],&a[0][0]的区别和含义

if (a[a[0]] == 0)
	return -1;

 递归函数结束的满足条件,即出口。

 return recurse(a[a[0]]) - 1;

  表示不断进行递归调用

int main(int argc, char *argv[])

 第一个int argc,是记录你输入在命令行上的字符串个数;
第二个*argv[]是个指针数组,存放输入在命令行上的命令(字符串)。

x = atoi(argv[1]);

将字符串转为int型。

atof:将……转成float型;atoi:字符串转成int型;atol:将……转成long型

 

./runaway 不带参数
./runaway 20

 

根据运行结果分析可知,当最后栈的分配到达最大值时,就会发生段错误,致使程序异常终止。因此,此程序可用来判断栈空间的大小。

 思考练习以下命令:
 -d:将代码段反汇编
-S:将代码段反汇编的同时,将反汇编代码和源代码交替显示,编译时需要给出-g,即需要调试信息。
-l:反汇编代码中插入源代码的文件名和行号。
-j section:仅反汇编指定的section。可以有多个-j参数来选择多个section。

 objdump -d a.out # 简单反汇编
 objdump -S a.out # 反汇编代码中混入对应的源代码
 objdump -j .text -l -S a.out # 打印源文件名和行号 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值