linux平台学x86汇编(二):处理器指令码及IA-32平台了解

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途】

在计算机操作的最底层,所有计算机处理器都按照制造厂商在处理器内部定义的二进制代码来操作数据,这些代码定义了处理器应该利用程序员提供的数据完成相应的功能,这些预置的代码被称为指令码。不同类型的处理器的指令码是不一样的,但处理指令码的方式是类似的。

当计算机处理器芯片运行时,他会读取存储在内存中的指令码,每个指令码包含不同长度字节的信息,这些信息指示处理器完成特定任务。每条指令码都是从内存读取,指令所需的操作数据也是从内存读取。

每条指令都必须包含至少一个字节的操作码,操作码定义处理器应该完成什么样的操作。每个处理器都有自己定义好的操作码。

Intel IA-32系列微处理器使用专门格式的指令码,了解一下这些指令格式对汇编语言程序设计会有所帮助。IA-32指令码格式有四个主要部分构成:

  • 可选指令前缀
  • 操作码
  • 可选修饰符
  • 可选数据元素

下图为IA-32指令码格式的布局。

如上图所示,IA-32指令格式中唯一必须的部分是操作码。每个指令码都必须包含操作码,其定义了指令执行的基本任务。

指令前缀可以包含0-4个修改操作码行为的1字节前缀。按照前缀功能,这些前缀被分成四个组,修改操作码时,每个组的前缀一次只能使用一个(最多4个)。四个前缀如下:

  • 锁定前缀和重复前缀
  • 段覆盖前缀和分支提示前缀
  • 操作数长度覆盖前缀
  • 地址长度覆盖前缀

一些操作码需要另外的修饰符来定义执行功能中涉及到的寄存器和内存地址。修饰符包含三部分:

  • (ModR/M)寻址方式字节
  • SIB(比例索引基址)字节
  • 1、2或4个地址移位字节

ModR/M字节由三个字段的信息构成。如下图:

mod字段和r/m字段一起使用,用于定义指令使用的寄存器或寻址模式。

reg/opcode用于允许使用更多的三位进一步定义操作码功能,或用于定义寄存器的值。

SIB字段也由3个字段的信息构成。如下图

比例字段指定操作的比例因素,索引字段指定内存访问中用作索引寄存器的寄存器,基址字段指定用作内存访问的基址寄存器的寄存器。

地址移位字节用来指定对于ModR/M和SIB字节中定义的内存位置位置的偏移量。

数据元素在指令码的最后部分,一些指令码从内存位置或处理器寄存器读取数据,而一些指令码在其指令本身之内就有包含数据。

可以看到,使用处理器的指令码进行程序设计是十分困难的,所以才有了后面的高级语言。但处理器根本不知道如何处理高级语言,必须通过某种机制把高级语言代码转换为处理器能够处理的指令码才能处理。

使用汇编语言程序设计必须要先了解处理器环境,不同类型的处理器的指令码是不一样的。我们将以AI-32平台为例来讲述汇编语言。

虽然不同处理器系列结合了不同的指令集合和功能,但大多数处理器都使用了相同的核心组件集合。计算机一般包含如下四个组件:

处理器包含控制计算机操作的硬件和指令码,其通过3个单独的总线:控制总线、地址总线、数据总线,处理器被连接到计算机的其他元素(内存存储单元、输入设备和输出设备)。处理器由很多组件构成,在处理器处理数据的过程中,每个组件都有其作用,汇编语言程序有访问和控制所有这些组件的能力,所以了解这些组件很重要。处理器主要组件如下:

  • 控制单元
  • 执行单元
  • 寄存器
  • 标志

控制单元是处理器的中心,控制单元的主要作用时控制处理器在何时做何种操作。控制单元实现4个基本功能:

  1. 从内存获得指令。
  2. 对指令进行分析以便进行操作。
  3. 从内存获得所需结果。
  4. 有必要则存储结果。

执行单元负责执行处理器指令。执行单元由一个或多个算术逻辑单元构成(ALU)。

寄存器用于解决处理器从内存读取数据时需要等待的问题。在处理器访问数据元素时,请求被发送到处理器外部,通过控制总线进入存储单元,执行该过程时处理器处于等待状态。而寄存器能够存储要处理的数据元素,而无需访问内存单元。但是处理器芯片中内置的寄存器数量是有限的。IA-32平台具有不同长度的多组寄存器。通用寄存器用于临时存储数据;段寄存器用于引用内存位置;指令指针寄存器,又称为程序计数器(PC),跟踪要执行的下一条指令码;控制寄存器用于确定处理器的操作模式。

通用寄存器及其用处描述如下表:


EAX

用于操作数和结果数据的累加器

EBX

指向数据内存段中的数据指针

ECX

字符串和循环操作的计数器

EDX

I/O指针

EDI

用于字符串操作的目标的数据指针

ESI

用于字符串操作的源的数据指针
ESP
堆栈指针

EBP

堆栈数据指针

段寄存器及其描述:


CS

代码段

DS

数据段

SS

堆栈段

ES

附加段指针

FS

