SunnyOS准备4

8086 CPU一般是这样:CS寄存器初始化为0xF000,IP寄存器初始化为0xFFF0,所以按照CPU实模式地址计算法则,CPU执行的第一条指令地址是CS*10h+IP,即0xFFFF0处

对于80386以上的CPU:

第一点,80386及其以上的现代CPU(以下简称CPU)加电Reset之后并不是直接进入实模式;

第二点,CPU在合成地址的时候不区分实模式和保护模式。

CPU进入保护模式的方法是CR0寄存器的PE Bit置为1。而在CPU刚加电的时候,CR0寄存器的PE位实际上没有置1,但是此时也不是实模式,Intel并没有给给出表示此时CPU状态的术语名词。自从80386以来,因为增加了保护模式的缘故,CS等段寄存器不再是简简单单的段寄存器了,而是一个包含了段选择器(segment selector)段基址(segment base),以及段限制(segment limit)的一组复杂寄存器。显然段基址决定着内存段的基地址不过需要说明的是作为程序员只能操作CS寄存器中的“段选择器”这16位的大小,其它的区域作为隐藏区域对程序员不可见,我们无法访问。

合成地址时,假设段选择器(我们能访问的那16位)装入了0xF000,那么CPU会先将F000 * 10h也就是F0000h装入段基址里。之后需要合成地址的时候不考虑别的,而是直接从之前合成好的段基址里读出基地址F0000h加上IP寄存器里的偏移生成地址。如果CS寄存器的值不发生改变,段基址部分就不会发生改变。所以我们说,CPU在合成地址的时候不区分实模式和保护模式,CPU只是机械的从隐藏区域读出来段基址和IP寄存器的数值相加。

Intel这样做是为了效率,虽然实模式的地址计算很快,但是保护模式计算一个地址还要有去内存中寻找段描述符等工作,这会大大影响CPU的效率

放弃,无法理解。。。。。

原文:http://0xffffff.org/2013/03/14/15-x86-boot/

32硬件平台下,进程拥有4GB的线性地址空间(并不是物理地址空间)

启动分段机制,未启动分页机制:逻辑地址--> (分段地址转换) -->线性地址==物理地址
启动分段和分页机制:逻辑地址--> (分段地址转换) -->线性地址-->(分页地址转换) -->物理地址

逻辑地址空间:从应用程序的角度看,逻辑地址空间就是应用程序员编程所用到的地址空间,比如下面的程序片段: int val=100; int * point=&val;

其中指针变量point中存储的即是一个逻辑地址。在基于80386的计算机系统中,逻辑地址由16位的段寄存器(也称段选择子,段选择子)和32位的偏移量构成。

进程线性地址空间:

内存高地址区域是被操作系统内核所占据的,Linux操作系统占据了高地址区域的1GB内存(Windows系统默认保留2GB给操作系统,但是可以配置为保留1GB)。如果我们想知道一个进程具体的内存空间布局的话,可以去/proc目录找以进程的pid所命名的目录下一个叫maps的文件,使用cat命令查看即可(需要root权限)。

32位Linux系统中,代码段从线性地址0x08048000处开始的。数据段一般是在下一个4KB(分页机制默认选择4KB一个内存页)对齐的地址处开始。运行时堆是在数据段之后又一个4KB对齐处开始的,并通过malloc()函数调用向上增长(Linux下的malloc()一般依靠调用brk()或者mmap()系统调用实现)。再接着跳过动态链接库的区域就是进程的运行时栈了,需要注意的是栈是由高地址向着低地址增长的(看图中esp寄存器内容增长方向)。栈空间再往上就是操作系统保留区域了,用于驻留内核的代码和数据。即就是在一个进程的眼里,只有它和操作系统在一起。

我们具体来看看代码段,以C语言为例,程序代码段的入口_start地址处的启动代码(startup code)是在目标文件ctr1.o(属于C运行时库的部分)中定义的,对于特定平台上的C程序都一样。其执行流程如下:

0x080480c0 <_start>:

调用 __libc_init_first 函数
调用 _init 函数
调用 atexit 函数
调用 main 函数
调用 _exit 函数 

例子:

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

int main(int argc, char *argv[])
{
    int a = 1;              // 栈区
    static int b = 2;       // 全局静态区(读/写段)
    const int c = 3;        // 只读段
    char *str1 = "Hello";   // str1指针在栈区,"hello"字符串在只读段
    char str2[] = "world";             // 只在栈区(字符串)
    char *str3 = (char *)malloc(20);   // str3变量在栈区,指针指向堆区
   
    return EXIT_SUCCESS;
}

注释中我们看到了各个元素所在内存段的位置。而编译好的main函数代码本身是存在于代码区的(一般代码段也是只读段)。我们这个程序运行后如果是动态链接的C语言运行时库的话,动态库会存在图示的动态库映射区无论使用C语言运行时库的程序无论有多少,运行时库的代码在内存里只会有一份,对于不同的程序,进行地址映射即可

栈也经常被叫做栈帧(Stack Frame)或者活动记录(Activate Record)。栈里通常存储以下内容:

