第三章:程序的转换

第三章:程序的转换计算机硬件只能识别和理解机器语言程序,用各种汇编语言或高级语言编写的源程序都要翻译(汇编,解释或编译)成以机器指令形式表示的机器语言才能在计算机中执行。 计算机的指令有微指令,机器指令和伪(宏)指令之分。微指令是微程序级命令,属于硬件范畴;伪指令是由若干机器指令组成的指令序列,…

概述

计算机硬件只能识别和理解机器语言程序,用各种汇编语言或高级语言编写的源程序都要翻译(汇编,解释或编译)成以机器指令形式表示的机器语言才能在计算机中执行。

计算机的指令有微指令,机器指令和伪(宏)指令之分。微指令是微程序级命令,属于硬件范畴;伪指令是由若干机器指令组成的指令序列,属于软件范畴;机器指令介于二者之间,处于硬件和软件的交界面。

指令结构体系

在计算机系统的抽象层中,最重要的抽象层就是指令集体系结构(ISA),他作为计算机硬件之上的抽象层,对使用硬件的软件屏蔽了底层硬件的实现细节,将物理上的计算机硬件抽象成一个逻辑上的虚拟计算机,称为机器语言级虚拟机。

ISA 定义了机器语言级虚拟机的属性和功能特性,主要包括以下信息:

  • 可执行的指令集合,包括指令格式,操作种类以及每种操作对应的操作数的相应规定;
  • 指令可接收的操作数的类型;
  • 操作数或其地址所能存放的寄存器组的结构,包括每个寄存器的名称,编号,长度和用途;
  • 操作数所能存放的存储空间的大小和编制方式;
  • 操作数在存储空间存放时按照大端方式还是小端方式存放;
  • 指令获取操作数以及下一条指令的方式,即寻址方式;
  • 指令执行过程的控制方式,包括程序计数器,条件码定义等。

生成机器代码的过程

通常,将一个 C 语言程序转换为可执行目标代码的过程分为 4 个步骤:

  1. 预处理:在预处理截断对带有 # 开头的语句进行处理,在源程序中插入所有用 #include 命令指定的文件和用 #define 声明指定的宏。
  2. 编译:将预处理后的源程序编译生成相应的汇编语言程序。
  3. 汇编:由汇编程序将汇编语言转换为可重定向的机器语言目标代码文件。
  4. 链接:由链接器将多个可重定位的机器语言目标文件以及库文件链接起来,生成最终的可执行文件。

源程序文件后缀名为 .c,所包含的头文件后缀名为 .h;预处理过的源文件后缀名为 .i;汇编语言源程序后缀名为 .s;编译后的可重定向文件后缀名为 .o,最终生成的可执行代码文件没有后缀。

寄存器与寻址方式

寄存器

第三章:程序的转换

IA-32 中的定点寄存器中共有 8 个通用寄存器,2 个专用寄存器和 6 个段寄存器。

  • 8 个通用寄存器的长度为 32 位,其中 EAX, EBX, ECX, EDX 主要用来存放操作数,可根据操作数长度是字节,字还是双子来确定存取寄存器的最低 8 位,16 位还是全部 32位。ESP, EBP, ESI, EDI 主要用来存放变址值或指针。ESP 是栈顶指针,EBP 是栈底指针。
  • 2 个专用寄存器分别是指令指针寄存器 EIP 和标志寄存器 EFLAGS。IP 与程序计数器 PC 是功能完全一样的寄存器,名称不同而已。EFLAGS 內有各种标志信息,用来记录操作数的状态。常见的标志信息有:
    • OF:溢出标志,反映带符号数的运算结果是否超过相应数值范围。
    • SF:符号标志,反映带符号数运算结果的符号。
    • CF:进/借位标志,反映无符号整数加减运算后的进借位情况。
    • DF:方向标志,用来确定串操作指令执行时编制寄存器 ESI 和 EDI 中的内容时自增还是自减。
    • IF:中断允许标志。IF 对非屏蔽中断和内部异常不起作用,仅对外部可屏蔽中断起作用。
    • TF:陷阱标志,用来控制单步执行操作。

寻址方式

根据指令给定的信息得到操作数或操作数地址的方式称为寻址方式。

立即寻址是指指令中直接给出操作数;寄存器寻址指指令中给出操作数所存放的寄存器的编号。除了立即寻址和寄存器寻址外,其他寻址方式下的操作数都在存储单元中,也称为存储器操作胡。

第三章:程序的转换

指令系统概述

数据类型

c 语言基本数据类型和 IA-32 操作数类型的对应关系:

c 语言声明 Intel 操作数类型 汇编指令长度后缀 存储长度(字节)
(unsigned) char 整数/字节 b 1b
(unsigned) short 整数/字 w 2b
(unsigned) int 整数/双字 l 4b
(unsigned) long int 整数/双字 l 4b
(unsigned) long long int 8b
char * 整数/双字 l 4b
float 单精度浮点数 s 4b
double 双精度浮点数 l 8b
long double 扩展精度浮点数 t 10b~12b

在表中,可以看出双字整数和双精度浮点数的长度后缀都一样,因为已经通过指令操作码区分了是浮点数还是整数,所以长度后缀相同不会产生歧义。

C 语言程序的基本数据类型主要由以下几类:

  1. 指针或地址:用来表示字符串或其他数据区域的指针或存储地址,可声明为 char * 等类型,其宽度为 32 位,对应 IA-32 的双字。
  2. 序数,位串:用来表示序号,元素个数,元素总长度,位串等的无符号数。
  3. 带符号整数:是 C 语言应用最广泛的基本数据类型,可声明位 char,short,int,long 等。
  4. 浮点数:用来表示实数,可声明为 float,double 和 long double 等。

