计算机系统基础 第三章

程序转换概述

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

指令集体系结构

称为机器语言级虚拟机
其规定的内容:数据类型及格式,指令格式,寻址方式和可访问地址空间大小,程序可访问的GPR个数,位数,编号,控制寄存器的定义,I/O控件的编址方式,中断结构,机器工作状态的定义和转换,输入/输出结构和数据传送方式,存储保护方式,由此可见ISA是指软件能感知到的部分,也称软件可见部分

IA-32指令系统概述

数据类型及其机器格式

在这里插入图片描述

寄存器组织和寻址方式

IA-32有8个通用寄存器,两个专用寄存器和6个段寄存器
EAX,EBX,ECX,EDX主要用来存放操作数,可根据操作数长度是字节,字还是双字确定存取寄存器的最低8位,16位或32位
ESP,EBP,ESI,EDI主要用来存放变址值或指针
ESP是栈指针寄存器,EBP为基址指针寄存器
两个专用寄存器:EIP为指令指针寄存器,EFLAGS为标志寄存器
标志寄存器:
6个条件标志:
OF SF ZF CF AF(辅助进位,在BCD码才有用),PF(奇偶标志)
3个控制标志:
DF(direction):方向标志,自动变址方向是增还是减
IF(interrupt):中断允许标志,仅对外部屏蔽中断有用
TF(trap):陷阱标志,判断是否是单步跟踪状态

寻址方式:根据指令给定信息得到操作数或操作数地址的方式
立即寻址:指令中直接给出操作数
寄存器寻址:指令中给出操作数所存放的寄存器的编号
其他的寻址方式下的操作数都在存储单元中,称为存储器操作数

处理器有两种工作方式:

  1. 实地址模式(基本不用):寻址空间:1MB 20位地址 (CS)<< 4+(IP)
  2. 保护模式:加电后进入,采用虚拟存储管理,多任务情况下隔离保护
    80286以上微处理器工作模式
    寻址空间232B(4GB),32位线性地址分段(段基址+段内偏移量也就是有效地址)

加电前为实地址模式(系统启动时)

机器指令格式

指令段的字节数:

  • 操作码:1 2 3
  • 寻址方式: 0 1
  • SIB:0 1
  • 位移:0 1 2 4
  • 立即数:0 1 2 4

SIB中基址B和编址I都可是8个GPR中任一个,SS给出比例因子
操作码:W:与机器模式(16/32位)一起确定寄存器位数(AL/AX/EAX),D:操作方向(确定源和目标)
寻址方式(ModRM字节):mod,r/m,reg/op三个字段与w字段和机器模式一起确定操作数所在的寄存器编号或有效地址计算方式

IA-32常用指令及其操作

1)传送指令
–通用数据传送指令

                MOV:一般传送,包括movb、movw和movl等

                MOVS:符号扩展传送,如movsbw、movswl等(有符号数)

                MOVZ:零扩展传送,如movzwl、movzbl等(无符号数)

                XCHG:数据交换(两个寄存器的内容)

                PUSH/POP:入栈/出栈,如pushl,pushw,popl,popw等

      –地址传送指令

                LEA:加载有效地址,如leal (%edx,%eax), %eax”的功能为R[eax]←R[edx]+R[eax],执行前,若R[edx]=i,可                                    以做无符号的加法 

                R[eax]=j,则指令执行后,R[eax]=i+j

      –输入输出指令

                IN和OUT:I/O端口与寄存器之间的交换

      –标志传送指令

                PUSHF、POPF:将EFLAG压栈,或将栈顶内容送EFLAG

备注:b:字节,w:字(2个字节),l:双字(4个字节)

(2)定点算术运算指令
–加 / 减运算(影响标志、不区分无/带符号)

               ADD:加,包括addb、addw、addl等

               SUB:减,包括subb、subw、subl等

      –增1 / 减1运算(影响除CF以外的标志、不区分无/带符号)

               INC:加,包括incb、incw、incl等

               DEC:减,包括decb、decw、decl等

      –取负运算(影响标志、若对0取负,则结果为0且CF=0, 否则CF=1)

               NEG:取负,包括negb、negw、negl等

      –比较运算(做减法得到标志、不区分无/带符号)

               CMP:比较,包括cmpb、cmpw、cmpl等

      –乘 / 除运算(区分无/带符号)

               MUL / IMUL:无符号乘 / 带符号乘(影响标志OF和CF)

               DIV/ IDIV:带无符号除 / 带符号除

(3)整数乘除指令
乘法指令:可给出一个、两个或三个操作数

若给出一个操作数SRC,则另一个源操作数隐含在AL/AX/EAX中,将SRC和累加器内容相乘,结果存放在AX(16 位)或DX-AX(32位)或EDX-EAX(64位)中。DX-AX表示32位乘积的高、低16位分别在DX和AX中。 n位× n位=2n位
若指令中给出两个操作数DST和SRC,则将DST和SRC相乘,结果在DST中。n位× n位=n位
若指令中给出三个操作数REG、SRC和IMM,则将SRC和立即数IMM相乘,结果在REG中。n位× n位=n位
除法指令:只明显指出除数

若为8位,则16位被除数在AX寄存器中,商送回AL,余数在AH
若为16位,则32位被除数在DX-AX寄存器中,商送回AX,余数在DX
若为32位,则被除数在EDX-EAX寄存器中,商送EAX,余数在EDX

