实验一:初步认识程序在内存中运行

顾涛原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

如果我写的不好或者有误的地方请留言

实验要求:

  • 题目自拟,内容围绕计算机是如何工作的进行;
  • 博客中需要使用实验截图
  • 博客内容中需要仔细分析汇编代码的工作过程中堆栈的变化
  • 总结部分需要阐明自己对“计算机是如何工作的”理解

实验报告:

首先我们编译一个简单的c语言代码main.c

int g(int x)
{
      return x + 3;
}
int f(int x)
{
      return g(x);
}
int main(void)
{
      return f(8) + 1;
}

gcc -S -o main.s main.c -m32 我们得到main.s如下

g:
	pushl  %ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	addl	$3, %eax
	popl	%ebp
	ret
f:
	pushl  %ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	call	g
	leave
	ret
main:
	pushl  %ebp
	movl  %esp, %ebp
	subl	$4, %esp
	movl	$8, (%esp)
	call	f
	addl	$1, %eax
	leave
	ret

接下来我们来认识一些汇编指令的含义:

ebp 堆栈栈底
esp 堆栈栈顶
eax 保存函数返回的数据
call f 等价于
pushl %eip;
movl f, %eip;
leave 等价于
movl %ebp,%esp;
popl %ebp;
ret 等价于 pop %eip

接下来一句一句分析汇编代码:

我们得到寄存器和栈中数据变化如下:

其中main函数 f函数 g函数分别对应从上到下的3个颜色

代码比较简单 不再码字叙述了

值得注意的是程序结束时候的ret指令将会出栈%eip

该eip是调用main函数的某个函数

最后结合所学知识 简单的说一下计算机是如何工作的

简单的说就是存储程序

时间: 2024-08-01 21:10:03

实验一:初步认识程序在内存中运行的相关文章

内存管理--程序在内存中的分布

在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这个沙盘就是虚拟地址空间(virtual address space). 1 32位虚拟内存布局 在32位模式下虚拟地址空间总是一个4GB的内存地址块.这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用.每一个进程拥有一套属于它自己的页表,但是还有一个隐情.只要虚拟地址被使用,那么它就会作用于这台机器上运行的所有软件,包括内核本身.因此一部分虚拟地址必须保留给内核使用: 图 1 这并不意味

程序在内存中的分布

转载,原文地址:http://blog.csdn.net/hackbuteer1/article/details/6786811 在现代的操作系统中,当我们说到内存,往往需要分两部分来讲:物理内存和虚拟内存.从硬件上讲,虚拟空间是CPU内部的寻址空间,位于MMU之前,物理空间是总线上的寻址空间,是经过MMU转换之后的空间. 一般我们所说的程序在内存中的分布指的就是程序在虚拟内存中的存储方式. 从低地址到高地址,可分为下面几段: 预留内存地址(操作系统维护的内存地址,不可访问) 程序代码区(只读,

程序在内存中的分配方式

1 桟区(stack):由编译器自动分配和释放,存放函数的参数值,局部变量的值,其操作方式类似于数据结构中的栈. 若申请的内存小于系统所剩内存则成功,否则就会发生栈溢出错误. 栈的增长方向是向下的,通常栈的初始化指针指向内存的最高地址,它是连续的.系统自动分配,因此速度很快. 在函数调用时,第一个进栈的是主函数的下一条指令的地址,然后是各个函数的参数,参数从右向左进栈,然后是函数中的局部变量.静态变量是不入栈的. 2 堆区(heap):一般有程序员分配和释放,若不释放,最后由操作系统回收. 它与

对一个程序在内存中的分析【转】

转自:http://blog.csdn.net/bullbat/article/details/7304404 bullbat  译 内存管理是操作系统的核心:它对于程序员和系统管理员都很关键.在接下来的几篇文章里面我将对内存的关键技术做谈论,但是不会远离其本质.然而概念很普通,例子多半来自32位X86系统的LINUX和Window操作系统.这第一篇文章谈论程序在内存中如何存放. 在多任务操作系统中的每一个进程运行在他自己的内存地址空间中.这个地址空间就是虚拟地址空间,虚拟地址空间在32位模式下

自己写的程序在OS中运行 杂想

搞嵌入式的同学问:怎么把自己的程序放到OS中? 程序放到OS中,回想一下自己学过的操作系统课程.学了一堆的进程调度.文件系统.是的,自己的操作系统学的都是怎么设计操作系统但是貌似没说明怎么将自己写的程序放到OS中. 首先Linux和Mac O都不熟悉,我回想一下Windows过程中程序的运行.安装-运行,就这么简单. 再想一下,在OS运行的过程中是一个死循环.那么在循环中应该有一个操作是专门监听事件的变动的------HOOK?应该就是想HOOK这种. 那么安装的时候也就是说: 1.我把程序的配

使用gdb进行程序调试1-在GDB中运行程序

在GDB中运行程序 一.启动程序 如果在启动gdb时没有指明程序,可以使用命令file或exec-file加载程序: run(r): run(r)命令使程序启动,可以在run命令中指明程序参数:值得注意的是,首次运行run后,如果再次执行run并且不带参数,会以之前的参数运行程序. set args: 指定程序的参数.set args后,run可以不带参数而以指定的参数运行程序.如果set args不太参数,清楚程序参数,执行run后程序不太参数运行. 在加载程序后,如果程序重新编译,gdb会根

程序在内存中镜像

用户空间的内存模型 Linux操作系统在加载程序时,将程序所使用的内存分为5段:text(程序段).data(数据段).bss(bss数据段).heap(堆).stack(栈). text segment(程序段) text segment用于存放程序指令本身,Linux在执行程序时,要把这个程序的代码加载进内存,放入text segment.程序段内存位于整个程序所占内存的最上方,并且长度固定(因为代码需要多少内存给放进去,操作系统是清楚的). data segment(数据段) data s

c++ 程序在内存中的分布

从低地址到高地址: 1.代码区[包含常量的]:存放函数体的二进制代码 2.全局变量区[已初始化 + 未初始化]: 全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量在一块区域, 未初始化的(全局变量和的静态变量)在相邻的另一块区域.  程序结束后有系统释放 3.堆:由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表. 4.栈:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.

Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

(进程的虚拟存储器映像布局详解) 前言:原文来自于http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/ 这里只是对其进行翻译,并且重构了原文中的图片.译注则是我增加的内容,用来解释原文或提出问题:由于个人水平有限,译文和译注中的错误之处还请广大坛友提出指正,不胜感激. 下面采用分段中英对照的方式列出内容: Memory management is the heart of operating systems; i