程序的机器级表示3

关键点:过程、调试、指针

过程1.运行时栈2.转移控制3.数据传递4.栈上的局部存储5.寄存器中的局部存储空间理解指针使用GDB调试器

过程

1.运行时栈

  x86-64的栈向低地址方向增长,而栈指针%rsp指向低地址方向增长,而栈指针%rsp指向栈顶元素。可以用pishq和popq指令将数据存入栈中或是从栈中取出。将栈指针减小一个适当的量可以为没有指定初始值的数据在栈上分配空间。类似地,可以通过增加栈指针来释放空间
  当x86-64过程需要的存储空间超出寄存器能够存放的大小时,就会在栈上分配空间。这个部分称为过程的栈帧(statck fram)。如图给出了运行时栈的通用结构,包括把它划分为栈帧,当前正在执行的过程帧总是在栈顶。当过程P调用过程Q时,会把返回地址压入栈中,指明当Q返回时要从P程序的哪个位置继续执行。我们把这个返回地址当做P的栈帧的一部分,因为它存放的是与P相关的状态。Q的代码会扩展到当前栈的边界,分配它的栈帧所需要的空间(可以保存寄存器的值、分配局部变量空间,为它调用的过程设置参数)

2.转移控制

  将控制函数从P转移到函数Q,只需要简单地把程序计数器(PC)设置为Q的代码的起始位置。当从Q返回的时候,处理器必须记录好它需要继续P的执行的代码位置。在x86-64机器中,这个信息是通过call指令调用过程记录。

  • call Label: 过程调用
  • call *operand :过程调用(间接调用)

3.数据传递

  在x86-64中,可以通过寄存器最多传递6个整型参数。寄存器的使用有特殊的顺序,寄存器使用的名字取决于要传递的数据类型大小。


  如果一个函数有大于6个整型参数,超出6个部分就要通过栈来传递。假设过程P调用过程Q,有n个整型参数,且。那么,p的代码栈帧必须要能容纳7到n号参数的存储空间,要把参数1~6复制到对应的寄存器,参数7~n放到栈上,而参数7位于栈顶。通过栈传递参数时,所有的数据大小都向8的倍数对齐。

 1void proc(long  a1,long  *a1p,
2          int   a2,int   *a2p,
3          short a3,short *a3p,
4          char  a4,char  *a4p)
5{
6    *a1p += a1;
7    *a2p += a2;
8    *a3p += a3;
9    *a4p += a4;
10}
11//反汇编
12/**
13*a1  in %rdi       (64bits)
14*a1p in %rsi       (64bits)
15*a2  in %edx       (32bits)
16*a2p in %rcx       (64bits)
17*a3  in %r8w       (16bits)
18*a3p in %r9        (64bits)
19*a4  at %rsp + 8   (8bits)
20*a4p at %rsp + 16  (64bits)
21*/
220000000000000000 <proc>:
23   0:    48 8b 44 24 10          mov(q)    0x10(%rsp),%rax;//%rax = ((%rsp)+16) 即取出参数ap4的值存入寄存器(%rax = a4p)
24   5:    48 01 3e                add(q)    %rdi,(%rsi);//*a1p+=a1;
25   8:    01 11                   add(l)    %edx,(%rcx);//*a2p+=a2;
26   a:    66 45 01 01             add(w)    %r8w,(%r9); //*a3p+=a3;
27   e:    8b 54 24 08             mov(l)    0x8(%rsp),%edx;//%edx = ((%rsp)+8) 将参数a4的的值存入%edx寄存器中
28  12:    00 10                   add(b)    %dl,(%rax);%dl取%edx低8位,*a4p+=a4;
29  14:    c3                      retq   
30
310000000000000015 <main>:
32  15:    b8 00 00 00 00          mov    $0x0,%eax
33  1a:    c3                      retq  

