ICS Notes

ICS Notes

2023年12月22日 作者 ScotI_Blog

why version

第二章:数据的机器级表示与处理

在实际的计算机机器中,机器级数据分为两大类,数值数据和非数值数据,全部的信息都是使用二进制进项编码(因为二稳定性的物理器件实现简单,编码容易,可以方便实用逻辑电路实现算术运算)

真值与机器数:

– 机器数:用0和1编码的计算机内部的0/1序列

– 真值:真正的值,即:现实中带正负

确定一个数值数据的三要素是:
进位计数制、定点or浮点表示、如何使用二进制编码

TIP:浮点数(可用一个定点小数和一个定点整数来表示)

在原码的设计中,存在一些不方便处理的问题,比如0不唯一的表示以及加减运算的不同意,并且在a<b时实现a-b比较困难

在补码的设计中,采取了模运算的概念:
重要概念:在一个模运算系统中,一个数与它除以“模”后的余数等价。

结论1:一个负数的补码等于模减该负数的绝对值。
结论2:对于某一确定的模,某数减去小于模的另一数,总可以用该数加上另一数负数的补码来代替。

变形(4’s)补码:双符号,用于存放可能溢出的中间结果。

移码:将每一个数值加上一个偏置常数(Excess / bias)

关于整数:

机器中字的位排列顺序有两种方式:(例:32位字:0…01011)

– 高到低位从左到右:0000 0000 0000 0000 0000 0000 0000 1011 LSB

– 高到低位从右到左:1101 0000 0000 0000 0000 0000 0000 0000 MSB
M– Leftmost 和 rightmost 这 两 个 词 有 歧 义 , 故 用 LSB(Least Significant Bit)来表示最低有效位,用MSB来表示最高有效位

关于浮点数:

对于一个32位的浮点数而言,第1-8位是阶码E,偏置常数是128,第9~31位为24位二进制原码小数表示的尾数M。规格化尾数的小数点后第一位总是1,故规定第一位默认的“1”不明显表示出来。这样可用23个
数位
表示24位尾数

直到80年代初,各个机器内部的浮点数表示格式还没有统一因而相互不兼容,机器之间传送数据时,带来麻烦
1970年代后期, IEEE成立委员会着手制定浮点数标准
1985年完成浮点数标准IEEE 754的制定

tip:

浮点数除0的结果是+/-∞, 而不是溢出异常.(整数除0为异常)
为什么要这样处理?
∞ :infinity
• 可以利用+∞/-∞作比较。例如:X/0>Y可作为有效比较

关于非规格数:

数据的基本宽度

比特(bit)是计算机中处理存储传输的最小单位

二进制信息最基本的计量单位是字节(Byte)

除比特(位)和字节外,还经常使用“字”(word) 作为单位–“字”和“字长”的概念不同
IA-32中的“字”有多少位?
16位
DWORD :32位
QWORD:64位

数据的存储和排列顺序

80年代开始,几乎所有通用计算机都采用字节编址

在高级语言中声明的基本数据类型有char、short、int、long、long long、float、double、long double等各种不同长度数据

一个基本数据可能会占用多个存储单元
这个时候就需要考虑这些问题:变量的地址是他的最大地址还是最小地址,多个字节存储单元中存放的顺序应该是什么样子的(大端小端方式)

n位加法器无法用于两个n位带符号整数(补码)相加,无法判断是否溢出

程序中经常需要比较大小,通过(在加法器中)做减法得到的标志信息来判断

程序转换概述

在程序执行之前:

数据和指令都实现存放在存储器中,每条指令和每个数据都有地址,指令按序存放,主要由OP/ADDR字段组成,程序起始地址置PC

开始执行程序:

根据PC取指令、指令译码、取操作数、指令执行、回写结果、修改PC的值

汇编指令是机器指令的符号表示(可有不同格式)
mov [bx+di-6], cl movb %cl, -6(%bx,%di)

IA32/x64指令概述

有关寄存器

条件标志用来存放运行的状态信息,控制标志由软件设定,用于中断响应、串操作、单步执行等控制

有关寻址

常用指令类型:

传送指令:

通用数据(指在寄存器或者存储器中的数据)传送指令:MOV一般传送 MOVS(SIGNED) MOVZ(ZERO) XCHG数据交换

地址传送指令:

传送的是操作数的存储地址,制定的目的寄存器不能是段寄存器,且源操作数不能是段寄存器

