MIT 6.828 JOS学习笔记8. Exercise 1.4
Lab 1 Exercise 4
阅读关于C语言的指针部分的知识。最好的参考书自然是"The C Programming Language"。
阅读5.1到5.5节。然后下载pointers.c的代码,并且编译运行它,确保你理解在屏幕上打印出来的所有的值是怎么来的。尤其要重点理解第1行,第6行的指针地址是如何得到的,以及在第2行到第4行的值是如何得到的,还有为什么在第5行打印出来的值看起来像程序崩溃了。
答:
首先编译运行文件pointer.c,得到如下结果:

首先程序声明了3个重要的数组,指针
int型数组--int a[4]; int类型指针--int *b = malloc(16); int类型指针--int *c;
打印的第一句:
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
其中:
a输出的是数组a的首地址,0xbfb4bf84。
b输出的是指针b所指向的操作系统分配给它的空间的起始地址,0x8886008
c输出的是未定义的指针变量c的值,0xb75d8255
打印第二句之前,完成的操作:
c = a; 让c指针和a指向同一个内存地址,0xbfb4bf84;
for(i = 0; i<4; i++) a[i] = 100+i; 这个操作会让数组a的四个单元的值变为,100,101,102,103。
c[0] = 200; 由于c和a指向同一个地方,c[0] = a[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d,", a[0], a[1], a[2], a[3]); 所以打印第二句,第一个元素的值会是200.
打印第三句之前,完成操作:
c[1] = 300;
*(c+2) = 301;
3[c] = 302;
分别代表访问数组中的值的三种不同的方法。由于c和a相同,所以它们也是在修改数组a的值。把a[1], a[2],a[3]全都被改变。printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d,", a[0], a[1], a[2], a[3]);
打印第四句前,完成操作:c = c+1;
将指针c指向数组中下一个单元,即a[1]
*c = 400
修该a[1]值为400
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d,", a[0], a[1], a[2], a[3]);
打印第五句前,完成操作
c = (int *)((char *)c + 1);
先把c强制转换为char类型指针,然后指针加1,此时c的数值应该也加1,由于之前c指向a数组中1号元素的起始地址,1号元素起始地址为0xbfb4bf88,之后加1,变为0xbfb4bf89。然后再把c强制转换回int类型指针,此时c所操作的地址为0xbfb4bf89~0xbfb4bf8c。
*c = 500
把地址地址为0xbfb4bf89~0xbfb4bf8c的值换为500,此时会影响原来数组a的1,2号元素。原来一号元素在内存中存放在地址0xbfb4bf88~0xbfb4bf8b处,存放的值为400,十六进制为0x00000190
0xbfb4bf88 0xbfb4bf89 0xbfb4bf8a 0xbfb4bf8b
90 01 00 00
原来二号元素在内存中存放在地址0xbfb4bf8c~0xbfb4bf8f处,存放的值为301,十六进制为0x0000012D。
0xbfb4bf8c 0xbfb4bf8d 0xbfb4bf8e 0xbfb4bf8f
2D 01 00 00
而现在c操作的地址为0xbfb4bf89~0xbfb4bf8c,并赋值500,十六进制为0x000001F4,所以内存单元变为
0xbfb4bf88 0xbfb4bf89 0xbfb4bf8a 0xbfb4bf8b
90 F4 01 00
0xbfb4bf8c 0xbfb4bf8d 0xbfb4bf8e 0xbfb4bf8f
00 01 00 00
所以此时a[1]的值变为0x0001F490 = 128144, a[2]的值变为0x00000100 = 256.
打印第六句前,完成操作:
b = (int *)a + 1;
这步操作会把b的值加1,由于b现在是int类型指针,所以数值上b的值增加4,所以b的值变为 0xbfb4bf84 + 0x4 = 0xbfb4bf88
c = (int *)((char *)a+1);
这步还是先把a转换为char型指针,然后加1,此时加1会让数值上只增加1,所以c的值变为 0xbfb4bf84 + 0x1 = 0xbfb4bf85
当然运行在你的机器上,这些地址的值一定和我的不一样,但是原理是相同的。
MIT 6.828 JOS学习笔记8. Exercise 1.4的更多相关文章
- MIT 6.828 JOS学习笔记11 Exercise 1.8
Exercise 1.8 我们丢弃了一小部分代码---即当我们在printf中指定输出"%o"格式的字符串,即八进制格式的代码.尝试去完成这部分程序. 解答: 在这个练 ...
- MIT 6.828 JOS学习笔记12 Exercise 1.9
Lab 1中Exercise 9的解答报告 Exercise 1.9: 判断一下操作系统内核是从哪条指令开始初始化它的堆栈空间的,以及这个堆栈坐落在内存的哪个地方?内核是如何给它的堆栈保留一块内存空间 ...
- MIT 6.828 JOS学习笔记13 Exercise 1.10
Lab 1 Exercise 10 为了能够更好的了解在x86上的C程序调用过程的细节,我们首先找到在obj/kern/kern.asm中test_backtrace子程序的地址, 设置断点,并且探讨 ...
- MIT 6.828 JOS学习笔记9. Exercise 1.5
Lab 1 Exercise 5 再一次追踪一下boot loader的一开始的几句指令,找到第一条满足如下条件的指令处: 当我修改了boot loader的链接地址,这个指令就会出现错误. 找到这样 ...
- MIT 6.828 JOS学习笔记5. Exercise 1.3
Lab 1 Exercise 3 设置一个断点在地址0x7c00处,这是boot sector被加载的位置.然后让程序继续运行直到这个断点.跟踪/boot/boot.S文件的每一条指令,同时使用boo ...
- MIT 6.828 JOS学习笔记3. Exercise 1.2
这篇博文是对Lab 1中的Exercise 2的解答~ Lab 1 Exercise 2: 使用GDB的'si'命令,去追踪ROM BIOS几条指令,并且试图去猜测,它是在做什么.但是不需要把每个细节 ...
- MIT 6.828 JOS学习笔记2. Lab 1 Part 1.2: PC bootstrap
Lab 1 Part 1: PC bootstrap 我们继续~ PC机的物理地址空间 这一节我们将深入的探究到底PC是如何启动的.首先我们看一下通常一个PC的物理地址空间是如何布局的: ...
- MIT 6.828 JOS学习笔记0. 写在前面的话
0. 简介 操作系统是计算机科学中十分重要的一门基础学科,是一名计算机专业毕业生必须要具备的基础知识.但是在学习这门课时,如果仅仅把目光停留在课本上一些关于操作系统概念上的叙述,并不能对操作系统有着深 ...
- MIT 6.828 JOS学习笔记7. Lab 1 Part 2.2: The Boot Loader
Lab 1 Part 2 The Boot Loader Loading the Kernel 我们现在可以进一步的讨论一下boot loader中的C语言的部分,即boot/main.c.但是在我们 ...
随机推荐
- 多视图学习(multiview learning)
多视图学习(multi-view learning) 前期吹牛:今天这一章我们就是来吹牛的,刚开始老板在和我说什么叫多视图学习的时候,我的脑海中是这么理解的:我们在欣赏妹子福利照片的时候,不能只看45 ...
- .Net 中的反射(查看基本类型信息) - Part.2
反射概述 和Type类 1.反射的作用 简单来说,反射提供这样几个能力:1.查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata):2.迟绑定(Late-Binding)方法和属性.3 ...
- arcgis engine 监听element的添加、更新和删除事件(使用IGraphicsContainerEvents)
IGraphicsContainerEvents Interface 如何监听 element事件? 如,当我们在Mapcontrol上添加.删除.更新了一个Element后,如何捕捉到这个事件? ...
- Node.js入门笔记(2):全局对象(1)
以下将以API文档为基础进行分析学习 global对象 这些对象在所有模块里都可用.有些对象不是在全局作用域而是在模块作用域里,这些情况下面文档都会标注出来. __filename--返回当前模块文件 ...
- thinkphp 3.2与phpexcel
thinkphp版本:3.2 1.在http://phpexcel.codeplex.com/下载最新PHPExcel 2.把Classes目录下的文件(PHPExcel.php和PHPExcel文件 ...
- tyvj1034 尼克的任务
描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成.尼克的一个工作日为N分钟,从第一分钟开始到第N ...
- R语言:用简单的文本处理方法优化我们的读书体验
博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html 前言 延续之前的用R语言读琅琊榜小说,继续讲一下利用R语言做一些简单的文本处理.分词的事情.其实 ...
- Tools
Database: Online Schema Tool: http://dbdsgnr.appspot.com/ Orcale --> SQL developer MySQL--> To ...
- IntelliJ IDEA 14.x 快捷键/个性化设置
常用快捷键设置(设置成跟Eclipse差不多) 按照路径:File -> Settings -> Appearance & Behavior -> Keymap -> ...
- Shell入门教程:命令替换 $() 和 ``
所谓命令替换,是把命令执行后的标准输出放入变量中.这是一个十分有威力的功能.例如说, 想查看工作目录中所有的文件名,可执行ls命令,但如何把这些文件名存入变量中,供往后的程序代码再利用呢? 使用命令替 ...