4.栈上的局部存储

  大都数过程示例都不需要超出寄存器大小的本地存储区域,不过有些时候,局部数据必须存放在内存中,常见的情况有:

  • 寄存器不足够存放所有本地数据。
  • 对一个局部变量使用地址运算符&,因此必须能够为它产生一个地址。
  • 某些局部变量是数组或者结构,因此必须能够通过数组或者结构引用被访问到。
      一般来说,过程通过减小栈指针在栈上分配空间。分配的结果作为栈帧的一部分,标号为“局部变量”。
 1long swap_add(long *xp,long *yp)
2{
3    long x = *xp;
4    long y = *yp;
5    *xp = y;
6    *yp = x;
7    return x + y;
8}
9long caller()
10{
11    long arg1 = 534;
12    long arg2 = 1057;
13    long sum = swap_add(&arg1,&arg2);
14    long diff = arg1 - arg2;
15    return sum * diff;
16}
17//反汇编
18caller:
19    subq    $16, %rsp ;  //%rsp-16 分配栈空间(2*8)*8bits
20    movq    $534,(%rsp); //arg1 = 534
21    movq    $1057,8(%rsp);//arg2 = 1057 %rsp-8
22    leaq    8(%rsp),%rsi; //加载%rsp+8地址到arg2
23    moveq   %rsp, %rdi;   //加载%rsp地址到arg1
24    call    swap_add;     //call swap_add(&arg1,&arg2)
25    movq    (%rsp), %rdx; //获取arg1的值存入%rdx
26    subq    8(%rsp), %rdx;//diff = arg1 - arg2
27    imulq   %rdx, %rax;   //%rax = %rax * diff
28    addq    $16,%rsp;     //释放栈空间
29    ret                   //return %rax     

5.寄存器中的局部存储空间

  寄存器组是唯一被所有过程共享的资源。虽然在给定的时刻只有一个过程是活动的,我们仍然必须确保当一个过程(调用者)调用另一个过程(被调用者)时,被调用者不会覆盖调用者稍后会使用的寄存器值。为此,x86-64采用了一组统一的寄存器使用惯例,所有的过程(包括程序库)都必须遵循。
  根据惯例,寄存器%rbx、%rbp和%r12~%r15被划为被调用者保存的寄存器。当过程P调用Q时,Q必须保存这些寄存器的值,保证它们的值在Q返回到P时与Q被调用时是一样的。

理解指针

  • 每个指针都对应一个类型。
  • 每个指针都有一个值。这个值是某个指定对象的地址。
  • 指针用'&'运算符创建
  • *操作符用于间接引用指针。
  • 数组与指针紧密联系。
  • 将指针从一种类型强制转成另外一种类型,只改变它的类型,而不改变它的值。
  • 指针也可以指向函数。

使用GDB调试器

  linux下通过命令启动GDB。gdb xxx。下图为GDB的一些常用命令