附加段指针

GS

附加段指针

处理器标志确定处理器实现的每个操作是否成功。

时间: 2024-11-15 03:31:07

linux平台学x86汇编(二):处理器指令码及IA-32平台了解的相关文章

linux平台学x86汇编(三):相关开发工具

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 类似于其它高级语言,编写汇编语言,必须有一个开发环境,那么也就需要适当的工具了.搭建汇编语言至少应该有下面这些工具:汇编器.链接器.调试器.下下面看看在汇编语言开发环境中如何使用它们. 汇编器 汇编器用于把汇编语言源代码转换为处理器指令码.选择的汇编器必须能够生成所在系统的处理器系列指令码.汇编语言源代码程序有3个部分:操作码助记符.数据段.命令.但是每种汇编器对于每个部分使

linux平台学x86汇编(二十):汇编库的使用

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 汇编语言和C一样,可以通过使用库来简化阻止大量函数的目标文件的问题.GNU C编译器可以不在命令行中独立地包含每个独立地函数目标文件,它允许吧所有目标文件组合在单一存档文件中.在编译C程序时,要做的工作就是包含单一的目标库文件,在编译时,编译器可以从库文件中挑出所需的正确目标文件.在库文件中,经常按照应用程序类型或者函数类型把函数分组在一起,单一应用程序项目可以使用多个库文件

linux平台学x86汇编(十二):字符串的存储与加载

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 字符串的存储与加载是指,将字符串的值加载到寄存器和将其传回内存位置中.其使用指令lods指令和stos指令. lods指令用于把内存中的字符串值传送到eax寄存器中,该指令有三种不同格式:lodsb(1字节).lodsw(2字节).lodsl(4字节).lods指令使用esi寄存器作为隐含的源操作数.esi寄存器必须包含要加载的字符串所在的内存地址. 在使用lods指令把字符

linux平台学x86汇编(十九):C语言中调用汇编函数

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 除了内联汇编以外,还有一种途径可以把汇编代码整合到C/C++语言中,C/C++语言可以直接调用汇编函数,把输入值传递给函数,然后从函数获得输出值. 如果希望汇编语言函数和C/C++程序一起工作,就必须显示地遵守C样式的函数格式,也就是说所有输入变量都必须从堆栈读取,并且大多数输入值都返回到EAX嫁寄存器中.在汇编函数代码中,C样式函数对于可以修改哪些寄存器和函数必须保留哪些寄

linux平台学x86汇编(六):数据的传送

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 前面讲了定义数据元素,既然定义了数据元素,那么就需要知道如何处理这些数据元素.数据元素位于内存中,并且处理器很多指令要使用寄存器,所以处理数据元素的第一个步骤就是在内存和寄存器之间传送它们.数据传送指令为mov,其为汇编语言中最常用的指令之一. mov指令的基本格式如下: movx source, dest 其中source和dest的值可以是内存地址.存储在内存中的数值.指

linux平台学x86汇编(四):从“hello world!”开始

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 汇编语言程序由定义好的段构成,每个段有各自的目的.三个最常用的的段如下:数据段.bss段.文本段.文本段是可执行程序内声明指令码的地方,所有汇编程序都必须有文本段,数据段和bss段是可选的,但是在程序中经常使用.数据段声明带有初始值的变量,bss段声明使用0值初始化的数据元素,这些元素常用作汇编程序的缓冲区.下图为汇编语言程序的布局. GNU汇编器使用.section命令语句

linux平台学x86汇编(八):条件跳转

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 在此之前我们使用的汇编代码示例都是从第一条指令开始,直到最后最后一条指令程序退出.但实际上和高级语言类似,汇编代码也提供指令来改变程序处理数据方式. 正常情况下,程序要执行要执行的下一条指令是在指令指针寄存器中,指令指针确定程序中哪条指令是应该执行的下一条指令. 当指令指针在程序指令中移动时,EIP寄存器会递增.指令长度可能是多个字节,所以指向下一条指令不仅仅是每次是指令指针

linux平台学x86汇编(十四):函数的使用

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 和高级语言一样,汇编语言在多个项目之间可能会编写相同的过程和处理,如果使用函数的话就可以不必每次需要时都重复编写实用程序代码,从而在需要它的时候调用它. 函数包含完成特定功能所需的代码,数据从主程序传递给函数,然后结果返回给主程序.调用函数时,程序执行路径被改变,切换到函数代码的第一条指令.处理器从这个位置开始执行指令,直到函数表明它可以把控制返回到主程序中的原始位置. 在汇

linux平台学x86汇编(五):使用gdb调试汇编程序

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 正如C语言一样,编写所有语言程序一样会出现一些一些错误,发生错误时,我们可以使用调试器一步一步运行程序以监视数据是如何被处理的.本节使用GNU调试器检查上一节hello程序,监视处理过程中寄存器和内存的值的变化.要调试汇编语言程序,在编译时,需要使用-gstabs参数重新汇编源代码,使用了该参数编译出来的可执行文件要比之前稍大一些,因为添加了附加信息.上一节程序不使用-gst