EBP和ESP是两个用于访问栈内存的寄存器,它们有以下特点:

  • EBP是基址指针寄存器,它指向当前函数的栈底,也就是函数的局部变量和参数的起始地址。通过EBP和偏移量,我们可以访问函数的任意变量或参数。
  • ESP是栈指针寄存器,它指向当前函数的栈顶,也就是最新压入栈的数据的地址。通过ESP,我们可以访问栈顶的数据,或者向栈中压入或弹出数据。

EBP和ESP在函数调用的过程中会发生变化,以保持栈的结构和数据的正确性。一般来说,函数调用的前后,EBP和ESP的变化如下:

  • 函数调用前,先将参数压入栈中,然后将返回地址压入栈中,再将当前的EBP压入栈中,最后将ESP赋值给EBP,作为新函数的栈底。
  • 函数返回前,先将EBP赋值给ESP,恢复栈顶的位置,然后将栈顶的数据弹出给EBP,恢复原函数的栈底,再将栈顶的数据弹出给EIP,恢复原函数的返回地址,最后将参数从栈中弹出,清理栈空间。

lea指令是一种数据传送指令,它的全称是load effective address,即装入有效地址。它的作用是将一个内存地址或一个算术表达式的结果直接赋给目的操作数,而不是将内存地址中的内容赋给目的操作数

虚拟内存

第1讲 分页存储管理的基本概念
第2讲 虚拟存储器及虚拟地址空间
第3讲 分页存储管理的实现
第4讲 存储器层次结构及其访问过程
第5讲 段式和段页式虚拟存储管理
第6讲存储保护

例如,当时的一种典型计算机,其指令中给出的主存地址为16位而主存容量只有4K字,则指令可寻址范围是多少?地址空间为0、1、2…、65535组成的地址集合,即地址空间大小为216。程序员编写程序的空间(地址空间,可寻址空间)比执行程序的空间(主存容量)大得多,怎么自动执行程序呢?

Paging(分页)

· 内存被分为固定长度且比较小的存储块(页框、实页、物理页)

· 每个进程也被划分为固定长的程序块(页,虚页,逻辑页)

· 程序块也可装到存储器中可用的存储块中

逻辑地址(Logical Address):

物理地址(Physical Address,简称PA)

实现虚拟存储器管理,需考虑:
#块大小(在虚拟存储器中“块”被称为“页/ Page”)应多大?
#主存与辅存的空间如何分区管理?
#程序块/ 存储块之间如何映像?
#逻辑地址和物理地址如何转换,转换速度如何提高?
#主存与辅存之间如何进行替换(与Cache所用策略相似)?
#页表如何实现,页表项中要记录哪些信息?
#如何加快访问页表的速度?
#如果要找的内容不在主存,怎么办?
#如何保护进程各自的存储区不被其他进程访问?

-为什么与cache相比页大小比Cache中的blcok大得多?且采用全相连映射?

缺页开销过大导致的。因此,页命中率比cache命中率更重要!“大页面”和“全相联”可提高页命中率。
且使用软件来处理缺页问题(硬件太慢)、使用write Back写策略(避免慢速的磁盘访问操作)、地址转换使用硬件实现(加快指令执行)

此图片的alt属性为空;文件名为image-55.png

在信息访问中可能出现的异常情况:

1)缺页

当有效位为0(Valid)需要从磁盘读到内存,如果没有空间需要替换(类似于cache的替换策略)

2)保护违例

存取权限和指定的具体操作不相符合(R R/W X(execute only))

在页表的读取过程中,我们会发现一次存储器引用需要访问2-3次主存
解释:

综上所述,一次存储器引用要访问主存的次数,至少为0次,至多为3次,具体情况如下:

  • 如果缓存命中,快表命中,页表或段表命中,不需要访问主存,访问次数为0次。
  • 如果缓存缺失,快表命中,页表或段表命中,需要访问主存一次,访问次数为1次。
  • 如果缓存缺失,快表缺失,页表或段表命中,需要访问主存两次,访问次数为2次。
  • 如果缓存缺失,快表缺失,页表或段表缺失,需要访问主存两次,外存一次,访问次数为3次。

因此引入TLB快表来加快地址转译

因为页大小是8KB,所以虚拟地址的0-12bit作为页内地址偏移。TLB表有64项,所以虚拟地址的13-18bit作为TLB表项的索引。假如虚拟地址的13-18bit是1,那么就会查询TLB的第1项,从中取出标识,与虚拟地址的19-31位作比较,如果相等,表示TLB命中,反之,表示TLB失靶。TLB失靶时,可以由硬件将需要的页表项加载入TLB,也可由软件加载,具体取决于处理器设计,OR1200没有提供硬件加载页表项的功能,只能由软件实现。TLB命中时,此时翻译得到的物理地址就是TLB第1项中的标识(即物理地址13-31位)与虚拟地址0-12bit的结合。在地址翻译的过程中还会结合TLB项中的辅助信息判断是否发生违反安全策略的情况,比如:要修改某一页,但该页是禁止修改的,此时就违反了安全策略,会触发异常。