CSAPP:第三章程序的机器级表示3的更多相关文章

  1. CSAPP:第三章程序的机器级表示2

    CSAPP:程序的机器级表示2 关键点:算术.逻辑操作 算术逻辑操作1.加载有效地址2.一元二元操作3.移位操作 算术逻辑操作   如图列出了x86-64的一些整数和逻辑操作,大多数操作分成了指令类( ...

  2. CSAPP:第三章程序的机器级表示1

    CSAPP:程序的机器级表示1 关键点:数据格式.操作数指示符. 数据格式访问信息操作数指示符举例说明 数据格式   术语字(word)表示16位数据类型,32位数为双字(double words), ...

  3. 【CSAPP】三、程序的机器级表示

    本章基于两种相关的机器语言:Intel IA32和x86-64,前者注重32位,后者注重64位. 本章脉络:c\汇编\机器码之间的关系,数据的表示,控制结构如何实现.运行栈,局部变量的存储,数据结构. ...

  4. 深入理解计算机系统 第三章 程序的机器级表示 Part2 第二遍

    第一遍对应笔记链接 https://www.cnblogs.com/stone94/p/9943779.html 本章汇编代码中常出现的几个指令及其含义 1.push 操作数的个数:1 将操作数(一般 ...

  5. 深入理解计算机系统 第三章 程序的机器级表示 part1

    如题所示,这一章讲解了程序在机器中是怎样表示的,主要讲汇编语言与机器语言. 学习什么,为什么学,以及学了之后有什么用 我们不用学习如何创建机器级的代码,但是我们要能够阅读和理解机器级的代码. 虽然现代 ...

  6. 深入理解计算机系统 第三章 程序的机器级表示 Part1 第二遍

    第一遍对应笔记链接 https://www.cnblogs.com/stone94/p/9905345.html 机器级代码 计算机系统使用了多种不同形式的抽象,利用更简单的抽象模型来隐藏实现的细节. ...

  7. 【CSAPP】第三章 程序的机器级表示

    目录 1. 数据的编码与存储 2. 汇编指令 2.1 数据传送指令 访存方式 数据传送指令 入栈出栈 2.2 算术/逻辑指令 2.3 过程控制指令 控制码 比较指令 跳转指令 条件设置指令 3. 程序 ...

  8. 深入理解计算机系统 第三章 程序的机器级表示 part2

    这周由于时间和精力有限,只读一小节:3.4.4  压入和弹出栈数据 栈是一种特殊的数据结构,遵循“后进先出”的原则,可以用数组实现,总是从数组的一端插入和删除元素,这一端被称为栈顶. 栈有两个常用指令 ...

  9. 深入理解计算机系统 第三章 程序的机器级表示 part3

    这周看了刘老师提供的相关视频,以及书中对应的章节“3.7 过程” 这一节分为运行时栈.转移控制.数据传送.栈上的局部存储.寄存器中的局部存储空间和递归过程这 6 个小节 其中前 3 小节看懂了一部分内 ...

随机推荐

  1. C#设计模式之十八状态模式(State Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西,那就是对象.有对象当然就 ...

  2. 用grunt进行ES6转换,再用uglify压缩所有js实例

    1.首先安装node.js 去官网下载exe执行文件安装即可,安装完成后自带有npm管理. 2.安装grunt CLI 在项目根文件夹下执行如下代码: npm install -g grunt-cli ...

  3. js中判断空及获取当前服务的根路径

    function isValue(o) { return (this.isObject(o) || this.isString(o) || this.isNumber(o) || this.isBoo ...

  4. Python入门基础之变量和数据类型

    在Python中,能够直接处理的数据类型有以下几种: 一.整数 Python可以处理任意大小的整数,当然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如:1,100,-80 ...

  5. Linux PCI设备驱动的实现思路与思想

    概述 1.PCI设备一般都具有双重身份,一方面作为PCI设备注册到Linux内核,另一方面,作为字符设备或者块设备,或者网络设备注册到Linux内核,所以,在看PCI设备时一定要注意到这点. 2. 一 ...

  6. Spring整合ActiveMq消息队列

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久 ...

  7. 【Spring源码解读】bean标签中的属性(一)你可能还不够了解的 scope 属性

    scope 属性说明 在spring中,在xml中定义bean时,scope属性是用来声明bean的作用域的.对于这个属性,你也许已经很熟悉了,singleton和prototype信手捏来,甚至还能 ...

  8. 章节七、6-Map集合的区别

    一.通过entrySet取出Map中的元素 package ZangJie7; import java.util.HashMap; import java.util.Map; public class ...

  9. 关于一体机外卖单不打印外卖单号FAQ(适用正餐6.0.09,轻餐4.0.6.1,轻餐4.0.6.2)

    适用情景:升级版本后打印机打印出的外卖小票不出现外卖单号. 解决方案:设置-功能设置-小票设置-小票自定义-前台小票-外卖订单-------选择编辑,选中右侧中外卖单号或者外卖订单编号,点击保存即可. ...

  10. sublime text 3 优化配置

    目录 1. sublime text 3 模板插件 SublimeTmpl 配置 修改模板内容格式 修改快捷键 2. 设置sublime text的 TAB 为4个空格 3. 添加markdown支持 ...