深入理解android卷3_深入理解计算机系统 第3章-程序的机器级表达

计算机只执行机器代码,用字节序列编码低级的操作。

编译器(compiler)基于编程语言的规则、目标机器的指令集和操作系统的惯例,将编程语言生成汇编代码。汇编代码是机器代码的文本表示。

然后汇编器(assembler)和连接器生成机器代码

用高级语言编写的程序可以在不同机器上编译和执行,而汇编代码则与特定机器有关。

1. 程序编码

机器级编程用抽象模型来隐藏实现的细节,主要有 2 种抽象:

  • 指令集体系结构(Instruction Set Architecture,ISA)来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式和每条指令对状态的影响。
  • 机器级程序使用的内存地址是虚拟地址,看上去是一个字节数组。存储器系统的实现是将多个硬件存储器和操作系统软件相结合。

汇编代码非常接近机器代码,但它用可读性更好的文本格式表示。

处理器(CPU)状态:

  • 程序计数器(PC):给出下一条要执行的指令在内存中的地址;
  • 整数寄存器文件:存储地址(指针)或整数数据。
    • 有的用来记录重要的程序状态;
    • 有的用来保存临时数据,如过程参数、局部变量或函数返回值;
  • 条件码寄存器:保存最近执行的算术或逻辑指令的状态信息;用来实现控制数据流中的条件变化,如 if 或 while;
  • 向量寄存器:存放一个或多个整数或浮点数值;

编程语言中的任何数据类型,在机器代码中都用一组连续的字节来表示。

程序内存

  • 程序的可执行机器代码;
  • 操作系统需要的信息;
  • 用来管理过程调用和返回的运行时栈;
  • 用户分配的内存块;

操作系统负责管理虚拟地址空间,将虚拟地址翻译成实际处理器内存中的物理地址。

一条机器指令只执行一个基本的操作,如将存放在寄存器中的两个数字相加,在存储器和寄存器之间传送数据。

编译器必须产生机器指令的序列,从而实现程序结构(如算术表达式求值或循环)。

2. 访问信息

一个中央处理单元(CPU)包含16个存储64位值的通用目的寄存器,用来存储整数数据和指针。

0a65902095d9bfeb2b0fb61fd313affc.png

2.1. 操作数指示符

大多数指令有一个或多个操作数(operand),指示出执行一个操作中要用到的源数据值和放置结果的目的位置。

操作数分为 3 个类型:

  • 立即数(immediate),表示常数值;
  • 寄存器(register),表示某个寄存器的内容;
    • 这里将寄存器集合看成是数组,用寄存器标识符来作为索引;
  • 内存引用,根据计算出来的地址访问某个内存位置;

2.2. 压入和弹出栈数据

栈(stack)是一种数据结构,可以添加或删除值。

栈遵循后进先出(first in,last out)原则,通过push把数据压入栈中,pop弹出数据。

栈可以由数组实现,从数组的一段插入和删除值,这一端称为栈顶(stack top)

将一个4字节的值压入栈,栈指针减8,然后值写入新的栈顶地址。

弹出该值时,寄存器读取该值,栈指针加8,但值任在原来的地址。

3. 算术和逻辑操作

操作指令有 4 种:

  • 加载有效地址;
  • 一元操作,1 个操作数;
  • 二元操作,2 个操作数;
  • 移位;

加载有效地址(load effective address)是从内存读取数据到寄存器,但实际上不从指定的位置读入数据,而是将有效地址写入操作数。

该指令位后面的内存引用产生指针,还可以简洁的描述普通的算术操作。

一元操作,只有一个操作数,既是源又是目的。这个操作数可以是一个寄存器,也可以是一个内存位置。如++,--。

二元操作,第二个操作数既是源也是目的,如赋值运算符:x-=y;操作数可以是寄存器或内存位置;

当第二个操作数为内存地址时,处理器必须从内存读出值,再把结果写入内存。

4. 过程

过程(process)是软件的一个重要抽象,是一种封装代码的方式。

函数用一组指定的参数和一个可选的返回值实现某种功能,在程序不同的地方调用该函数。

过程隐藏某个行为的具体实现,并提供清晰简洁的接口定义。

过程在不同的编程语言中有不同形式:

  • 函数(function)
  • 方法(method)
  • 子例程(subroutine)
  • 处理函数(handler)

假设过程 P 调用过程 Q,Q 执行后返回到 P,需要以下机制:

  • 传递控制
    • 在进入程序Q时,程序计数器必须设置为Q代码的起始地址;
    • 返回P时,程序计数器设置为P中调用Q后面那条指令的地址;
  • 传递数据:P 向 Q 传递参数,Q 向 P 返回一个值;
  • 分配和释放内存
    • 开始时,Q需要为局部变量分配空间;
    • 返回前,Q必须释放这些存储空间;

4.1. 运行时栈

过程调用的关键是使用了栈数据结构的后进先出内存管理原则。

当过程P调用过程Q时,控制和数据信息被添加到栈尾,当返回P时,这些信息会被释放掉。

栈指针增加或减少,来分配或释放空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值