计算机系统SPOC版

计算机系统课程组@湖南大学

目录

  • 1 计算机系统漫游
    • 1.1 课程介绍
    • 1.2 引论
      • 1.2.1 《计算机系统》概论
      • 1.2.2 计算机简化模型
      • 1.2.3 一个原型系统
    • 1.3 Hello World
      • 1.3.1 基础知识
      • 1.3.2 程序的存储与编译
      • 1.3.3 程序的运行过程
    • 1.4 本章小结
    • 1.5 讨论一:操作环境及GDB;C++与C语言的异同
  • 2 汇编入门
    • 2.1 汇编初步
      • 2.1.1 汇编基础知识
      • 2.1.2 第一个汇编程序
      • 2.1.3 MOV指令
      • 2.1.4 比例变址寻址
      • 2.1.5 绝对寻址
      • 2.1.6 间接寻址
      • 2.1.7 变址寻址
      • 2.1.8 传送数据至内存
      • 2.1.9 获取变量在内存的地址
    • 2.2 汇编进阶
      • 2.2.1 栈操作指令
      • 2.2.2 算术逻辑运算指令
      • 2.2.3 跳转与条件传送
      • 2.2.4 循环指令
    • 2.3 本章小结
    • 2.4 本章拓展
    • 2.5 讨论二:编译环境与整数及浮点数运算
  • 3 位字节与信息存储
    • 3.1 位字节信息存储
    • 3.2 整数的表示与运算
      • 3.2.1 有符号数与无符号数
      • 3.2.2 整数的扩展与截断
      • 3.2.3 整数运算-加法&减法
      • 3.2.4 整数运算-乘法&除法
      • 3.2.5 整数的表示-sizeof代码演示
    • 3.3 浮点数的表示与运算
    • 3.4 本章小结
    • 3.5 讨论三:数据及程序的机器级表示
  • 4 程序的机器级表示
    • 4.1 基本
      • 4.1.1 基础知识
      • 4.1.2 数据传送与寻址方式
      • 4.1.3 算术操作
    • 4.2 控制
      • 4.2.1 条件码
      • 4.2.2 条件分支
      • 4.2.3 循环
      • 4.2.4 Switch
    • 4.3 函数调用
      • 4.3.1 过程与栈帧
      • 4.3.2 sum代码演示
      • 4.3.3 sum调用
      • 4.3.4 嵌套与递归
      • 4.3.5 swap函数及小结
    • 4.4 数据
      • 4.4.1 复杂数据的机器级表达
    • 4.5 X86-64简介
    • 4.6 本章小结
    • 4.7 讨论四:缓冲区溢出攻击;程序,递归、链表的机器级表示
  • 5 CPU设计
    • 5.1 指令集结构及计算机硬件基本组成
      • 5.1.1 指令集结构
      • 5.1.2 计算机硬件基本组成
    • 5.2 RTL语言及其数字系统描述
    • 5.3 CPU设计规范
    • 5.4 VSCPU设计
      • 5.4.1 硬布线方式
      • 5.4.2 微程序控制方式
    • 5.5 自学拓展-RSCPU设计
    • 5.6 拓展-简单CPU的缺点&8085CPU
    • 5.7 讨论五:CPU设计
  • 6 优化程序性能
    • 6.1 基础优化
      • 6.1.1 编译器的局限性
      • 6.1.2 CPE与第一个程序
      • 6.1.3 高级语言层次优化程序性能
    • 6.2 进阶优化
      • 6.2.1 冯诺伊曼体系结构
      • 6.2.2 从机器代码角度优化程序性能
      • 6.2.3 读写相关
      • 6.2.4 阿姆达尔定律
    • 6.3 本章小结
    • 6.4 本章小测
  • 7 存储器层次结构
    • 7.1 存储器层次结构
      • 7.1.1 存储器技术
      • 7.1.2 访问主存
      • 7.1.3 磁盘结构
      • 7.1.4 磁盘访问时间
      • 7.1.5 访问磁盘的过程
      • 7.1.6 存储技术发展趋势
      • 7.1.7 局部性原理
      • 7.1.8 存储器层次结构
    • 7.2 高速缓存
      • 7.2.1 高速缓存概念
      • 7.2.2 基本结构和参数
      • 7.2.3 映射规则
      • 7.2.4 直接映射高速缓存
      • 7.2.5 组相联高速缓存
      • 7.2.6 全相联高速缓存
      • 7.2.7 写入与性能指标
      • 7.2.8 存储器山
      • 7.2.9 空间局部性
      • 7.2.10 时间局部性
    • 7.3 本章小结
    • 7.4 本章小测
    • 7.5 讨论六:程序性能优化
  • 8 链接
    • 8.1 符号解析与目标文件
      • 8.1.1 链接概论
      • 8.1.2 链接工作与符号解析
      • 8.1.3 目标文件
    • 8.2 重定位与库文件
      • 8.2.1 重定位
      • 8.2.2 静态链接库
      • 8.2.3 可执行文件与共享库
    • 8.3 本章小结
    • 8.4 本章小测
    • 8.5 讨论七:神奇的链接器
  • 9 异常控制流
    • 9.1 异常与进程
      • 9.1.1 异常基本概念
      • 9.1.2 异常分类
      • 9.1.3 进程基本概念
      • 9.1.4 进程回收
    • 9.2 信号与非本地跳转
      • 9.2.1 加载运行程序
      • 9.2.2 信号基本概念
      • 9.2.3 信号处理
      • 9.2.4 非本地跳转
    • 9.3 本章小结
  • 10 虚拟存储器
    • 10.1 概念与系统
      • 10.1.1 基本概念
      • 10.1.2 功能
      • 10.1.3 地址翻译
    • 10.2 动态内存分配
    • 10.3 本章小结
    • 10.4 讨论八:进程,信号与虚存
  • 11 拓展学习
    • 11.1 深入理解攻击
      • 11.1.1 SQL注入攻击
      • 11.1.2 键盘记录器
      • 11.1.3 缓冲区溢出攻击
      • 11.1.4 修改返回地址(破解)
      • 11.1.5 直接修改可执行文件
  • 12 课程实验
    • 12.1 数据实验
    • 12.2 炸弹实验
    • 12.3 缓冲区实验
    • 12.4 链接/外壳实验
    • 12.5 Linux GDB和DEBUG初探(选做)
    • 12.6 模型机
    • 12.7 性能实验
    • 12.8 高速缓存实验