例子:一个简化的存储系统

分段式虚拟存储器

  • 程序员或OS将程序模块或数据模块分配给不同的主存段,一个大程序有多个代码段和多个数据段构成,是按照程序的逻辑结构划分而成的多个相对独立的部分。(例如,代码段、只读数据段、可读写数据段等)
  • 段通常带有段名或基地址,便于编写程序、编译器优化和操作系统调度管理
  • 分段系统将主存空间按实际程序中的段来划分,每个段在主存中的位置记录在段表中,并附以“段长”项
  • 段表由段表项组成,段表本身也是主存中的一个可再定位段

IA-32的寻址方式

逻辑地址向线性地址转换:

逻辑地址向线性地址转换举例:

已知变量y和数组a都是int型,a的首地址为0x8048a00。假设编译器将a的首地址分配在ECX中,数组的下标变量i分配在EDX中,y分配在EAX中,C语言赋值语句“y=a[i];”被编译为指令“movl (%ecx, %edx, 4),%eax”。若在IA-32/Linux环境下执行指令地址为0x80483c8的该指令时,CS段寄存器对应的描述符cache中存放的是表6.2中所示的用户代码段信息且CPL=3,DS段寄存器对应的描述符cache中存放的是表6.2中所示的用户数据段信息,则当i=100时,取指令操作过程中MMU得到的指令的线性地址是多少?取数操作过程中MMU得到的操作数的线性地址是多少?

线性地址向物理地址转换

线性地址空间划分:4GB=1K个子空间* 1K个页面/子空间* 4KB/页

程序的执行顺序与中断

正常控制流

按顺序取下一条指令执行;
通过CALL/RET/Jcc/JMP等指令跳转到转移目标地址处执行

异常控制流

用户模式和内核模式:

为了使OS能够起到管理程序执行的目的,在一些时候处理
器中必须运行内核代码

  • 为了区分处理器运行的是用户代码还是内核代码,必须有一个状态位来标识,这个状态位称为模式位
  • 处理器模式分用户模式(用户态)和内核模式(核心态)
  • 用户模式(也称目态、用户态)下,处理器运行用户进程,此时不允许使用特权指令
  • 内核模式(有时称系统模式、管理模式、超级用户模式、管态、内核态、核心态)下处理器运行内核代码,允许使用特权指令,例如:停机指令、开/关中断指令、Cache冲刷指令等。

处理异常的三种方式:

故障(fault) :执行指令引起的异常事件,如溢出、非法指令、缺页、访问越权等。
“断点”为发生故障指令的地址
自陷(Trap) :预先安排的事件(“埋地雷”),如单步跟踪、断点、系统调用(执行访管指令) 等。是一种自愿中断。“断点”为自陷指令下条指令地址
终止(Abort) :硬故障事件,此时机器将“终止”,调出中断服务程序来重启操作系统。“断点”是什么?随便!

异常举例:

“异常”按处理方式分为故障、自陷和终止三类

ELF可重定位目标文件

  • 可被链接(合并)生成可执行文件或共享目标文件
  • 静态链接库文件由若干个可重定位目标文件组成
  • 包含代码、数据(已初始化全局变量和局部静态变量.data和未初始
    化的全局变量和局部静态变量.bss)
  • 包含重定位信息(指出哪些符号引用处需要重定位)
  • 文件扩展名为.o(相当于Windows中的.obj文件)

将未初始化变量(.bss节)与已初始化变量(.data节)分开的
好处

– .data节中存放具体的初始值,需要占磁盘空间– .bss节中无需存放初始值,只要说明.bss中的每个变量将来在执行时占用几个字节即可,因此,.bss节实际上不占用磁盘空间,提高了磁盘空间利用率

链接操作的步骤

1)确定符号引用关系(符号解析)
2)合并相关.o文件
3)确定每个符号的地址
4)在指令中填入新地址

注意一点:局部变量temp分配在栈中,不会在过程外被引用,因此不是符号定义

符号解析:

目的:将每个模块中引用的符号与某个目标模块中的定义符号建立关联。

符号解析也称符号绑定

指被分配了存储空间。为函数名即指其代码所在区;为变量名即指其所占的静态数据区。所有定义符号的值就是其目标所在的首地址

数名和已初始化的全局变量名是强符号– 未初始化的全局变量名是弱符号

Print Friendly, PDF & Email