指令类型

1. 传送指令

传送指令用于寄存器,存储单元或 I/O 端口之间传送信息。

通用数据传送指令:

  • MOV:一般的传送指令,包括 movb(字节传送),movw(单字传送),movl(双字传送);
  • MOVS:符号扩展传送指令,将短的源数据按高位符号扩展后传送到目的地址,如 movzwl 表示把一个字节进行符号扩展后送到一个字地址中。
  • MOVZ:零扩展传送指令,将短的源数据按高位零扩展后传送到目的地址。
  • XCHG:数据交换指令,将两个寄存器内容互换。
  • PUSH:压栈操作,先将栈下移一个单元,为新进成员让出空间,然后再把新进成员放进来。
  • POP:出栈操作,先将栈顶成员算到目的寄存器中,再上移缩小栈空间。

地址传送指令:LEA 指令,主要是加载有效地址,用来将源操作数的存储地址送到目的寄存器中。

输入输出指令:专门用于累加器和 I/O 端口之间进行数据传送。例如:in 指令用于将 I/O 端口内容送至累加器,out 指令将累加器内容送至 I/O 端口。

标志传送指令:标志传送指令专门用于对标志寄存器进行操作。如 pushf 指令用于将标志寄存器的内容压栈,popf 指令将栈顶内容送至标志寄存器。

2. 定点算术运算指令

  1. 加/减运算指令:ADD/SUB。用于对给定长度的两个位串进行相加或相减,两个操作数中最多只有一个是存储器操作数,不区分是无符号数还是带符号整数,产生的和/差送到目的地址,生成的标志信息送到标志寄存器 EFLAGS。
  2. 增/减运算指令:INC/EDC。对给定长度的一个位串加一或减一,给定的操作数既是源操作数,也是目的操作数。
  3. 取负指令:NEG。用于求操作数的负数。
  4. 比较指令:CMP。用于两个寄存器操作数的比较,用目的操作数减去源操作数,结果不送回目的操作数,即两个操作数保持不变,只是标志位作相应改变,因而类似于 SUB 指令。
  5. 乘法指令:
    • 无符号数乘:MUL。只能明显给出一个操作数。
    • 带符号数乘:IMUL。可以明显给出一个,两个或三个操作数。

    若指令只给出一个操作数,则另一个源操作数隐含再累加器 EAX 中。对于 MUL 指令,若乘积高 n 位为全 0,则标志 OF 和 CF 皆为 0,否则皆为 1。对于 IMUL 指令,若乘积的高 n 位为全 0 或全 1,并且等于低 n 位中的最高位,则 OF 和 CF 皆为 0,否则皆为 1。

  6. 除法指令:
    • 无符号数除:DIV。
    • 有符号数除:IDIV

    指令中只能明显指出除数,用累加器 EAX,EDX 存放被除数。若源操作数(除数)是 32 位,则 64 位被除数隐含在 EDX-EAX 寄存器中,计算后的商在 EAX,余数在 EDX。

3. 按位运算指令

逻辑运算指令:

  1. NOT:单操作数取反指令,将操作数每一位取反,然后把结果送回对应位。
  2. AND:对双操作数进行按位逻辑“与”,主要用来实现“掩码”操作。
  3. OR:对双操作数进行按位逻辑“或”,常用于使目的操作时的特定位置为 1.
  4. XOR:对双操作数进行按位逻辑“异或”,常用于判断两个操作数中哪些位不同或用于改变指定位的值。
  5. TEST:根据两个操作数相“与”的结果来设置标志位,常用于检测某种条件但不能改变源操作数的场合。

移位指令:

  1. SHL:逻辑左移,每左移一次,最高位送入 CF,并在低位补 0。
  2. SHR:逻辑右移,每右移一次,最低位送入 CF,并在低位补 0。
  3. SAL:算术左移,操作与 SHL 类似,每次移位,最高位送入 CF,并在低位补 0.执行 SAL 指令使,如果移位前后符号位发生变化,则 OF=1,表示左移后结果溢出。这是 SAL 与 SHL 的不同之处。
  4. SAR:算术右移,每右移一次,操作数的最低位送入 CF,并在高位补符号位。
  5. ROL:循环左移,每左移一次,最高位移到最低位,并送入 CF。
  6. ROR:循环右移,每右移一次,最低位移到最高位,并送入 CF。
  7. RCL:带循环左移,将 CF 作为操作数的一部分循环左移。
  8. RCR:带循环右移,将 CF 作为操作数的一部分循环右移。

4. 控制转移指令

无条件转移指令:JMP。无条件转移到转移目标地址处执行。

条件转移指令:以条件标志或者条件标志位的逻辑运算结果作为转移依据。

第三章:程序的转换

条件设置指令:SET。用来将条件标志组合得到的条件值设置到一个 8 位通用寄存器中。

条件传送指令:CMOV。如果符合条件就进行传送操作,佛则什么都不做。

调用指令:CALL。是一种无条件转移指令,跳转方式与 JMP 指令类似,它具有两个功能:

  1. 将返回地址入栈(相当于 PUSH 操作)
  2. 跳转到指定地址处执行。

返回指令:RET。是一种无条件转移指令,是子程序执行后返回主程序继续执行。

5. 浮点处理指令

  1. 浮点装入指令 FLD 用来将存储单元中的浮点数转入到浮点寄存器栈的栈顶。
  2. 浮点存储指令 FST 和 FSTP 用来将浮点寄存器栈顶中的元素存储到存储单元中。

今天的文章第三章:程序的转换分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22615.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注