1.函数的临时变量;
2.函数的返回地址和参数;
3.函数调用过程中保存的上下文。

在i386中,使用esp和ebp寄存器划定范围。esp寄存器始终指向栈顶,随着压栈和出栈操作而改变值。ebp寄存器随着调用过程,暂时的指向一个固定的栈位置,便于寻址操作的进行。

 Done!!!

引用:

http://0xffffff.org/2013/05/23/18-linux-process-address-space/

时间: 2024-07-30 14:22:04

SunnyOS准备4的相关文章

SunnyOS准备

AT&T语法汇编和Intel语法汇编比较: 1.  前缀: ①在AT&T语法中,寄存器以'%'为前缀,立即数则以'$'为前缀,而Intel语法中则没有: ②在Intel语法中,十六进制立即数以'h'结尾,二进制立即数则以'b'结尾.另外对于编译器来说,十六进制立即数不能以字符a~f打头,需要在前面上加上'0'.而AT&T语法中,十六进制使用 "  0x数据  "来表示 Intel Syntax AT&T Syntax mov     eax, 1 mov

1. 公众号开发架构

1. 公众号开发需要与公众号后台有交互,需要在后台网页进行配置,比如通信的域名地址,js jdk的授权地址等等. 2. 使用Node.js为底层环境,使用ES6新特性. 3. 使用Koa框架,主要用来处理服务器之间的应用初始化.接口调用以及数据的响应. 4. 使用bluebird来处理和封装异步请求. 5. 网络请求使用request,它是对原生的http request的封装. 6. 微信的数据包装方式是XML,借助ejs模板库,把数据作为变量替换到XML字符中. 7. 常用工具模块, lod

ThinkPHP3.2对接开发支付宝即时到帐接口

ThinkPHP3.2对接开发支付宝即时到帐接口 在做一些商城.自动发卡网站.会员积分充值.金币充值等等这类网站都时候,我们极大可能需要使用到第三方都支付接口.不管是财付通.支付宝.银联.贝宝.易宝这些都 ThinkPHP3.2对接开发支付宝即时到帐接口        在做一些商城.自动发卡网站.会员积分充值.金币充值等等这类网站都时候,我们极大可能需要使用到第三方都支付接口.不管是财付通.支付宝.银联.贝 宝.易宝这些都好,总之这些第三方支付平台给我们带来了很多便利都地方.我们只需要跟这些平台

centos 6.4下安装与设置apache服务器

1.打开虚拟机开启centos 6.4系统后进入root用户下,打开终端,输入#yum -y install httpd,安装apache服务器. 输入命令后到安装完成前有几次需要暂停确认,输入y按enter键即可,直到安装显示complete. 2.为服务器设定本机IP地址.利用这个IP地址创建基于IP地址的虚拟主机 在/var/www/html目录下创建h1文件夹,在文件夹下创建index.html文件(文件内写可在屏幕输出的html代码,以作测试): 查看本机ip地址,然后把服务器的eth

阿里云搭建配置自己的ngrok服务

一直在使用sunny提供的免费的ngrok服务,由于昨天不知是不是服务器down的原因,一直连接不上,导致手中微信开发的工作无法很好的开展.遂有了再次尝试自己搭建一个ngrok服务(曾经有过几个小时的研究和尝试,没有成功).在N小时的尝试之后,最终修成正果,成功搭建属于自己的ngrok服务! (其实还有一些问题没有确认,但是暂时不深入研究了,有兴趣的可以深入) 准备工作: 一台外网服务器,一个域名. 我的环境: 阿里云Centos6.5,二级域名ngrok.***.cn泛解析. Go环境 1 #

ubuntu下使用ngrok外网映射

好久之前想搞明白这个事情,可是就是不知道这个词叫外网映射,所以也一直不知怎么做,在慕课网看用java开发微信公众号的时候教程里提到了外网映射,查了一些资料终于把本地给映射到外网了,直接变成了80端口,在这记录一下. 1.首先先下载ngrok:https://ngrok.com/download 2.打开http://www.ngrok.cc/下载sunny和之前下载的ngrok放在同一个文件夹中 3.写配置文件https://www.sunnyos.com/article-show-61.htm

免费内网映射外网绑定,tcp端口转发(windows)

在tcp socket开发过程中,想要外网客户端映射到本地启动的tcp服务端,总结本地tcp端口映射外网方法: 1.打开ngrok后注册用户,网址 ngrok:https://www.ngrok.cc/ 2.添加一个隧道,选择免费版即可.  具体的添加方法:https://www.sunnyos.com/article-show-70.html 3.启动ngrok隧道: ngrok  参考文献:https://www.sunnyos.com/article-show-67.html 下载插件,打

1.利用consul实现k8s服务自动发现

标题 : 1.利用consul实现k8s服务自动发现 目录 : 微服务架构设计 序号 : 1 ] } } ] } } ? - consul自身支持ACL,但目前,Helm图表不支持其中一些功能,需要额外的手动配置, 有关详细信息可参阅:https://www.consul.io/docs/platform/k8s/helm.html - 我们使用basic-auth作了授权,当用户访问consul-ui时需要提供用户名和密码 ?shell yum -y install httpd echo "$