5)定点算术运算指令汇总
逻辑运算(仅NOT不影响标志,其他指令OF=CF=0,而ZF和SF根据结果设置:若全0,则ZF=1;若最高位为1,则SF=1 )NOT:非,包括 notb、notw、notl等
AND:与,包括 andb、andw、andl等
OR:或,包括 orb、orw、orl等
XOR:异或,包括 xorb、xorw、xorl等
TEST:做“与”操作测试,仅影响标志
移位运算(左/右移时,最高/最低位送CF)

SHL/SHR:逻辑左/右移,包括 shlb、shrw、shrl等
SAL/SAR:算术左/右移,左移判溢出,右移高位补符
(移位前、后符号位发生变化,则OF=1 )
ROL/ROR: 循环左/右移,包括 rolb、rorw、roll等
RCL/RCR: 带循环左/右移,将CF作为操作数一部分循环移位

(6)控制转移指令
指令执行可按顺序 或 跳转到转移目标指令处执行

无条件转移指令

JMP DST:无条件转移到目标指令DST处执行
条件转移

Jcc DST:cc为条件码,根据标志(条件码)判断是否满足条件,若满足,则转移到目标指令DST处执行,否则按顺序执行
条件设置

SETcc DST:将条件码cc保存到DST(通常是一个8位寄存器 )
调用和返回指令 (用于过程调用)

CALL DST:返回地址RA入栈,转DST处执行
RET:从栈中取出返回地址RA,转到RA处执行
在这里插入图片描述

C语言程序的机器级表示

P是调用者,Q是被调用者
过程调用的执行步骤:

  1. P将入口参数(实参)放在Q能访问的地方
  2. P保存返回地址,然后将控制转移到Q,call指令
  3. Q保存P的现场,并为自己的非静态局部变量分配空间
  4. 执行Q的过程体 处理阶段
  5. Q回复Q的现场,释放局部变量空间
  6. Q去除返回地址,将控制转移到P

保留现场的原因:所有过程共享一套GPRs

使用约定:
P保存寄存器 EAX,EDX,ECX
Q可以直接使用这三个寄存器
若P在从Q返回还要用的话,P应在转到Q之前先保存,并在从Q返回后先回复它们的值再使用

EBP:帧指针寄存器(栈帧的底部)
ESP:栈指针寄存器(顶部)有参数和返回地址

复杂数据类型的分配和访问

数组的分配和访问

地址:&A[0]+2*i
movw 0(%edx ,%ecx,2)%ax
edx是基址,ecx是变址,2为系数

auto型数组的初始化和访问:
movl $10 -8(%ebp)
08048908 [buf]
08048908:0A000000(小端)

数组和指针在这里插入图片描述
数组指针和多维数组:
存储类型 数据类型 *指针数组名[元素个数]
数组指针每个元素都是指针,每个元素指向的目标数据类型相同

结构体数据的分配和访问

分配在栈中的auto型变量,首地址由EBP或ESP定位
分配在静态区的变量,首地址十一个确定的静态区地址

按值传递时:结构成员都要复制到栈中参数区,既增加时间又增加空间开销(需要复制到栈中)
按地址传递时:仅需传递指向结构体的指针而不需要复制每个成员到栈中,所以一般按地址传递
(*stu_info_ptr)name可写成stu_info_ptr->name

联合体数据的分配和访问

各成员共享存储空间,按最大长度成员所需大小为准

数据的对齐

#pragma pack(n)
为编译器制定结构体或类内部的成员变量的对其方式
当自然边界(如int按照4字节)比n大时,按照n字节对齐
缺省或# pragma pack()按照自然边界对齐

attribute((aligned(m)))
为编译器指定一个结构体或类或联合体或一个单独变量的对齐方式
必须按照m字节而对齐(m为2n),占用大小也是m的整数倍以保证在申请连续空间时各元素也按照m字节对齐

attribute((packed))
不按边界对齐,称为紧凑方式

越界访问和缓冲区溢出

缓冲区溢出

超越数组存储区范围的写入操作(结束符‘\0’算一个字节,char类型有)
造成缓冲区溢出的原因是,没有对栈中作为缓冲区的数组的访问进行越界检查

缓冲区溢出攻击

通过execve()函数加载并执行程序
int execve(char *filename,char *argv[],*envg[]);
若错误(即找不到filename),则返回-1并将控制权交给调用程序
若成功过,则将控制权传递到main中

X86-64

X86-64基本指令和对齐

数据传送指令(助记符“q”表示操作数长度为四字(即64位))
movabsq I, R:将64位立即数送64位通用寄存器
movq:传送一个64位的四字
movsbq、movswq、movslq:将源操作数进行符号扩展并传送
到一个64位寄存器或存储单元中
movzbq、movzwq:将源操作数进行零扩展后传送到一个64位寄
存器或存储单元中
movl:的功能相当于movzlq指令
pushq S:R[rsp]←R[rsp]-8; M[R[rsp]] ←S
popq D: D← M[R[rsp]]; R[rsp]←R[rsp]-8

常规的算术逻辑运算指令
只要将原来IA-32中的指令扩展到64位即可。例如:
– addq(四字相加)
– subq(四字相减)
– incq(四字加1)
– decq(四字减1)
– imulq(带符号整数四字相乘)
– orq(64位相或)
– salq(64位算术左移)
– leaq(有效地址加载到64位寄存器)

X86-64的过程调用

和IA-32差不多
不同点:最多有六个整形或指针型参数通过寄存器传递,超过六个只能通过栈来传递
在函数中尽量使用RAX,R10,R11,若使用RBX,RBP,R12,R13,R14,R15则需要将它们先保存在栈中在使用,最后返回前再恢复其值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值