`
simohayha
  • 浏览: 1403648 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

intel IA-32架构简介

    博客分类:
  • asm
阅读更多
IA32的cpu操作模式

1保护模式:

这个模式是cpu的native状态.它可以在一个保护的多任务的环境中直接执行 "real-address mode"的8086的软件.这个特性叫做virtual-8086模式.

这个模式也就是cpu的一般工作模式.因为这个模式基本上打开了cpu的所有特性.

2 real-address模式:

这个模式它实现了一个8086处理器的环境的扩展.换句话说,可以说是模拟了一个8086的程序环境.

计算机在重启或者开机的时候就处于这个模式,因此每次开机需要操作系统来切换到保护模式.这个模式中很多cpu的特性都是被关闭的.

3 system management 模式(SMM)

这个模式提供给操作系统一个执行平台指定的功能,提供了一个透明的架构.比如系统安全或者电源管理.

当进入到smm中后,cpu保存当前的运行上下文,然后跳转到一个完全隔离的地址空间.然后smm指定的代码会被执行.当从smm返回时,处理器会返回刚才保存的状态.


IA-64的cpu操作模式:

IA-64加了一个模式就是IA-32e.这个模式包含下面两种子模式.

1 compatibility 模式

这个模式主要是用来不重新编译32位或者16位的程序,而能直接在64位处理器上运行.


2 64位模式

这个模式他所要求的环境必须是64位的操作系统,以及64位的应用程序.这个模式下能存取64位的线性地址空间.

一个64位的操作系统既能在64位模式运行64位的应用程序,也能在兼容模式下运行32位程序(不重新编译).


执行环境:

1 地址空间

IA-32 最大有4GB 线性地址空间,以及64GB物理地址空间

内存存取是虚拟为一个栈来进行的.


内存模型,也就是程序用来存取内存的方式:

1 flat memory模型

在这个模型下,内存看起来就是单独的持续的地址空间.这个空间叫做线性地址空间.代码,数据以及栈都是保存在这个地址空间内.

2 segments内存模型.

这个模型下,内存看起来就是由一些不连续的地址空间组成的,这些地址空间就称为段.数据,代码,以及栈包含在不同的段里面.要在一个段里面寻址,则程序必须生成一个逻辑地址.

逻辑地址由一个段选择符和一个位移组成.

在内部,所有的段都被映射为线性地址,因此要存取一个内存位置,处理器必须翻译逻辑地址到线性地址.

3 Real-address mode memory model

这个模式主要是针对8086处理器的.


下面这张图表示了3种内存模型:





寄存器:

下面这张图表示了IA-32架构的所有寄存器:





段选择符必须保存到段寄存器中.一共6个段寄存器.分别代表不同的段.

cs,ss,分别代表代码段以及栈段.剩下的都是数据段寄存器.

General-Purpose Registers有8个,分别是EAX, EBX, ECX, EDX, ESI, EDI, EBP, 和 ESP.

ebp和esp为帧指针和栈指针.


数据类型:

1 byte,words,doublewords,quadwords以及doublequadwords.

分别是8位,16位,32位,64位,128位.

这里要注意doublequadwords只有在拥有sse扩展的处理器才存在.

下面这张图表示了所有的数值类型:







存取words,doublewords,quadwords以及doublequadwords的地址最好都要自然对齐,一般是4字节或者8字节对齐.


如果是一次没有对齐的内存存取,则处理器将会请求两次内存存取,才能取到对应的内存数据.

还有一些指令操作doublequadwords时也要求对齐.如果是非对齐的存储的话,会产生一个general-protection exception (#GP).而他一般是16字节对齐.

IA-32的浮点是符合IEEE 754的标准的.具体格式可以看下面的表:





2 指针类型.

near pointer和far pointer

far pointer是一个逻辑地址由段选择符和位移组成:




还有一些类型比如String,BCD等,这里都没有介绍,详细的请去看intel的官方手册.

函数调用:

主要是4条指令 CALL,RET,ENTER以及LEAVE.

栈只不过是在内存中虚拟出来的一块类似数组的区域(或者说是段)而已,段寄存器SS保存有栈的地址.

使用PUSH和POP指令来操作数据的压栈,入栈.

这里要注意栈是向下增长的.

下图就是栈的结构:





初始化和确立一个栈为当前栈,也就是栈的切换需要下面几个步骤:

1 建立一个stack段.

2 load这个段选择符到SS寄存器.这里能使用MOVE,POP或者LSS.

3 load栈指针到ESP寄存器.


栈的对齐:

栈的地址(其实也就是栈的段描述符)必须是16位或者32位对齐.依赖于段的宽度.

因此我们经常可以看到汇编中这一句:

and    $0xfffffff0,%esp

这句也就是对其的语句。

存取栈的地址宽度:

要么是16位,要么是32位。当为16位宽时则栈寄存器使用sp,当为32位宽则使用esp。使用16位还是32位依赖于当前代码段寄存器的D flag。


过程调用:

一般来说使用stack-frame 的话,都会在push本地变量进栈之前,复制esp到ebp。因此可以这么说当栈建立起来时ebp和esp一样,指向当前栈段的地址。也就是ss寄存器的值。

接下来来看call指令。

call指令
这个指令应该是条伪指令。

当执行所要跳到的过程第一条指令之前,call指令会先push 当前EIP寄存器的内容到当前栈。这个地址叫做return-instruction pointer,保存这个地址的目的是为了等会函数调用返回后能够正确的返回到当前的位置。

而对应的RET指令就是从栈里面pop出return-instruction pointer到EIP寄存器。

这里要注意处理器并不会保存return-instruction pointer的位置,因此应用程序要确定当函数调用完毕后,栈指针指向return-instruction pointer,这一切都要在ret指令调用之前完成。因此一般都会直接拷贝EBP(这里ebp保存的是调用前的esp的位置)到ESP,然后调用 ret,此时ESp中就保存有调用前我们保存的return-instruction pointer,我们就可以直接pop,然后保存到EIP寄存器。

这里还有一个要注意的,处理器并没有强制要求return-instruction pointer一定要指向调用者的栈,它可以指向任何地址。因此我们可以在ret指令执行之前修改这个值,也就是修改esp的值,然后当ret执行之后,我们就跳到另外的地址了。不过这样非常危险,举个例子,csapp中的那个缓冲区攻击的练习题就是用这个来做的。

CALL指令分两种类型,一种是调用当前代码段的函数,这种叫做near call,一种是调用不同代码段的,这种叫做far call.对应的RET指令也是分为两种类型匹配CALL指令。

接下来来看这两种类型的不同:

当执行一个near call时,处理器会做下面几步:

1 压当前的EIP入栈,也就是保存return-instruction pointer。

2 load被调用函数的位移到EIP寄存器

3 开始执行。

对应的执行RET:

1 弹出保存的return-instruction pointer到EIP。

2 如果ret指令有参数N,则增加栈指针n个字节来释放参数。

3 返回调用者。

当执行一个far call时,处理器会做下面几步:

1 压当前的CS寄存器的值入栈。也就是保存代码段。

2 压当前的EIP入栈。

3 load被调用者函数的代码段的段选择符到CS寄存器。

4 load被调用函数的位移到EIP寄存器

5 开始执行。

对应的ret:

和上面的near类似,只不过会将cs弹出。

下面这张图表示了near call 和far call的区别:






下面来看参数的传递
参数传递有三种类型,分别是通过General-Purpose寄存器,参数列表或者栈。

1 General-Purpose寄存器

处理器在过程调用中并不会保存General-Purpose寄存器的状态,调用者可以传递6个参数给被调用者,通过复制参数到这些寄存器中的任意一个(除了ESp和EBP).这一切都要在CALL指令之前完成。

2 参数列表

上面通过寄存器的传递,我们最多只能传递6个参数,并且不能传递复杂的数据结构。而我们用参数列表就可以做到,它是将所要传递的参数放到内存中的一个数据段,然后一个保存有这个参数列表的指针就能够通过General-Purpose寄存器传递给被调用者了。

3 栈。

这种也是为了传递更多得参数。它很简单,就是将要传递的参数压入栈,然后通过帧指针很容易存取参数,。


虽然处理器不能保存相应的函数状态信息。可是这里有几条指令,比如PUSHA,POPA,保存和弹出General-Purpose寄存器的值。

下面来看cpu操作的特权级别
一共有4个级别,可以看下图:





0是最高级别。当低级别想要存取或者操作高级别的段时,必须通过一个叫做gate的接口,否则就会报一个#GP的异常。

这里要知道每一个级别都有自己独立的栈。

这时如果一个低级别的函数调用一个处于高级别的段的函数时,虽然也叫做far call,可是还是有些不同的:

1 CALL 指令所提供的段选择符指向一个特殊的数据结构,叫做call gate descriptor.这个结构包含了下面3个部分,存取权限,被调用者的代码段的段描述符以及代码段的位移。

2 处理器会切换到一个新的栈执行被调用函数。这里还有一个要注意的,对于级别3来说,段选择符和栈指针分别保存在SS和esp寄存器里面,而在级别0,1,2来说,他们则是保存在一个系统段叫做task state segment(TSS).

接下来就来看不同特权级别的CALL和入RET指令的操作。

当调用一个更高特权级别的函数,处理器会做如下操作:

1 执行一个权限检测。

2 保存当前的SS, ESP, CS, and EIP寄存器(注意这里是处理器内部做的)。

3 为新栈load栈指针和段选择符(从TSS段)到SS和esp寄存器中。

4 将第二步保存的SS和esp压入新的栈。

5 从调用者的栈拷贝参数到新的栈。而拷贝多少值,这个值是保存在call gate descriptor中的。

6将第二步保存的CS和EIP压入新栈。

7  从call gate将新的代码段和指令指针保存到CS和EIP。

8 开始执行。

这里RET就不描述了,基本对照CALL和前面的RET的描述就可以理解了。

可以看下面的图,能更好的理解这个过程:





最后还有一对指令那就是ENTER和LEAVE指令.

这两个指令自动的创建,释放被调用者的栈帧.ENTER指令具体的用法以及描述最好还是去看intel 的处理器手册. 看gcc生成的汇编很少使用ENTER,不知道什么原因..

LEAVE指令复制EBP寄存器的内容到ESP,也就是释放掉所有的为了执行当前函数所分配的栈空间.这个指令其实也就是restore ESP,因此我们一般都是在ret之前调用这个指令.



  • 大小: 68.4 KB
  • 大小: 41 KB
  • 大小: 40.9 KB
  • 大小: 12.5 KB
  • 大小: 40.9 KB
  • 大小: 57.9 KB
  • 大小: 50.4 KB
  • 大小: 30 KB
  • 大小: 74 KB
0
0
分享到:
评论

相关推荐

    英特尔 64 位和 IA-32 架构软件开发人员手册(全套最新)+最新历史更新说明-2022年4月

    《英特尔 64 位和 IA-32 架构软件开发人员手册》是一套全面且权威的技术参考资料,旨在帮助软件开发者深入理解英特尔处理器的架构和指令集,从而编写更高效、更优化的代码。这套手册包含了最新的技术信息,截至2022...

    Intel 64及IA-32架构软件开发者手册

    ### Intel 64及IA-32架构软件开发者手册知识点详解 #### 一、手册概述 《Intel 64及IA-32架构软件开发者手册》是为开发人员提供的一套全面的技术文档,旨在帮助他们深入理解Intel 64与IA-32架构,并能够在此基础上...

    英特尔64和IA-32架构软件开发人员手册(十卷)

    《英特尔64和IA-32架构软件开发人员手册》是英特尔公司为软件开发者提供的一套详尽的技术参考资料,旨在帮助他们充分利用英特尔64和IA-32处理器的硬件功能。这套手册涵盖了从基本的指令集到高级的系统编程、性能优化...

    Intel 64及IA-32 架构软件开发者手册(1~3卷).zip

    《Intel 64及IA-32架构软件开发者手册》是汇编语言程序员、系统软件开发者和硬件工程师的重要参考资料,它详细阐述了Intel处理器的工作原理和编程模型。这套手册共分为三卷,全面覆盖了从基本指令集到高级系统编程的...

    [Intel.64.and.IA-32体系结构:软件开发人员手册]文字版

    - **Intel 64 和 IA-32 架构**:这是由 Intel 公司设计的一种计算机体系结构,支持两种不同的指令集架构(ISA):Intel 64(也称为 x86-64 或 AMD64)和 IA-32(即传统的 32 位 x86 架构)。这种混合架构使得系统...

    英特尔® 64 和 IA-32 架构软件开发人员手册卷 3A:系统编程指南

    《英特尔® 64 和 IA-32 架构软件开发人员手册卷 3A:系统编程指南》是为软件开发者提供深入理解英特尔处理器体系结构和系统编程接口的重要参考资料。该手册详细阐述了如何在英特尔® 64 和 IA-32 平台上进行高效的...

    Intel IA-32手册3卷(3个PDF文件)

    《Intel IA-32手册》是理解Intel处理器架构和编程的重要参考资料,分为三卷,涵盖了基本架构、指令集参考和系统编程指南。这套手册详细介绍了Intel IA-32架构的各个方面,对于从事汇编语言编程、系统级开发或者对...

    IA-32架构软件开发人员手册_1~3卷:系统编程指南

    Intel® 64 and IA-32 架构软件开发人员手册1~3卷,英文版 Intel® 64 and IA-32 ArchitecturesSoftware Developer’s ManualVolume (1, 2A, 2B, 2C, 3A, 3B and 3C):System Programming Guide

    英特尔® 64 和 IA-32 架构软件开发人员手册合并版移除密码

    《英特尔® 64 和 IA-32 架构软件开发人员手册》(以下简称“手册”)是英特尔公司为开发者提供的一份详尽的技术文档,它包含了关于英特尔64位架构(Intel® 64)和IA-32架构(即传统的32位x86架构)的所有关键技术...

    英特尔 64 位和 IA-32 架构软件开发人员手册第 3 卷(2019年10月最新更新)

    IA-32架构原名为i386,是英特尔早期32位微处理器架构,而英特尔64架构则是基于x86架构的64位扩展。这两款架构的设计旨在提供高性能计算能力,支持广泛的软件应用。 英特尔发布的《英特尔64位和IA-32架构软件开发...

    英特尔® 64 和 IA-32 架构优化参考手册.pdf

    英特尔® 64 和 IA-32 架构优化参考手册.pdf

    Intel 64-ia-32架构软件开发手册卷3

    ### Intel 64-ia-32 架构软件开发手册卷3:系统开发 #### 一、关于手册 Intel 64-ia-32 架构软件开发手册卷3(System Programming Guide)是Intel官方发布的一系列文档中的一个组成部分,主要针对系统级别的软件...

    Intel 64及IA-32 架构优化参考手册

    ### Intel 64及IA-32 架构优化参考手册关键知识点解析 #### 一、概述 《Intel 64及IA-32 架构优化参考手册》是Intel官方发布的一本重要文档,旨在指导软件开发者如何针对Intel 64及IA-32架构的处理器进行代码优化...

    IA-32架构 英特尔

    在IT行业的深度解析中,英特尔(Intel)的IA-32架构与Intel 64架构是计算机科学领域的重要组成部分,其复杂性和影响力不容小觑。本文将深入探讨这些架构的关键特性、发展历程以及对现代计算环境的影响。 ### IA-32...

    Intel ia-32 CPU手册

    《Intel ia-32 CPU手册》是一份珍贵的技术文献,主要涵盖了Intel IA-32架构的处理器技术细节,包括从基本的指令集到高级的MMX指令集。IA-32,全称为“Intel Architecture, 32-bit”,是Intel公司开发的一种广泛使用...

    英特尔® 64 和 IA-32 架构软件开发人员手册-卷3-系统编程指南

    英特尔® 64和IA-32架构软件开发人员手册-卷3-系统编程指南是针对开发者的一本技术手册,旨在指导开发者如何为英特尔® 64和IA-32架构编写系统级的软件。这两架构分别对应于英特尔®架构的64位和32位技术。本卷主要...

    IA-32架构软件开发人员手册卷3:系统编程指南(包括中英两版)

    《IA-32架构软件开发人员手册卷3:系统编程指南》是Intel公司为开发者提供的一份详尽的系统编程参考资料,涵盖了Intel? 64和IA-32架构的硬件特性和软件接口。这份手册旨在帮助程序员充分利用这些处理器的性能,编写...

    IA-32架构软件开发人员手册3卷齐全

    《IA-32架构软件开发人员手册》是Intel公司为开发者提供的一套全面、权威的指导书籍,旨在帮助程序员深入理解和充分利用IA-32架构。这套手册覆盖了从80386到现代处理器的广泛内容,对于系统编程、驱动开发、性能优化...

    IA-32架构软件开发人员手册

    IA-32架构是英特尔公司设计的32位微处理器架构,主要用于其x86系列的中央处理器(CPU)。该架构自1985年以来一直被广泛应用于个人电脑领域,支持了PC操作系统和应用程序的发展。IA-32架构软件开发人员手册是针对软件...

Global site tag (gtag.js) - Google Analytics