讨论四:缓冲区溢出攻击;程序,递归、链表的机器级表示

讨论课实施方法:

每次讨论课布置三道选题,每个班分为六个小组,同一道题有两个小组选择(小组间协商或随机分配)并进行准备。在讨论课时,每道题随机选择一组进行汇报,另外一组或其他组进行质疑与提问。

讨论课的成绩由本组表现及个人表现组成。

第四次讨论课选题

选题一

如下程序pwd.c用于判断输入的密码是否正确

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define PASSWORD "1234567"

int verify(char *password)

{

   int auth;

   char buffer[8];

   auth = strcmp(password, PASSWORD);

   strcpy(buffer, password);

   return auth;

}

int main(void){

    int flag = 0;

    char pass[1024];

    while(1){

        printf("enter the password:\t");

        scanf("%s", pass);

        flag = verify(pass);

        if(flag)

            printf("passwordincorrect!\n");

        else{

           printf("congratulation!\n");

            break;

        }

    }

}

在关闭缓冲区溢出保护后进行编译:(Ubuntu 12.04 32,gcc版本4.6.3

gcc -fno-stack-protector -zexecstack -o pwd.out pwc.c

在命令行输入

./pwd.out运行,

发现输入:1111111112344444等字符串时会提示密码不正确,而在输入qqqqqqqq12355555时会提示密码正确。

请:

(1)分析这些现象产生的原因,并总结规律;

(2)在缺省编译状态下,例如gcc pwd.c -o pwd.out后,运行程序不会产生这样的结果,试从汇编代码这一级别进行解释;

(3)测试其他的c语言编译器(例如windows下的visual studiogcc的低版本2.7.3等)是否有缓冲区溢出保护功能。

 

选题二

小学生小军在学习递归的概念后,很轻松的写出了求菲波拉契数列的c语言代码:

#include"stdio.h"

int f(intn)

{

    if (n<=0) return 0;

    if (n==1 || n==2) return 1;

    return f(n-1)+f(n-2);

}

intmain()

{

    int i=f(5);

    printf("%d\n",i);

    return 0;

}

在得知某些计算机专业的大学生要很费劲才能写出这个程序后,他很骄傲自满,为了让小军明白计算机专业知识的博大精深,我们决定向小军演示整个函数执行过程中栈帧变化情况。

要求:

从进入main函数开始到结束,每一次函数调用都至少有一个栈帧的示意图,并标注栈顶、栈底,局部变量,参数,旧ebp,返回地址等内容,例如:

(具体数值以在本机上的运行情况为准)

 

选题三

小明在《计算机系统》的期末考试复习过程中,预感到老师会出如下的题目,但小明不会做,请告诉小明答案及详细的解题过程。

 

 

请参照汇编代码将如下的c语言程序补充完整:

#include"stdio.h"

#include"stdlib.h"

 

intmain()

{

    int a[]={3,-5,6,7,2,-8,10,2,4};

    struct link

    {

       inti;

       structlink * next;

       structlink * pre;

    }head,*p1,*p2;

    head.i=a[0];

    head.next=NULL;

    head.pre=NULL;

    int j=0;

    p1=__________;

    for(j=1;j<=8;j++)

    {

       p2=(structlink*)malloc(sizeof(head));

       p2->i=______;

       p1->next=p2;

       p2->next=NULL;

       p2->pre=p1;

       p1=p2;

    }

    p1=&head;

    while(p1->next)

    {

       if(__________) 

           ____________;

       else

           p1->i-=p1->next->i;

       printf("%d\n",p1->i);

       p1=p1->next;

    }

    return 0;

}

 

编译后的汇编代码如下:

 

main:

    pushl  %ebp

    movl   %esp,%ebp

    andl   $-16,%esp

    subl   $80,%esp

    movl   $3,20(%esp)

    movl   $-5,24(%esp)

    movl   $6,28(%esp)

    movl   $7,32(%esp)

    movl   $2,36(%esp)

    movl   $-8,40(%esp)

    movl   $10,44(%esp)

    movl   $2,48(%esp)

    movl   $4,52(%esp)

    movl   20(%esp),%eax

    movl   %eax,56(%esp)

    movl   $0,60(%esp)

    movl   $0,64(%esp)

    movl   $0,72(%esp)

    leal   56(%esp),%eax

    movl   %eax,68(%esp)

    movl   $1,72(%esp)

    jmp.L2

.L3:

    movl   $12,(%esp)

    call   malloc

    movl   %eax,76(%esp)

    movl   72(%esp),%eax

    movl   20(%esp,%eax,4),%eax

    movl   %eax,%edx

    imull  72(%esp),%edx

    movl   76(%esp),%eax

    movl   %edx,(%eax)

    movl   68(%esp),%eax

    movl   76(%esp),%edx

    movl   %edx,4(%eax)

    movl   76(%esp),%eax

    movl   $0,4(%eax)

    movl   76(%esp),%eax

    movl   68(%esp),%edx

    movl   %edx,8(%eax)

    movl   76(%esp),%eax

    movl   %eax,68(%esp)

    addl   $1,72(%esp)

.L2:

    cmpl   $8,72(%esp)

    jle.L3

    leal   56(%esp),%eax

    movl   %eax,68(%esp)

    jmp.L4

.L7:

    movl   68(%esp),%eax

    movl   (%eax),%edx

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    movl   (%eax),%eax

    leal   (%edx,%eax),%ecx

    movl   68(%esp),%eax

    movl   (%eax),%edx

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    movl   (%eax),%eax

    imull  %edx,%eax

    movl   %eax,%edx

    shrl   $31,%edx

    addl   %edx,%eax

    sarl   %eax

    cmpl   %eax,%ecx

    jle.L5

    movl   68(%esp),%eax

    movl   (%eax),%edx

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    movl   (%eax),%eax

    addl   %eax,%edx

    movl   68(%esp),%eax

    movl   %edx,(%eax)

    jmp.L6

.L5:

    movl   68(%esp),%eax

    movl   (%eax),%edx

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    movl   (%eax),%eax

    subl   %eax,%edx

    movl   68(%esp),%eax

    movl   %edx,(%eax)

.L6:

    movl   68(%esp),%eax

    movl   (%eax),%edx

    movl   $.LC0,%eax

    movl   %edx,4(%esp)

    movl   %eax,(%esp)

    call   printf

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    movl   %eax,68(%esp)

.L4:

    movl   68(%esp),%eax

    movl   4(%eax),%eax

    testl  %eax,%eax

    jne.L7

    movl   $0,%eax

    leave

    ret