<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>CSAPP-Lab on 夜云泊</title>
    <link>https://lifeislife.cn/categories/csapp-lab/</link>
    <description>feedId:57980998056508425+userId:73222296380546048 Recent content in CSAPP-Lab on 夜云泊</description>
    <generator>Hugo -- 0.161.1</generator>
    <language>zh</language>
    <lastBuildDate>Mon, 11 Jul 2022 09:55:39 +0000</lastBuildDate>
    <atom:link href="https://lifeislife.cn/categories/csapp-lab/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>CSAPP-LAB-Cache Lab</title>
      <link>https://lifeislife.cn/posts/csapp-lab-cache-lab/</link>
      <pubDate>Mon, 11 Jul 2022 09:55:39 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/csapp-lab-cache-lab/</guid>
      <description>&lt;h2 id=&#34;预备知识&#34;&gt;预备知识&lt;/h2&gt;
&lt;p&gt;开始这个实验前，需要学习《CSAPP 第六章-存储器层次结构》的相关内容，与缓存相关的内容，我也做了相关的&lt;a href=&#34;https://dunky-z.github.io/2022/07/10/CPU-Cache%E9%AB%98%E9%80%9F%E7%BC%93%E5%AD%98/&#34;&gt;CPU Cache 高速缓存学习记录&lt;/a&gt;可以参考。&lt;/p&gt;
&lt;p&gt;实验相关的文件可以从&lt;a href=&#34;http://csapp.cs.cmu.edu/3e/labs.html&#34;&gt;CS:APP3e, Bryant and O&amp;rsquo;Hallaron&lt;/a&gt;下载。&lt;/p&gt;
&lt;p&gt;其中，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;README：介绍实验目的和实验要求，以及实验的相关文件。需要注意的是，必须在 64-bit x86-64 system 上运行实验。需要安装 Valgrind 工具。&lt;/li&gt;
&lt;li&gt;Writeup：实验指导。&lt;/li&gt;
&lt;li&gt;Release Notes：版本发布信息。&lt;/li&gt;
&lt;li&gt;Self-Study Handout：&lt;strong&gt;需要下载的压缩包&lt;/strong&gt;，里面包含了待修改的源码文件等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下载 Self-Study Handout 并解压，得到如下文件：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── cachelab.c    &lt;span class=&#34;c1&#34;&gt;# 一些辅助函数，如打印输出等，不需要修改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── cachelab.h    &lt;span class=&#34;c1&#34;&gt;# 同上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── csim.c        &lt;span class=&#34;c1&#34;&gt;# 需要完善的主文件，需要在这里模拟Cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── csim-ref      &lt;span class=&#34;c1&#34;&gt;# 已经编译好的程序，我们模拟的Cache需要与这个程序运行的结果保持一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── driver.py     &lt;span class=&#34;c1&#34;&gt;# 驱动程序，运行 test-csim 和 test-trans&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Makefile      &lt;span class=&#34;c1&#34;&gt;# 用来编译csim程序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── README        &lt;span class=&#34;c1&#34;&gt;# &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── test-csim     &lt;span class=&#34;c1&#34;&gt;# 测试缓存模拟器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── test-trans.c  &lt;span class=&#34;c1&#34;&gt;# 测试转置功能&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── tracegen.c    &lt;span class=&#34;c1&#34;&gt;# test-trans 辅助程序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── traces        &lt;span class=&#34;c1&#34;&gt;# test-csim.c 使用的跟踪文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── dave.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── long.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── trans.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── yi2.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── yi.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── trans.c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20220711145159.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20220711145159.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;part-a--writing-a-cache-simulator&#34;&gt;Part A —— Writing A Cache Simulator&lt;/h2&gt;
&lt;p&gt;在 Part A，我们将在 &lt;code&gt;csim.c&lt;/code&gt; 中编写一个缓存模拟器，它将 &lt;code&gt;valgrind&lt;/code&gt; 内存跟踪作为输入，在此跟踪上模拟高速缓存的命中/未命中行为，并输出命中、未命中和驱逐的总数。&lt;/p&gt;
&lt;p&gt;这里的输入由&lt;code&gt;valgrind&lt;/code&gt;通过以下命令生成的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;valgrind --log-fd&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; --tool&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;lackey -v --trace-mem&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;yes ls -l
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--log-fd=1&lt;/code&gt;表示将输出输出到标准输出；
&lt;code&gt;--tool=lackey&lt;/code&gt;：Lackey 是一个简单的 Valgrind 工具，可进行各种基本程序测量；
&lt;code&gt;--trace-mem=yes&lt;/code&gt;：Lackey 的一个参数，启用后，Lackey 会打印程序几乎所有内存访问的大小和地址；
&lt;code&gt;ls -l&lt;/code&gt;：是一个简单的程序，可以查看当前目录下的文件列表。
也就是检测&lt;code&gt;ls -l&lt;/code&gt;程序在运行时访问内存的情况。&lt;/p&gt;
&lt;p&gt;执行结果像下面的形式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# [space]operation address,size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  0400639c,4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; L 1ffeffec00,8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  040063a0,2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; S 1ffeffea50,8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  040063a2,4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; L 1ffeffebf0,8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  040063a6,3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  040063a9,3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; L 1ffeffebf8,4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  040063ac,7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;操作字段表示内存访问的类型：&lt;code&gt;I&lt;/code&gt;表示指令加载，&lt;code&gt;L&lt;/code&gt;表示数据加载，&lt;code&gt;S&lt;/code&gt;表示数据存储，&lt;code&gt;M&lt;/code&gt;表示数据修改（即，数据加载后跟数据存储） ）。每个&lt;code&gt;I&lt;/code&gt;之前都没有空格。每个&lt;code&gt;M&lt;/code&gt;、&lt;code&gt;L&lt;/code&gt;和&lt;code&gt;S&lt;/code&gt;之前总是有一个空格。地址字段指定一个 &lt;code&gt;64&lt;/code&gt; 位的十六进制内存地址。 &lt;code&gt;size&lt;/code&gt; 字段指定操作访问的字节数。&lt;/p&gt;
&lt;p&gt;了解这些基础后，&lt;strong&gt;我们最主要的是要明确，我们需要实现一个什么样的程序，这个程序具体有哪些参数，怎么执行的&lt;/strong&gt;。&lt;code&gt;csim-ref&lt;/code&gt;是已经完成的可执行文件，它的用法是&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./csim-ref &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-hv&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; -s &amp;lt;s&amp;gt; -E &amp;lt;E&amp;gt; -b &amp;lt;b&amp;gt; -t &amp;lt;tracefile&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-h&lt;/code&gt;：打印帮助信息；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt;：显示详细信息，如是 I，L 还是 M；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s &amp;lt;s&amp;gt;&lt;/code&gt;：组索引位数（$S=2^{s}$组个数）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-E &amp;lt;E&amp;gt;&lt;/code&gt;：关联性（每组的行数）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-b &amp;lt;b&amp;gt;&lt;/code&gt;：块位数（$B=2^{b}$ 是块大小）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t &amp;lt;tracefile&amp;gt;&lt;/code&gt;：valgrind 生成的文件；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./csim-ref -s &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; -E &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -b &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; -t traces/yi.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hits:4 misses:5 evictions:3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果显示详细信息可以执行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./csim-ref -v -s &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; -E &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -b &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; -t traces/yi.trace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;L 10,1 miss
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;M 20,1 miss hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;L 22,1 hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S 18,1 hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;L 110,1 miss eviction
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;L 210,1 miss eviction
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;M 12,1 miss eviction hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hits:4 misses:5 evictions:3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们的目的就是要完善&lt;code&gt;csim.c&lt;/code&gt;，使其能够使用上面相同的参数，得到与&lt;code&gt;csim-ref&lt;/code&gt;相同的结果。
&lt;a href=&#34;http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/recitations/rec07.pdf&#34;&gt;Cache Lab Implementa/on and Blocking&lt;/a&gt;这份 PPT 里有一些实验指导，可以参考。
首先需要解决的就是如何处理输入的参数，我们可以使用 PPT 里提到的&lt;code&gt;getopt&lt;/code&gt;库来解决。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdbool.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;cachelab.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;getopt.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;S&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 组个数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 组占的位数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;E&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hits&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;misses&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;evictions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;typedef&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_CacheLine&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;typedef&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_Cache&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;getopt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;s:E:b:t:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;s&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// 传入的参数为占用的bit，需要转换为10进制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;S&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;E&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;E&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;t&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;strcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;initialize_cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;S&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;S&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;/*!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @breif Add a new CacheLine to the Cache first line
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @param nodeToDel CacheLine to be deleted
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @param curLru  Current Cache
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;insert_first_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;evict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nodeToDel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nodeToDel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodeToDel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nodeToDel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nodeToDel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mask&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0xFFFFFFFF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;maskSet&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mask&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 取出组索引
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetSet&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maskSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 取出标记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetTag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;address&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Cache&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;targetSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 查找是否存与当前标记位相同的缓存行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;found&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;found&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;found&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;hits&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;evict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;insert_first_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;gt; hit!, set: %d &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newNode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;newNode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;E&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 如果缓存已满，则删除最后一个缓存行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;evict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;insert_first_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;evictions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;misses&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;gt; evic &amp;amp;&amp;amp; miss set:%d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;misses&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;insert_first_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curLru&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;gt; miss %d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;targetSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cache_simulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 分配并初始化S组缓存
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;initialize_cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;FILE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fopen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;r&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;fscanf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34; %c %x,%d&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%c, %x %d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;L&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;M&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;S&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nf&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;malloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;parse_option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;cache_simulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;printSummary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;misses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;evictions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<h2 id="预备知识">预备知识</h2>
<p>开始这个实验前，需要学习《CSAPP 第六章-存储器层次结构》的相关内容，与缓存相关的内容，我也做了相关的<a href="https://dunky-z.github.io/2022/07/10/CPU-Cache%E9%AB%98%E9%80%9F%E7%BC%93%E5%AD%98/">CPU Cache 高速缓存学习记录</a>可以参考。</p>
<p>实验相关的文件可以从<a href="http://csapp.cs.cmu.edu/3e/labs.html">CS:APP3e, Bryant and O&rsquo;Hallaron</a>下载。</p>
<p>其中，</p>
<ul>
<li>README：介绍实验目的和实验要求，以及实验的相关文件。需要注意的是，必须在 64-bit x86-64 system 上运行实验。需要安装 Valgrind 工具。</li>
<li>Writeup：实验指导。</li>
<li>Release Notes：版本发布信息。</li>
<li>Self-Study Handout：<strong>需要下载的压缩包</strong>，里面包含了待修改的源码文件等。</li>
</ul>
<p>下载 Self-Study Handout 并解压，得到如下文件：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">├── cachelab.c    <span class="c1"># 一些辅助函数，如打印输出等，不需要修改</span>
</span></span><span class="line"><span class="cl">├── cachelab.h    <span class="c1"># 同上</span>
</span></span><span class="line"><span class="cl">├── csim.c        <span class="c1"># 需要完善的主文件，需要在这里模拟Cache</span>
</span></span><span class="line"><span class="cl">├── csim-ref      <span class="c1"># 已经编译好的程序，我们模拟的Cache需要与这个程序运行的结果保持一致</span>
</span></span><span class="line"><span class="cl">├── driver.py     <span class="c1"># 驱动程序，运行 test-csim 和 test-trans</span>
</span></span><span class="line"><span class="cl">├── Makefile      <span class="c1"># 用来编译csim程序</span>
</span></span><span class="line"><span class="cl">├── README        <span class="c1"># </span>
</span></span><span class="line"><span class="cl">├── test-csim     <span class="c1"># 测试缓存模拟器</span>
</span></span><span class="line"><span class="cl">├── test-trans.c  <span class="c1"># 测试转置功能</span>
</span></span><span class="line"><span class="cl">├── tracegen.c    <span class="c1"># test-trans 辅助程序</span>
</span></span><span class="line"><span class="cl">├── traces        <span class="c1"># test-csim.c 使用的跟踪文件</span>
</span></span><span class="line"><span class="cl">│   ├── dave.trace
</span></span><span class="line"><span class="cl">│   ├── long.trace
</span></span><span class="line"><span class="cl">│   ├── trans.trace
</span></span><span class="line"><span class="cl">│   ├── yi2.trace
</span></span><span class="line"><span class="cl">│   └── yi.trace
</span></span><span class="line"><span class="cl">└── trans.c
</span></span></code></pre></div><p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20220711145159.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20220711145159.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="part-a--writing-a-cache-simulator">Part A —— Writing A Cache Simulator</h2>
<p>在 Part A，我们将在 <code>csim.c</code> 中编写一个缓存模拟器，它将 <code>valgrind</code> 内存跟踪作为输入，在此跟踪上模拟高速缓存的命中/未命中行为，并输出命中、未命中和驱逐的总数。</p>
<p>这里的输入由<code>valgrind</code>通过以下命令生成的：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">valgrind --log-fd<span class="o">=</span><span class="m">1</span> --tool<span class="o">=</span>lackey -v --trace-mem<span class="o">=</span>yes ls -l
</span></span></code></pre></div><p><code>--log-fd=1</code>表示将输出输出到标准输出；
<code>--tool=lackey</code>：Lackey 是一个简单的 Valgrind 工具，可进行各种基本程序测量；
<code>--trace-mem=yes</code>：Lackey 的一个参数，启用后，Lackey 会打印程序几乎所有内存访问的大小和地址；
<code>ls -l</code>：是一个简单的程序，可以查看当前目录下的文件列表。
也就是检测<code>ls -l</code>程序在运行时访问内存的情况。</p>
<p>执行结果像下面的形式：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># [space]operation address,size</span>
</span></span><span class="line"><span class="cl">I  0400639c,4
</span></span><span class="line"><span class="cl"> L 1ffeffec00,8
</span></span><span class="line"><span class="cl">I  040063a0,2
</span></span><span class="line"><span class="cl"> S 1ffeffea50,8
</span></span><span class="line"><span class="cl">I  040063a2,4
</span></span><span class="line"><span class="cl"> L 1ffeffebf0,8
</span></span><span class="line"><span class="cl">I  040063a6,3
</span></span><span class="line"><span class="cl">I  040063a9,3
</span></span><span class="line"><span class="cl"> L 1ffeffebf8,4
</span></span><span class="line"><span class="cl">I  040063ac,7
</span></span></code></pre></div><p>操作字段表示内存访问的类型：<code>I</code>表示指令加载，<code>L</code>表示数据加载，<code>S</code>表示数据存储，<code>M</code>表示数据修改（即，数据加载后跟数据存储） ）。每个<code>I</code>之前都没有空格。每个<code>M</code>、<code>L</code>和<code>S</code>之前总是有一个空格。地址字段指定一个 <code>64</code> 位的十六进制内存地址。 <code>size</code> 字段指定操作访问的字节数。</p>
<p>了解这些基础后，<strong>我们最主要的是要明确，我们需要实现一个什么样的程序，这个程序具体有哪些参数，怎么执行的</strong>。<code>csim-ref</code>是已经完成的可执行文件，它的用法是</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./csim-ref <span class="o">[</span>-hv<span class="o">]</span> -s &lt;s&gt; -E &lt;E&gt; -b &lt;b&gt; -t &lt;tracefile&gt;
</span></span></code></pre></div><ul>
<li><code>-h</code>：打印帮助信息；</li>
<li><code>-v</code>：显示详细信息，如是 I，L 还是 M；</li>
<li><code>-s &lt;s&gt;</code>：组索引位数（$S=2^{s}$组个数）；</li>
<li><code>-E &lt;E&gt;</code>：关联性（每组的行数）；</li>
<li><code>-b &lt;b&gt;</code>：块位数（$B=2^{b}$ 是块大小）；</li>
<li><code>-t &lt;tracefile&gt;</code>：valgrind 生成的文件；</li>
</ul>
<p>如：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./csim-ref -s <span class="m">4</span> -E <span class="m">1</span> -b <span class="m">4</span> -t traces/yi.trace
</span></span><span class="line"><span class="cl">hits:4 misses:5 evictions:3
</span></span></code></pre></div><p>如果显示详细信息可以执行：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./csim-ref -v -s <span class="m">4</span> -E <span class="m">1</span> -b <span class="m">4</span> -t traces/yi.trace
</span></span><span class="line"><span class="cl">L 10,1 miss
</span></span><span class="line"><span class="cl">M 20,1 miss hit
</span></span><span class="line"><span class="cl">L 22,1 hit
</span></span><span class="line"><span class="cl">S 18,1 hit
</span></span><span class="line"><span class="cl">L 110,1 miss eviction
</span></span><span class="line"><span class="cl">L 210,1 miss eviction
</span></span><span class="line"><span class="cl">M 12,1 miss eviction hit
</span></span><span class="line"><span class="cl">hits:4 misses:5 evictions:3
</span></span></code></pre></div><p>我们的目的就是要完善<code>csim.c</code>，使其能够使用上面相同的参数，得到与<code>csim-ref</code>相同的结果。
<a href="http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/recitations/rec07.pdf">Cache Lab Implementa/on and Blocking</a>这份 PPT 里有一些实验指导，可以参考。
首先需要解决的就是如何处理输入的参数，我们可以使用 PPT 里提到的<code>getopt</code>库来解决。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-C" data-lang="C"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;cachelab.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;getopt.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">S</span><span class="p">;</span> <span class="c1">// 组个数
</span></span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">s</span><span class="p">;</span> <span class="c1">// 组占的位数
</span></span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">E</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">B</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">hits</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">misses</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="n">evictions</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">_CacheLine</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="n">tag</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">_CacheLine</span> <span class="o">*</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">_CacheLine</span> <span class="o">*</span><span class="n">prev</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="n">CacheLine</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">_Cache</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">CacheLine</span> <span class="o">*</span><span class="n">head</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">CacheLine</span> <span class="o">*</span><span class="n">tail</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="o">*</span><span class="n">size</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="n">Cache</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">static</span> <span class="n">Cache</span> <span class="o">*</span><span class="n">cache</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">parse_option</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">option</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">((</span><span class="n">option</span> <span class="o">=</span> <span class="nf">getopt</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="s">&#34;s:E:b:t:&#34;</span><span class="p">))</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">switch</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;s&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">s</span> <span class="o">=</span> <span class="nf">atoi</span><span class="p">(</span><span class="n">optarg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// 传入的参数为占用的bit，需要转换为10进制
</span></span></span><span class="line"><span class="cl">            <span class="n">S</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">s</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;E&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">E</span> <span class="o">=</span> <span class="nf">atoi</span><span class="p">(</span><span class="n">optarg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;b&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">B</span> <span class="o">=</span> <span class="nf">atoi</span><span class="p">(</span><span class="n">optarg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;t&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="nf">strcpy</span><span class="p">(</span><span class="o">*</span><span class="n">fileName</span><span class="p">,</span> <span class="n">optarg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">initialize_cache</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">cache</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">S</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">cache</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">S</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">head</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">CacheLine</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">tail</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">CacheLine</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">head</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">tail</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">tail</span><span class="o">-&gt;</span><span class="n">prev</span> <span class="o">=</span> <span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">head</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">size</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="o">*</span><span class="p">(</span><span class="n">cache</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">size</span><span class="p">)</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/*!
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @breif Add a new CacheLine to the Cache first line
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param nodeToDel CacheLine to be deleted
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param curLru  Current Cache
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">insert_first_line</span><span class="p">(</span><span class="n">CacheLine</span> <span class="o">*</span><span class="n">node</span><span class="p">,</span> <span class="n">Cache</span> <span class="o">*</span><span class="n">curLru</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">curLru</span><span class="o">-&gt;</span><span class="n">head</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">node</span><span class="o">-&gt;</span><span class="n">prev</span> <span class="o">=</span> <span class="n">curLru</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">curLru</span><span class="o">-&gt;</span><span class="n">head</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">prev</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">curLru</span><span class="o">-&gt;</span><span class="n">head</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">*</span><span class="p">(</span><span class="n">curLru</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">)</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="n">curLru</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">evict</span><span class="p">(</span><span class="n">CacheLine</span> <span class="o">*</span><span class="n">nodeToDel</span><span class="p">,</span> <span class="n">Cache</span> <span class="o">*</span><span class="n">curLru</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">nodeToDel</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">prev</span> <span class="o">=</span> <span class="n">nodeToDel</span><span class="o">-&gt;</span><span class="n">prev</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">nodeToDel</span><span class="o">-&gt;</span><span class="n">prev</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">nodeToDel</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="o">*</span><span class="p">(</span><span class="n">curLru</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">)</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="n">curLru</span><span class="o">-&gt;</span><span class="n">size</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span><span class="kt">unsigned</span> <span class="n">address</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">mask</span> <span class="o">=</span> <span class="mh">0xFFFFFFFF</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">maskSet</span> <span class="o">=</span> <span class="n">mask</span> <span class="o">&gt;&gt;</span> <span class="p">(</span><span class="mi">32</span> <span class="o">-</span> <span class="n">s</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 取出组索引
</span></span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">targetSet</span> <span class="o">=</span> <span class="p">((</span><span class="n">maskSet</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">address</span> <span class="o">&gt;&gt;</span> <span class="n">B</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 取出标记
</span></span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">targetTag</span> <span class="o">=</span> <span class="n">address</span> <span class="o">&gt;&gt;</span> <span class="p">(</span><span class="n">s</span> <span class="o">+</span> <span class="n">B</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">Cache</span> <span class="n">curLru</span> <span class="o">=</span> <span class="n">cache</span><span class="p">[</span><span class="n">targetSet</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// 查找是否存与当前标记位相同的缓存行
</span></span></span><span class="line"><span class="cl">    <span class="n">CacheLine</span> <span class="o">*</span><span class="n">cur</span> <span class="o">=</span> <span class="n">curLru</span><span class="p">.</span><span class="n">head</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="n">cur</span> <span class="o">!=</span> <span class="n">curLru</span><span class="p">.</span><span class="n">tail</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">cur</span><span class="o">-&gt;</span><span class="n">tag</span> <span class="o">==</span> <span class="n">targetTag</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">cur</span> <span class="o">=</span> <span class="n">cur</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">hits</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nf">evict</span><span class="p">(</span><span class="n">cur</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">curLru</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">insert_first_line</span><span class="p">(</span><span class="n">cur</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">curLru</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;&gt; hit!, set: %d </span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">targetSet</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">CacheLine</span> <span class="o">*</span><span class="n">newNode</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">CacheLine</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">newNode</span><span class="o">-&gt;</span><span class="n">tag</span> <span class="o">=</span> <span class="n">targetTag</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">curLru</span><span class="p">.</span><span class="n">size</span><span class="p">)</span> <span class="o">==</span> <span class="n">E</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 如果缓存已满，则删除最后一个缓存行
</span></span></span><span class="line"><span class="cl">            <span class="nf">evict</span><span class="p">(</span><span class="n">curLru</span><span class="p">.</span><span class="n">tail</span><span class="o">-&gt;</span><span class="n">prev</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">curLru</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">insert_first_line</span><span class="p">(</span><span class="n">newNode</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">curLru</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">evictions</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">misses</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;&gt; evic &amp;&amp; miss set:%d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">targetSet</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">misses</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="nf">insert_first_line</span><span class="p">(</span><span class="n">newNode</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">curLru</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;&gt; miss %d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">targetSet</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">cache_simulate</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 分配并初始化S组缓存
</span></span></span><span class="line"><span class="cl">    <span class="nf">initialize_cache</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">FILE</span> <span class="o">*</span><span class="n">file</span> <span class="o">=</span> <span class="nf">fopen</span><span class="p">(</span><span class="n">fileName</span><span class="p">,</span> <span class="s">&#34;r&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="n">op</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">address</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">size</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="nf">fscanf</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s">&#34; %c %x,%d&#34;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">op</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">size</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;%c, %x %d</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">op</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">switch</span> <span class="p">(</span><span class="n">op</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;L&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="nf">update</span><span class="p">(</span><span class="n">address</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;M&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="nf">update</span><span class="p">(</span><span class="n">address</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="sc">&#39;S&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">            <span class="nf">update</span><span class="p">(</span><span class="n">address</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">char</span> <span class="o">*</span><span class="n">fileName</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="mi">100</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">char</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">parse_option</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">fileName</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">cache_simulate</span><span class="p">(</span><span class="n">fileName</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nf">printSummary</span><span class="p">(</span><span class="n">hits</span><span class="p">,</span> <span class="n">misses</span><span class="p">,</span> <span class="n">evictions</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>CSAPPLAB-Bomb Lab</title>
      <link>https://lifeislife.cn/posts/csapp-lab-bomb-lab/</link>
      <pubDate>Sun, 29 Aug 2021 18:40:16 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/csapp-lab-bomb-lab/</guid>
      <description>&lt;h2 id=&#34;tips&#34;&gt;Tips&lt;/h2&gt;
&lt;h3 id=&#34;缩写注释&#34;&gt;缩写注释&lt;/h3&gt;
&lt;p&gt;CSAPP：Computer Systems A Programmer’s Perspective（深入理解计算机操作系统）。CSAPP（C：P166，O：P278）表示书本的中文版第 166 页，英文原版第 278 页。&lt;/p&gt;
&lt;h3 id=&#34;寄存器信息&#34;&gt;寄存器信息&lt;/h3&gt;
&lt;p&gt;了解寄存器的基本用途，看到一个汇编代码，可以大概了解这个寄存器是在栈中使用的，还是保存参数的，是调用者保存，还是被调用者保存。


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20210830160500.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20210830160500.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;div STYLE=&#34;page-break-after: always;&#34;&gt;&lt;/div&gt;
&lt;h3 id=&#34;gdb&#34;&gt;GDB&lt;/h3&gt;
&lt;p&gt;调试过程用到的 GDB 命令可以先参考&lt;a href=&#34;https://dunky-z.github.io/2021/08/29/GDB%E8%B0%83%E8%AF%95%E5%85%A5%E9%97%A8/&#34;&gt;GDB 调试入门&lt;/a&gt;这篇文章。文中所用例子也是摘自与 BombLab 的源码，更容易理解如何使用。还有一定比较重要的是，如何使用 gdb 带参数调试。为了不用每次运行&lt;code&gt;bomb&lt;/code&gt;程序都需要重新输入答案，&lt;code&gt;bomb&lt;/code&gt;程序可以读取文本信息，在文本文件中写入答案即可免去手动输入。&lt;/p&gt;
&lt;h2 id=&#34;phase_1&#34;&gt;phase_1&lt;/h2&gt;
&lt;p&gt;拆弹专家已上线，开干！！！！！！！！！！！！！&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) b phase_1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) b explode_bomb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas phase_1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function phase_1:&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ee0 &amp;lt;+0&amp;gt;: sub    $0x8,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ee4 &amp;lt;+4&amp;gt;: mov    $0x402400,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ee9 &amp;lt;+9&amp;gt;: callq  0x401338 &amp;lt;strings_not_equal&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400eee &amp;lt;+14&amp;gt;: test   %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ef0 &amp;lt;+16&amp;gt;: je     0x400ef7 &amp;lt;phase_1+23&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ef2 &amp;lt;+18&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ef7 &amp;lt;+23&amp;gt;: add    $0x8,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400efb &amp;lt;+27&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;End of assembler dump.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;3：将栈指针&lt;code&gt;rsp&lt;/code&gt;减去 8 个字节，也就是申请 8 个字节的栈空间&lt;/li&gt;
&lt;li&gt;4：将一个立即数存到寄存器&lt;code&gt;esi&lt;/code&gt;中&lt;/li&gt;
&lt;li&gt;5：调用函数&lt;code&gt;strings_not_equal&lt;/code&gt;，该函数第一条语句的地址为&lt;code&gt;0x401338&lt;/code&gt;。&lt;code&gt;callq&lt;/code&gt;指令的执行过程可参考书本 CSAPP（C：P166，O：P278）&lt;/li&gt;
&lt;li&gt;6：使用&lt;code&gt;test&lt;/code&gt;命令（同&lt;code&gt;and&lt;/code&gt;命令，不修改目标对象的值）来测试&lt;code&gt;eax&lt;/code&gt;中的值是否为&lt;code&gt;0&lt;/code&gt;，如果为&lt;code&gt;0&lt;/code&gt;则跳过引爆炸弹的函数&lt;/li&gt;
&lt;li&gt;7：这一句和上一句是一个整体，如果&lt;code&gt;eax==0&lt;/code&gt;,就跳转到&lt;code&gt;0x400ef7&lt;/code&gt;，这个地址也就是第 9 行的地址，成功跳过了引爆炸弹函数。意思就是我们输入的某个字符串成功匹配，也就是&lt;code&gt;strings_not_equal&lt;/code&gt;函数返回值为 0。&lt;/li&gt;
&lt;li&gt;8：调用函数&lt;code&gt;explode_bomb&lt;/code&gt;，引爆炸弹&lt;/li&gt;
&lt;li&gt;9：将栈指针&lt;code&gt;rsp&lt;/code&gt;加上 8 个字节，也就是恢复 8 个字节的栈空间&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas strings_not_equal 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function strings_not_equal:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=&amp;gt; 0x0000000000401338 &amp;lt;+0&amp;gt;: push   %r12
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040133a &amp;lt;+2&amp;gt;: push   %rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040133b &amp;lt;+3&amp;gt;: push   %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040133c &amp;lt;+4&amp;gt;: mov    %rdi,%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040133f &amp;lt;+7&amp;gt;: mov    %rsi,%rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401342 &amp;lt;+10&amp;gt;: callq  0x40131b &amp;lt;string_length&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401347 &amp;lt;+15&amp;gt;: mov    %eax,%r12d
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040134a &amp;lt;+18&amp;gt;: mov    %rbp,%rdi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040134d &amp;lt;+21&amp;gt;: callq  0x40131b &amp;lt;string_length&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401352 &amp;lt;+26&amp;gt;: mov    $0x1,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401357 &amp;lt;+31&amp;gt;: cmp    %eax,%r12d
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040135a &amp;lt;+34&amp;gt;: jne    0x40139b &amp;lt;strings_not_equal+99&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040135c &amp;lt;+36&amp;gt;: movzbl (%rbx),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040135f &amp;lt;+39&amp;gt;: test   %al,%al
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401361 &amp;lt;+41&amp;gt;: je     0x401388 &amp;lt;strings_not_equal+80&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401363 &amp;lt;+43&amp;gt;: cmp    0x0(%rbp),%al
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401366 &amp;lt;+46&amp;gt;: je     0x401372 &amp;lt;strings_not_equal+58&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401368 &amp;lt;+48&amp;gt;: jmp    0x40138f &amp;lt;strings_not_equal+87&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040136a &amp;lt;+50&amp;gt;: cmp    0x0(%rbp),%al
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040136d &amp;lt;+53&amp;gt;: nopl   (%rax)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401370 &amp;lt;+56&amp;gt;: jne    0x401396 &amp;lt;strings_not_equal+94&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401372 &amp;lt;+58&amp;gt;: add    $0x1,%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401376 &amp;lt;+62&amp;gt;: add    $0x1,%rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040137a &amp;lt;+66&amp;gt;: movzbl (%rbx),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040137d &amp;lt;+69&amp;gt;: test   %al,%al
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040137f &amp;lt;+71&amp;gt;: jne    0x40136a &amp;lt;strings_not_equal+50&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401381 &amp;lt;+73&amp;gt;: mov    $0x0,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401386 &amp;lt;+78&amp;gt;: jmp    0x40139b &amp;lt;strings_not_equal+99&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401388 &amp;lt;+80&amp;gt;: mov    $0x0,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040138d &amp;lt;+85&amp;gt;: jmp    0x40139b &amp;lt;strings_not_equal+99&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040138f &amp;lt;+87&amp;gt;: mov    $0x1,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401394 &amp;lt;+92&amp;gt;: jmp    0x40139b &amp;lt;strings_not_equal+99&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401396 &amp;lt;+94&amp;gt;: mov    $0x1,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040139b &amp;lt;+99&amp;gt;: mov    %edx,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040139d &amp;lt;+101&amp;gt;: pop    %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040139e &amp;lt;+102&amp;gt;: pop    %rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040139f &amp;lt;+103&amp;gt;: pop    %r12
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004013a1 &amp;lt;+105&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;End of assembler dump.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;3-5：在函数调用时先保存相关寄存器值，&lt;code&gt;rbp&lt;/code&gt;和&lt;code&gt;rbx&lt;/code&gt;就是用来保存两个参数的寄存器&lt;/li&gt;
&lt;li&gt;6：将寄存器&lt;code&gt;rdi&lt;/code&gt;的值复制到寄存器&lt;code&gt;rbp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;7：将寄存器&lt;code&gt;rsi&lt;/code&gt;的值复制到寄存器&lt;code&gt;rbx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实看到这里就一直能够猜到答案是什么了。我们通过之前的&lt;code&gt;phase_1&lt;/code&gt;函数能够大概知道需要输入一个值进行比较，如果比较正确就能解除炸弹。现在我们又进入到了这个比较函数，比较函数有两个参数，分别保存在两个寄存器里。我们正常的思维如果写一个比较函数，肯定一个参数是我们输入的值，一个参数是正确的值。&lt;/p&gt;
&lt;p&gt;这里看到了&lt;code&gt;rsi&lt;/code&gt;寄存器，我们还记得在&lt;code&gt;phase_1&lt;/code&gt;函数中第 4 行的&lt;code&gt;esi&lt;/code&gt;寄存器吗？这两个寄存器是同一个寄存器，只不过&lt;code&gt;esi&lt;/code&gt;是寄存器的低 32 位，既然&lt;code&gt;esi&lt;/code&gt;已经赋值了，那剩下的一个参数保存我们输入的内容。所以&lt;code&gt;esi&lt;/code&gt;内存的内容就是我们需要的正确答案。我们只要把寄存器&lt;code&gt;esi&lt;/code&gt;中的值打印出来，或者内存地址为&lt;code&gt;0x402400&lt;/code&gt;的内容打印出来即可。可以通过以下三条命令查看。&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) p (char*)($esi)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$5 = 0x402400 &amp;#34;Border relations with Canada have never been better.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) x/s 0x402400
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0x402400: &amp;#34;Border relations with Canada have never been better.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) x/s $esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0x402400: &amp;#34;Border relations with Canada have never been better.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将答案复制，然后继续运行&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The program being debugged has been started already.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Start it from the beginning? (y or n) y
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Starting program: /home/dominic/learning-linux/bomb/bomb 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Welcome to my fiendish little bomb. You have 6 phases with
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which to blow yourself up. Have a nice day!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Border relations with Canada have never been better.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Breakpoint 2, 0x0000000000400ee0 in phase_1 ()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Single stepping until exit from function phase_1,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which has no line number information.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;main (argc=&amp;lt;optimized out&amp;gt;, argv=&amp;lt;optimized out&amp;gt;) at bomb.c:75
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;75     phase_defused();                 /* Drat!  They figured it out!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;77     printf(&amp;#34;Phase 1 defused. How about the next one?\n&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;从 13 行&lt;code&gt;phase_defused()&lt;/code&gt;可以知道我们已经解除了炸弹，从 15 行&lt;code&gt;printf&lt;/code&gt;函数也可以看到，需要进行下一个炸弹的拆除。过来人的建议，在这里就开始分析&lt;code&gt;phase_2&lt;/code&gt;，寻找答案，因为继续执行就要开始输入内容了，将无法调试。&lt;/p&gt;
&lt;h2 id=&#34;phase_2&#34;&gt;phase_2&lt;/h2&gt;
&lt;p&gt;继续分析第二个炸弹，&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas phase_2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function phase_2:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400efc &amp;lt;+0&amp;gt;: push   %rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400efd &amp;lt;+1&amp;gt;: push   %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400efe &amp;lt;+2&amp;gt;: sub    $0x28,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f02 &amp;lt;+6&amp;gt;: mov    %rsp,%rsi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f05 &amp;lt;+9&amp;gt;: callq  0x40145c &amp;lt;read_six_numbers&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f0a &amp;lt;+14&amp;gt;: cmpl   $0x1,(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f0e &amp;lt;+18&amp;gt;: je     0x400f30 &amp;lt;phase_2+52&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f10 &amp;lt;+20&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f15 &amp;lt;+25&amp;gt;: jmp    0x400f30 &amp;lt;phase_2+52&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f17 &amp;lt;+27&amp;gt;: mov    -0x4(%rbx),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f1a &amp;lt;+30&amp;gt;: add    %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f1c &amp;lt;+32&amp;gt;: cmp    %eax,(%rbx)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f1e &amp;lt;+34&amp;gt;: je     0x400f25 &amp;lt;phase_2+41&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f20 &amp;lt;+36&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f25 &amp;lt;+41&amp;gt;: add    $0x4,%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f29 &amp;lt;+45&amp;gt;: cmp    %rbp,%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f2c &amp;lt;+48&amp;gt;: jne    0x400f17 &amp;lt;phase_2+27&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f2e &amp;lt;+50&amp;gt;: jmp    0x400f3c &amp;lt;phase_2+64&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f30 &amp;lt;+52&amp;gt;: lea    0x4(%rsp),%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f35 &amp;lt;+57&amp;gt;: lea    0x18(%rsp),%rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f3a &amp;lt;+62&amp;gt;: jmp    0x400f17 &amp;lt;phase_2+27&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f3c &amp;lt;+64&amp;gt;: add    $0x28,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f40 &amp;lt;+68&amp;gt;: pop    %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f41 &amp;lt;+69&amp;gt;: pop    %rbp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f42 &amp;lt;+70&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;End of assembler dump.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;3-6：保存程序入口地址，变量等内容，就不再赘述了&lt;/li&gt;
&lt;li&gt;7: 调用&lt;code&gt;read_six_numbers&lt;/code&gt;函数，根据函数名我们可以猜测这个函数需要读入六个数字&lt;/li&gt;
&lt;li&gt;8-9：比较寄存器&lt;code&gt;rsp&lt;/code&gt;存的第一个数字是否等于&lt;code&gt;0x1&lt;/code&gt;，如果等于就跳转到&lt;code&gt;phase_2+52&lt;/code&gt;处继续执行，如果不等于就执行&lt;code&gt;explode_bomb&lt;/code&gt;。栈中保存了六个输入的数字，保存顺序是从右往左，假如输入&lt;code&gt;1,2,3,4,5,6&lt;/code&gt;。那么入栈的顺序就是&lt;code&gt;6,5,4,3,2,1&lt;/code&gt;，寄存器&lt;code&gt;rsp&lt;/code&gt;指向栈顶，也就是数字&lt;code&gt;1&lt;/code&gt;的地址。&lt;/li&gt;
&lt;li&gt;21:假设第一个数字正确，我们跳转到&lt;code&gt;&amp;lt;+52&amp;gt;&lt;/code&gt;位置，也就是第 21 行，将&lt;code&gt;rsp+0x4&lt;/code&gt;写入寄存器&lt;code&gt;rbx&lt;/code&gt;，栈指针向上移动四个字节，也就是取第二个输入的参数，将它赋给寄存器&lt;code&gt;rbx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;22：将&lt;code&gt;rsp+0x18&lt;/code&gt;写入寄存器&lt;code&gt;rbp&lt;/code&gt;，十六进制&lt;code&gt;0x18=24&lt;/code&gt;，4 个字节一个数，刚好 6 个数，就是将输入参数的最后一个位置赋给寄存器&lt;code&gt;rbp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;23：跳到&lt;code&gt;phase_2+27&lt;/code&gt;继续执行&lt;/li&gt;
&lt;li&gt;12：&lt;code&gt;rbx-0x4&lt;/code&gt;赋给寄存器&lt;code&gt;eax&lt;/code&gt;。第 21 行我们知道，&lt;code&gt;rbx&lt;/code&gt;此时已经到第二个参数了，这一句就是说把第一个参数的值写入寄存器&lt;code&gt;eax&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;13：将&lt;code&gt;eax&lt;/code&gt;翻一倍，第 8 行知道第一个参数值为&lt;code&gt;1&lt;/code&gt;，所以此时&lt;code&gt;eax&lt;/code&gt;值为&lt;code&gt;2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;14-15：比较&lt;code&gt;eax&lt;/code&gt;是否等于&lt;code&gt;rbx&lt;/code&gt;。&lt;code&gt;rbx&lt;/code&gt;此时保存的是第二个参数，这里也就是比较第二个参数是否等于&lt;code&gt;2&lt;/code&gt;。如果等于跳转到&lt;code&gt;phase_2+41&lt;/code&gt;位置，如果不等于就调用爆炸函数&lt;/li&gt;
&lt;li&gt;17-18：假设第二个参数就是 2，我们跳过了炸弹来到第 17 行，将&lt;code&gt;rbx&lt;/code&gt;继续上移，然后比较&lt;code&gt;rbp&lt;/code&gt;是否等于&lt;code&gt;rbx&lt;/code&gt;，我们知道&lt;code&gt;rbp&lt;/code&gt;保存了最后一个参数的地址，所以这里的意思就是看看参数有没有到最后一个参数。&lt;/li&gt;
&lt;li&gt;19：如果&lt;code&gt;rbx&amp;lt;rbp&lt;/code&gt;，意思就是还没到最后一个参数，就跳转到&lt;code&gt;phase_2+27&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;12：再次回到第 12 行，这里就是相当于一个循环了，让&lt;code&gt;rbx&lt;/code&gt;一直向上移动，分别存入第 2，3，4，5，6 个参数，在移动到下一个参数时先保存当前参数到寄存器&lt;code&gt;eax&lt;/code&gt;让其翻一倍，然后&lt;code&gt;rbx&lt;/code&gt;再移动到下一个参数，比较&lt;code&gt;eax==rbx&lt;/code&gt;。直到&lt;code&gt;rbx&lt;/code&gt;越过了&lt;code&gt;rbp&lt;/code&gt;。程序跳转到&lt;code&gt;phase_2+64&lt;/code&gt;，将栈空间恢复。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上分析也可以得出答案了，我们只要输入一个以&lt;code&gt;1&lt;/code&gt;为初值，公比为&lt;code&gt;2&lt;/code&gt;，个数为&lt;code&gt;6&lt;/code&gt;的等比数列就是答案，也就是&lt;code&gt;1 2 4 8 16 32&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;gdb&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; c
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Continuing.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Phase &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; defused. How about the next one?
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Breakpoint 6, 0x00000000004015c4 in phase_defused &lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;gdb&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Single stepping &lt;span class=&#34;k&#34;&gt;until&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; from &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; phase_defused,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which has no line number information.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;main &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;optimized out&amp;gt;, &lt;span class=&#34;nv&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;optimized out&amp;gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; at bomb.c:84
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;84&lt;/span&gt;     printf&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;That&amp;#39;s number 2.  Keep going!\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;gdb&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个炸弹的作者应该再心狠手辣一点，把函数名换成&lt;code&gt;read_some_numbers&lt;/code&gt;，这样我们就不得不看这个函数的内容了，因为这个函数里还有一个坑，这个坑在函数名字上一句被填了。那就是这个函数会对参数个数做判断，如果小于 5 就爆炸。&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas read_six_numbers
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function read_six_numbers:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040145c &amp;lt;+0&amp;gt;: sub    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401460 &amp;lt;+4&amp;gt;: mov    %rsi,%rdx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401463 &amp;lt;+7&amp;gt;: lea    0x4(%rsi),%rcx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401467 &amp;lt;+11&amp;gt;: lea    0x14(%rsi),%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040146b &amp;lt;+15&amp;gt;: mov    %rax,0x8(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401470 &amp;lt;+20&amp;gt;: lea    0x10(%rsi),%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401474 &amp;lt;+24&amp;gt;: mov    %rax,(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401478 &amp;lt;+28&amp;gt;: lea    0xc(%rsi),%r9
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040147c &amp;lt;+32&amp;gt;: lea    0x8(%rsi),%r8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401480 &amp;lt;+36&amp;gt;: mov    $0x4025c3,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401485 &amp;lt;+41&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040148a &amp;lt;+46&amp;gt;: callq  0x400bf0 &amp;lt;__isoc99_sscanf@plt&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040148f &amp;lt;+51&amp;gt;: cmp    $0x5,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401492 &amp;lt;+54&amp;gt;: jg     0x401499 &amp;lt;read_six_numbers+61&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401494 &amp;lt;+56&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401499 &amp;lt;+61&amp;gt;: add    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040149d &amp;lt;+65&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;End of assembler dump.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;3：申请 24 个字节栈空间&lt;/li&gt;
&lt;li&gt;4：&lt;code&gt;rdx=rsi&lt;/code&gt;，将输入参数的第一个参数放到寄存器&lt;code&gt;rdx&lt;/code&gt;中，为啥是第一个参数，因为&lt;code&gt;rsi&lt;/code&gt;现在保存的地址是栈顶位置，栈顶目前保存就是第一个参数。&lt;/li&gt;
&lt;li&gt;5：&lt;code&gt;rcx = rsi + 4&lt;/code&gt;，把第二个参数的地址传给寄存器&lt;code&gt;rcx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;6：&lt;code&gt;rax = rsi + 20&lt;/code&gt;，把第六个参数的地址传给寄存器&lt;code&gt;rax&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;7：&lt;code&gt;rsp + 8 = rax&lt;/code&gt;第八个参数&lt;/li&gt;
&lt;li&gt;8：&lt;code&gt;rax = rsi + 16&lt;/code&gt;，把第五个参数传给&lt;/li&gt;
&lt;li&gt;9：&lt;code&gt;rsp = rax&lt;/code&gt;第七个参数&lt;/li&gt;
&lt;li&gt;10：&lt;code&gt;r9 = rsi + 12&lt;/code&gt;把第四个参数传给寄存器&lt;code&gt;r9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;11：&lt;code&gt;r8 = rsi + 8&lt;/code&gt;把第三个参数传给寄存器&lt;code&gt;r8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;12：&lt;/li&gt;
&lt;li&gt;13：&lt;code&gt;eax = 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;14：调用输入函数&lt;code&gt;sscanf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;15-17：函数返回值个数与 5 比较，如果小于 5 就爆炸，否则返回&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;phase_3&#34;&gt;phase_3&lt;/h2&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f43 &amp;lt;+0&amp;gt;: sub    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f47 &amp;lt;+4&amp;gt;: lea    0xc(%rsp),%rcx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f4c &amp;lt;+9&amp;gt;: lea    0x8(%rsp),%rdx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f51 &amp;lt;+14&amp;gt;: mov    $0x4025cf,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f56 &amp;lt;+19&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f5b &amp;lt;+24&amp;gt;: callq  0x400bf0 &amp;lt;__isoc99_sscanf@plt&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f60 &amp;lt;+29&amp;gt;: cmp    $0x1,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f63 &amp;lt;+32&amp;gt;: jg     0x400f6a &amp;lt;phase_3+39&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f65 &amp;lt;+34&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f6a &amp;lt;+39&amp;gt;: cmpl   $0x7,0x8(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f6f &amp;lt;+44&amp;gt;: ja     0x400fad &amp;lt;phase_3+106&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f71 &amp;lt;+46&amp;gt;: mov    0x8(%rsp),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f75 &amp;lt;+50&amp;gt;: jmpq   *0x402470(,%rax,8)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f7c &amp;lt;+57&amp;gt;: mov    $0xcf,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f81 &amp;lt;+62&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f83 &amp;lt;+64&amp;gt;: mov    $0x2c3,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f88 &amp;lt;+69&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f8a &amp;lt;+71&amp;gt;: mov    $0x100,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f8f &amp;lt;+76&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f91 &amp;lt;+78&amp;gt;: mov    $0x185,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f96 &amp;lt;+83&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f98 &amp;lt;+85&amp;gt;: mov    $0xce,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f9d &amp;lt;+90&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400f9f &amp;lt;+92&amp;gt;: mov    $0x2aa,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fa4 &amp;lt;+97&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fa6 &amp;lt;+99&amp;gt;: mov    $0x147,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fab &amp;lt;+104&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fad &amp;lt;+106&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fb2 &amp;lt;+111&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fb7 &amp;lt;+116&amp;gt;: jmp    0x400fbe &amp;lt;phase_3+123&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fb9 &amp;lt;+118&amp;gt;: mov    $0x137,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fbe &amp;lt;+123&amp;gt;: cmp    0xc(%rsp),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fc2 &amp;lt;+127&amp;gt;: je     0x400fc9 &amp;lt;phase_3+134&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fc4 &amp;lt;+129&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fc9 &amp;lt;+134&amp;gt;: add    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fcd &amp;lt;+138&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;1：开辟 24 字节的栈空间&lt;/li&gt;
&lt;li&gt;2：&lt;code&gt;rcx = rsp + 12&lt;/code&gt;第二个参数&lt;/li&gt;
&lt;li&gt;3：&lt;code&gt;rdx = rsp + 8&lt;/code&gt;第一个参数&lt;/li&gt;
&lt;li&gt;4-8：和&lt;code&gt;phase_2&lt;/code&gt;里&lt;code&gt;read_six_numbers&lt;/code&gt;函数中的第 13 行开始一样，输入数据，判断一下输入参数的个数，只不过这里是返回值个数大于 1，如果参数个数正确就跳到&lt;code&gt;phase_3+39&lt;/code&gt;也就是第 10 行，否则引爆炸弹。&lt;/li&gt;
&lt;li&gt;10-11：如果&lt;code&gt;7 &amp;lt; rsp + 8 等价于 7 &amp;lt; rdx 等价于 7 &amp;lt; 第一个参数&lt;/code&gt;就跳转到&lt;code&gt;phase_3+106&lt;/code&gt;，爆炸。这里确定第一个数必须小于 7&lt;/li&gt;
&lt;li&gt;12：&lt;code&gt;eax = rsp + 8 等价于 eax = 第一个参数&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;13：跳转至&lt;code&gt;0x402470 + 8 * rax&lt;/code&gt;处，具体跳转到哪里根据第一个值做判断&lt;/li&gt;
&lt;li&gt;14：&lt;code&gt;eax = 207&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;15：跳转至&lt;code&gt;phase_3+123&lt;/code&gt;,即 32 行&lt;/li&gt;
&lt;li&gt;16：&lt;code&gt;eax = 707&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;17：跳转到 32 行&lt;/li&gt;
&lt;li&gt;18：&lt;code&gt;eax = 256&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;19：跳转到 32 行&lt;/li&gt;
&lt;li&gt;20：&lt;code&gt;eax = 389&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;21-27：以此类推&lt;/li&gt;
&lt;li&gt;29：&lt;code&gt;eax = 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;30：&lt;/li&gt;
&lt;li&gt;31：&lt;code&gt;eax = 311&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;32-34：比较&lt;code&gt;eax&lt;/code&gt;和&lt;code&gt;rsp + 12&lt;/code&gt; 等价于 比较 第二个参数和&lt;code&gt;eax&lt;/code&gt;。如果相等就返回，如果不等就引爆。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分析至此，我们也就知道了程序的大概流程，输入两个值，第一个值必须小于等于 7，第二个值根据第一个值来确定，具体等于多少，根据跳转表确定，因为第一个值有八个数，也就对应着汇编中八段寄存器&lt;code&gt;eax&lt;/code&gt;赋值的过程，我们只要输入第一个合法的数值，然后再打印出寄存器&lt;code&gt;eax&lt;/code&gt;的值，即可确定答案。&lt;/p&gt;
&lt;p&gt;比如我们先测试一下第一个值为 0 时，对应的第二个值为多少，我们输入&lt;code&gt;0  10&lt;/code&gt;，因为只是测试，第二个值任意。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;That&amp;#39;s number 2.  Keep going! //接上个炸弹后面
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;88     input = read_line();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0 10              //输入测试答案
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;89     phase_3(input);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Breakpoint 4, 0x0000000000400f43 in phase_3 ()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Single stepping until exit from function phase_3,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which has no line number information.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Breakpoint 2, 0x000000000040143a in explode_bomb ()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) p $eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$14 = 207         //207即是答案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输入真正答案测试，&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0 207                         //输入答案
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;89     phase_3(input);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Breakpoint 4, 0x0000000000400f43 in phase_3 ()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Single stepping until exit from function phase_3,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which has no line number information.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;main (argc=&amp;lt;optimized out&amp;gt;, argv=&amp;lt;optimized out&amp;gt;) at bomb.c:90
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;90     phase_defused();    //炸弹拆除
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;91     printf(&amp;#34;Halfway there!\n&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们上面说过，第一个值有八种可能，所以这题答案也有八个，我们只要挨个测试&lt;code&gt;0-7&lt;/code&gt;，分别打印出寄存器&lt;code&gt;eax&lt;/code&gt;的值就可以得到所有答案。他们分别是&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0 207
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1 311
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2 707
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3 256
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4 389
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5 206
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6 682
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;7 327
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;phase_4&#34;&gt;phase_4&lt;/h2&gt;
&lt;p&gt;行百里者半九十，NO&lt;/p&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas phase_4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function phase_4:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040100c &amp;lt;+0&amp;gt;: sub    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401010 &amp;lt;+4&amp;gt;: lea    0xc(%rsp),%rcx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401015 &amp;lt;+9&amp;gt;: lea    0x8(%rsp),%rdx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040101a &amp;lt;+14&amp;gt;: mov    $0x4025cf,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040101f &amp;lt;+19&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401024 &amp;lt;+24&amp;gt;: callq  0x400bf0 &amp;lt;__isoc99_sscanf@plt&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401029 &amp;lt;+29&amp;gt;: cmp    $0x2,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040102c &amp;lt;+32&amp;gt;: jne    0x401035 &amp;lt;phase_4+41&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040102e &amp;lt;+34&amp;gt;: cmpl   $0xe,0x8(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401033 &amp;lt;+39&amp;gt;: jbe    0x40103a &amp;lt;phase_4+46&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401035 &amp;lt;+41&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040103a &amp;lt;+46&amp;gt;: mov    $0xe,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040103f &amp;lt;+51&amp;gt;: mov    $0x0,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401044 &amp;lt;+56&amp;gt;: mov    0x8(%rsp),%edi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401048 &amp;lt;+60&amp;gt;: callq  0x400fce &amp;lt;func4&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040104d &amp;lt;+65&amp;gt;: test   %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040104f &amp;lt;+67&amp;gt;: jne    0x401058 &amp;lt;phase_4+76&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401051 &amp;lt;+69&amp;gt;: cmpl   $0x0,0xc(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401056 &amp;lt;+74&amp;gt;: je     0x40105d &amp;lt;phase_4+81&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401058 &amp;lt;+76&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040105d &amp;lt;+81&amp;gt;: add    $0x18,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401061 &amp;lt;+85&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;1-8：开辟空间，保存参数信息，调用输入函数，和上面的分析重复，不再赘述。注意的是第 6 行，&lt;code&gt;x/s 0x4025cf&lt;/code&gt;可知两个参数是整型数值。&lt;/li&gt;
&lt;li&gt;9-10：参数个数必须等于 2，否则引爆&lt;/li&gt;
&lt;li&gt;11-12：&lt;code&gt;14&lt;/code&gt;与&lt;code&gt;rsp + 8&lt;/code&gt;比较，等价于&lt;code&gt;14&lt;/code&gt;与第一个参数比较。表示第一个参数必须小于等于 14，否则引爆。&lt;/li&gt;
&lt;li&gt;14：&lt;code&gt;edx = 14&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;15：&lt;code&gt;esi = 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;16：&lt;code&gt;edi = rsp + 8&lt;/code&gt;即&lt;code&gt;edi = 第一个参数&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;17：调用函数&lt;code&gt;fun4&lt;/code&gt;，参数分别为&lt;code&gt;edi 0 14&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;18：测试返回值是否为 0，如果不为 0，引爆&lt;/li&gt;
&lt;li&gt;20-22：比较&lt;code&gt;0&lt;/code&gt;和&lt;code&gt;rsp + 12&lt;/code&gt;，如果不等，引爆，否则返回&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;(gdb) disas func4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dump of assembler code for function func4:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fce &amp;lt;+0&amp;gt;: sub    $0x8,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fd2 &amp;lt;+4&amp;gt;: mov    %edx,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fd4 &amp;lt;+6&amp;gt;: sub    %esi,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fd6 &amp;lt;+8&amp;gt;: mov    %eax,%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fd8 &amp;lt;+10&amp;gt;: shr    $0x1f,%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fdb &amp;lt;+13&amp;gt;: add    %ecx,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fdd &amp;lt;+15&amp;gt;: sar    %eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fdf &amp;lt;+17&amp;gt;: lea    (%rax,%rsi,1),%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fe2 &amp;lt;+20&amp;gt;: cmp    %edi,%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fe4 &amp;lt;+22&amp;gt;: jle    0x400ff2 &amp;lt;func4+36&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fe6 &amp;lt;+24&amp;gt;: lea    -0x1(%rcx),%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fe9 &amp;lt;+27&amp;gt;: callq  0x400fce &amp;lt;func4&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400fee &amp;lt;+32&amp;gt;: add    %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ff0 &amp;lt;+34&amp;gt;: jmp    0x401007 &amp;lt;func4+57&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ff2 &amp;lt;+36&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ff7 &amp;lt;+41&amp;gt;: cmp    %edi,%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ff9 &amp;lt;+43&amp;gt;: jge    0x401007 &amp;lt;func4+57&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ffb &amp;lt;+45&amp;gt;: lea    0x1(%rcx),%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000400ffe &amp;lt;+48&amp;gt;: callq  0x400fce &amp;lt;func4&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401003 &amp;lt;+53&amp;gt;: lea    0x1(%rax,%rax,1),%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401007 &amp;lt;+57&amp;gt;: add    $0x8,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040100b &amp;lt;+61&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;c1&#34;&gt;// edi = 第一个参数, esi = 0, edx = 14
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt;            &lt;span class=&#34;c1&#34;&gt;// 4:mov %edx, %eax
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;       &lt;span class=&#34;c1&#34;&gt;// 5:sub esi, %eax
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt;            &lt;span class=&#34;c1&#34;&gt;// 6:mov %eax, %ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eсx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;// 7:shr  $0x1f, %ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;// 8:add %ecx, %eax
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//替换eax和ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;       &lt;span class=&#34;c1&#34;&gt;// 9:sar %eax
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// 10:lea (rax,ersi,1), %ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;edx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;esi&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;c1&#34;&gt;// 11:cmp %edi, %ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;// 12:jle 400ff2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;eax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;// mov $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;// 18:cmp %edi, %ecx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ecx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;edi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;c1&#34;&gt;// 19:jge    0x401007 &amp;lt;func4+57&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;c1&#34;&gt;//由此可以得知道 edx == edi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;phase_5&#34;&gt;phase_5&lt;/h2&gt;
&lt;div class=&#34;highlight line-numbers&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401062 &amp;lt;+0&amp;gt;: push   %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401063 &amp;lt;+1&amp;gt;: sub    $0x20,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401067 &amp;lt;+5&amp;gt;: mov    %rdi,%rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040106a &amp;lt;+8&amp;gt;: mov    %fs:0x28,%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401073 &amp;lt;+17&amp;gt;: mov    %rax,0x18(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401078 &amp;lt;+22&amp;gt;: xor    %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040107a &amp;lt;+24&amp;gt;: callq  0x40131b &amp;lt;string_length&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040107f &amp;lt;+29&amp;gt;: cmp    $0x6,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401082 &amp;lt;+32&amp;gt;: je     0x4010d2 &amp;lt;phase_5+112&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401084 &amp;lt;+34&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401089 &amp;lt;+39&amp;gt;: jmp    0x4010d2 &amp;lt;phase_5+112&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040108b &amp;lt;+41&amp;gt;: movzbl (%rbx,%rax,1),%ecx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x000000000040108f &amp;lt;+45&amp;gt;: mov    %cl,(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401092 &amp;lt;+48&amp;gt;: mov    (%rsp),%rdx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401096 &amp;lt;+52&amp;gt;: and    $0xf,%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x0000000000401099 &amp;lt;+55&amp;gt;: movzbl 0x4024b0(%rdx),%edx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010a0 &amp;lt;+62&amp;gt;: mov    %dl,0x10(%rsp,%rax,1)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010a4 &amp;lt;+66&amp;gt;: add    $0x1,%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010a8 &amp;lt;+70&amp;gt;: cmp    $0x6,%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010ac &amp;lt;+74&amp;gt;: jne    0x40108b &amp;lt;phase_5+41&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010ae &amp;lt;+76&amp;gt;: movb   $0x0,0x16(%rsp)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010b3 &amp;lt;+81&amp;gt;: mov    $0x40245e,%esi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      0x00000000004010b8 &amp;lt;+86&amp;gt;: lea    0x10(%rsp),%rdi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010bd &amp;lt;+91&amp;gt;: callq  0x401338 &amp;lt;strings_not_equal&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010c2 &amp;lt;+96&amp;gt;: test   %eax,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010c4 &amp;lt;+98&amp;gt;: je     0x4010d9 &amp;lt;phase_5+119&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010c6 &amp;lt;+100&amp;gt;: callq  0x40143a &amp;lt;explode_bomb&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010cb &amp;lt;+105&amp;gt;: nopl   0x0(%rax,%rax,1)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010d0 &amp;lt;+110&amp;gt;: jmp    0x4010d9 &amp;lt;phase_5+119&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010d2 &amp;lt;+112&amp;gt;: mov    $0x0,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010d7 &amp;lt;+117&amp;gt;: jmp    0x40108b &amp;lt;phase_5+41&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010d9 &amp;lt;+119&amp;gt;: mov    0x18(%rsp),%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010de &amp;lt;+124&amp;gt;: xor    %fs:0x28,%rax
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010e7 &amp;lt;+133&amp;gt;: je     0x4010ee &amp;lt;phase_5+140&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010e9 &amp;lt;+135&amp;gt;: callq  0x400b30 &amp;lt;__stack_chk_fail@plt&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010ee &amp;lt;+140&amp;gt;: add    $0x20,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010f2 &amp;lt;+144&amp;gt;: pop    %rbx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   0x00000000004010f3 &amp;lt;+145&amp;gt;: retq   
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<h2 id="tips">Tips</h2>
<h3 id="缩写注释">缩写注释</h3>
<p>CSAPP：Computer Systems A Programmer’s Perspective（深入理解计算机操作系统）。CSAPP（C：P166，O：P278）表示书本的中文版第 166 页，英文原版第 278 页。</p>
<h3 id="寄存器信息">寄存器信息</h3>
<p>了解寄存器的基本用途，看到一个汇编代码，可以大概了解这个寄存器是在栈中使用的，还是保存参数的，是调用者保存，还是被调用者保存。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20210830160500.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/20210830160500.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<div STYLE="page-break-after: always;"></div>
<h3 id="gdb">GDB</h3>
<p>调试过程用到的 GDB 命令可以先参考<a href="https://dunky-z.github.io/2021/08/29/GDB%E8%B0%83%E8%AF%95%E5%85%A5%E9%97%A8/">GDB 调试入门</a>这篇文章。文中所用例子也是摘自与 BombLab 的源码，更容易理解如何使用。还有一定比较重要的是，如何使用 gdb 带参数调试。为了不用每次运行<code>bomb</code>程序都需要重新输入答案，<code>bomb</code>程序可以读取文本信息，在文本文件中写入答案即可免去手动输入。</p>
<h2 id="phase_1">phase_1</h2>
<p>拆弹专家已上线，开干！！！！！！！！！！！！！</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">(gdb) b phase_1
</span></span><span class="line"><span class="cl">(gdb) b explode_bomb
</span></span><span class="line"><span class="cl">(gdb) disas phase_1
</span></span><span class="line"><span class="cl">Dump of assembler code for function phase_1:&#39;
</span></span><span class="line"><span class="cl">   0x0000000000400ee0 &lt;+0&gt;: sub    $0x8,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400ee4 &lt;+4&gt;: mov    $0x402400,%esi
</span></span><span class="line"><span class="cl">   0x0000000000400ee9 &lt;+9&gt;: callq  0x401338 &lt;strings_not_equal&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400eee &lt;+14&gt;: test   %eax,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400ef0 &lt;+16&gt;: je     0x400ef7 &lt;phase_1+23&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400ef2 &lt;+18&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400ef7 &lt;+23&gt;: add    $0x8,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400efb &lt;+27&gt;: retq   
</span></span><span class="line"><span class="cl">End of assembler dump.
</span></span></code></pre></div><ul>
<li>3：将栈指针<code>rsp</code>减去 8 个字节，也就是申请 8 个字节的栈空间</li>
<li>4：将一个立即数存到寄存器<code>esi</code>中</li>
<li>5：调用函数<code>strings_not_equal</code>，该函数第一条语句的地址为<code>0x401338</code>。<code>callq</code>指令的执行过程可参考书本 CSAPP（C：P166，O：P278）</li>
<li>6：使用<code>test</code>命令（同<code>and</code>命令，不修改目标对象的值）来测试<code>eax</code>中的值是否为<code>0</code>，如果为<code>0</code>则跳过引爆炸弹的函数</li>
<li>7：这一句和上一句是一个整体，如果<code>eax==0</code>,就跳转到<code>0x400ef7</code>，这个地址也就是第 9 行的地址，成功跳过了引爆炸弹函数。意思就是我们输入的某个字符串成功匹配，也就是<code>strings_not_equal</code>函数返回值为 0。</li>
<li>8：调用函数<code>explode_bomb</code>，引爆炸弹</li>
<li>9：将栈指针<code>rsp</code>加上 8 个字节，也就是恢复 8 个字节的栈空间</li>
</ul>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) disas strings_not_equal 
</span></span><span class="line"><span class="cl">Dump of assembler code for function strings_not_equal:
</span></span><span class="line"><span class="cl">=&gt; 0x0000000000401338 &lt;+0&gt;: push   %r12
</span></span><span class="line"><span class="cl">   0x000000000040133a &lt;+2&gt;: push   %rbp
</span></span><span class="line"><span class="cl">   0x000000000040133b &lt;+3&gt;: push   %rbx
</span></span><span class="line"><span class="cl">   0x000000000040133c &lt;+4&gt;: mov    %rdi,%rbx
</span></span><span class="line"><span class="cl">   0x000000000040133f &lt;+7&gt;: mov    %rsi,%rbp
</span></span><span class="line"><span class="cl">   0x0000000000401342 &lt;+10&gt;: callq  0x40131b &lt;string_length&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401347 &lt;+15&gt;: mov    %eax,%r12d
</span></span><span class="line"><span class="cl">   0x000000000040134a &lt;+18&gt;: mov    %rbp,%rdi
</span></span><span class="line"><span class="cl">   0x000000000040134d &lt;+21&gt;: callq  0x40131b &lt;string_length&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401352 &lt;+26&gt;: mov    $0x1,%edx
</span></span><span class="line"><span class="cl">   0x0000000000401357 &lt;+31&gt;: cmp    %eax,%r12d
</span></span><span class="line"><span class="cl">   0x000000000040135a &lt;+34&gt;: jne    0x40139b &lt;strings_not_equal+99&gt;
</span></span><span class="line"><span class="cl">   0x000000000040135c &lt;+36&gt;: movzbl (%rbx),%eax
</span></span><span class="line"><span class="cl">   0x000000000040135f &lt;+39&gt;: test   %al,%al
</span></span><span class="line"><span class="cl">   0x0000000000401361 &lt;+41&gt;: je     0x401388 &lt;strings_not_equal+80&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401363 &lt;+43&gt;: cmp    0x0(%rbp),%al
</span></span><span class="line"><span class="cl">   0x0000000000401366 &lt;+46&gt;: je     0x401372 &lt;strings_not_equal+58&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401368 &lt;+48&gt;: jmp    0x40138f &lt;strings_not_equal+87&gt;
</span></span><span class="line"><span class="cl">   0x000000000040136a &lt;+50&gt;: cmp    0x0(%rbp),%al
</span></span><span class="line"><span class="cl">   0x000000000040136d &lt;+53&gt;: nopl   (%rax)
</span></span><span class="line"><span class="cl">   0x0000000000401370 &lt;+56&gt;: jne    0x401396 &lt;strings_not_equal+94&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401372 &lt;+58&gt;: add    $0x1,%rbx
</span></span><span class="line"><span class="cl">   0x0000000000401376 &lt;+62&gt;: add    $0x1,%rbp
</span></span><span class="line"><span class="cl">   0x000000000040137a &lt;+66&gt;: movzbl (%rbx),%eax
</span></span><span class="line"><span class="cl">   0x000000000040137d &lt;+69&gt;: test   %al,%al
</span></span><span class="line"><span class="cl">   0x000000000040137f &lt;+71&gt;: jne    0x40136a &lt;strings_not_equal+50&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401381 &lt;+73&gt;: mov    $0x0,%edx
</span></span><span class="line"><span class="cl">   0x0000000000401386 &lt;+78&gt;: jmp    0x40139b &lt;strings_not_equal+99&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401388 &lt;+80&gt;: mov    $0x0,%edx
</span></span><span class="line"><span class="cl">   0x000000000040138d &lt;+85&gt;: jmp    0x40139b &lt;strings_not_equal+99&gt;
</span></span><span class="line"><span class="cl">   0x000000000040138f &lt;+87&gt;: mov    $0x1,%edx
</span></span><span class="line"><span class="cl">   0x0000000000401394 &lt;+92&gt;: jmp    0x40139b &lt;strings_not_equal+99&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401396 &lt;+94&gt;: mov    $0x1,%edx
</span></span><span class="line"><span class="cl">   0x000000000040139b &lt;+99&gt;: mov    %edx,%eax
</span></span><span class="line"><span class="cl">   0x000000000040139d &lt;+101&gt;: pop    %rbx
</span></span><span class="line"><span class="cl">   0x000000000040139e &lt;+102&gt;: pop    %rbp
</span></span><span class="line"><span class="cl">   0x000000000040139f &lt;+103&gt;: pop    %r12
</span></span><span class="line"><span class="cl">   0x00000000004013a1 &lt;+105&gt;: retq   
</span></span><span class="line"><span class="cl">End of assembler dump.
</span></span><span class="line"><span class="cl">       
</span></span></code></pre></div><ul>
<li>3-5：在函数调用时先保存相关寄存器值，<code>rbp</code>和<code>rbx</code>就是用来保存两个参数的寄存器</li>
<li>6：将寄存器<code>rdi</code>的值复制到寄存器<code>rbp</code></li>
<li>7：将寄存器<code>rsi</code>的值复制到寄存器<code>rbx</code></li>
</ul>
<p>其实看到这里就一直能够猜到答案是什么了。我们通过之前的<code>phase_1</code>函数能够大概知道需要输入一个值进行比较，如果比较正确就能解除炸弹。现在我们又进入到了这个比较函数，比较函数有两个参数，分别保存在两个寄存器里。我们正常的思维如果写一个比较函数，肯定一个参数是我们输入的值，一个参数是正确的值。</p>
<p>这里看到了<code>rsi</code>寄存器，我们还记得在<code>phase_1</code>函数中第 4 行的<code>esi</code>寄存器吗？这两个寄存器是同一个寄存器，只不过<code>esi</code>是寄存器的低 32 位，既然<code>esi</code>已经赋值了，那剩下的一个参数保存我们输入的内容。所以<code>esi</code>内存的内容就是我们需要的正确答案。我们只要把寄存器<code>esi</code>中的值打印出来，或者内存地址为<code>0x402400</code>的内容打印出来即可。可以通过以下三条命令查看。</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) p (char*)($esi)
</span></span><span class="line"><span class="cl">$5 = 0x402400 &#34;Border relations with Canada have never been better.&#34;
</span></span><span class="line"><span class="cl">(gdb) x/s 0x402400
</span></span><span class="line"><span class="cl">0x402400: &#34;Border relations with Canada have never been better.&#34;
</span></span><span class="line"><span class="cl">(gdb) x/s $esi
</span></span><span class="line"><span class="cl">0x402400: &#34;Border relations with Canada have never been better.&#34;
</span></span></code></pre></div><p>将答案复制，然后继续运行</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">The program being debugged has been started already.
</span></span><span class="line"><span class="cl">Start it from the beginning? (y or n) y
</span></span><span class="line"><span class="cl">Starting program: /home/dominic/learning-linux/bomb/bomb 
</span></span><span class="line"><span class="cl">Welcome to my fiendish little bomb. You have 6 phases with
</span></span><span class="line"><span class="cl">which to blow yourself up. Have a nice day!
</span></span><span class="line"><span class="cl">Border relations with Canada have never been better.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Breakpoint 2, 0x0000000000400ee0 in phase_1 ()
</span></span><span class="line"><span class="cl">(gdb) s
</span></span><span class="line"><span class="cl">Single stepping until exit from function phase_1,
</span></span><span class="line"><span class="cl">which has no line number information.
</span></span><span class="line"><span class="cl">main (argc=&lt;optimized out&gt;, argv=&lt;optimized out&gt;) at bomb.c:75
</span></span><span class="line"><span class="cl">75     phase_defused();                 /* Drat!  They figured it out!
</span></span><span class="line"><span class="cl">(gdb) s
</span></span><span class="line"><span class="cl">77     printf(&#34;Phase 1 defused. How about the next one?\n&#34;);
</span></span></code></pre></div><p>从 13 行<code>phase_defused()</code>可以知道我们已经解除了炸弹，从 15 行<code>printf</code>函数也可以看到，需要进行下一个炸弹的拆除。过来人的建议，在这里就开始分析<code>phase_2</code>，寻找答案，因为继续执行就要开始输入内容了，将无法调试。</p>
<h2 id="phase_2">phase_2</h2>
<p>继续分析第二个炸弹，</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) disas phase_2
</span></span><span class="line"><span class="cl">Dump of assembler code for function phase_2:
</span></span><span class="line"><span class="cl">   0x0000000000400efc &lt;+0&gt;: push   %rbp
</span></span><span class="line"><span class="cl">   0x0000000000400efd &lt;+1&gt;: push   %rbx
</span></span><span class="line"><span class="cl">   0x0000000000400efe &lt;+2&gt;: sub    $0x28,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400f02 &lt;+6&gt;: mov    %rsp,%rsi
</span></span><span class="line"><span class="cl">   0x0000000000400f05 &lt;+9&gt;: callq  0x40145c &lt;read_six_numbers&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f0a &lt;+14&gt;: cmpl   $0x1,(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000400f0e &lt;+18&gt;: je     0x400f30 &lt;phase_2+52&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f10 &lt;+20&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f15 &lt;+25&gt;: jmp    0x400f30 &lt;phase_2+52&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f17 &lt;+27&gt;: mov    -0x4(%rbx),%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f1a &lt;+30&gt;: add    %eax,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f1c &lt;+32&gt;: cmp    %eax,(%rbx)
</span></span><span class="line"><span class="cl">   0x0000000000400f1e &lt;+34&gt;: je     0x400f25 &lt;phase_2+41&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f20 &lt;+36&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f25 &lt;+41&gt;: add    $0x4,%rbx
</span></span><span class="line"><span class="cl">   0x0000000000400f29 &lt;+45&gt;: cmp    %rbp,%rbx
</span></span><span class="line"><span class="cl">   0x0000000000400f2c &lt;+48&gt;: jne    0x400f17 &lt;phase_2+27&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f2e &lt;+50&gt;: jmp    0x400f3c &lt;phase_2+64&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f30 &lt;+52&gt;: lea    0x4(%rsp),%rbx
</span></span><span class="line"><span class="cl">   0x0000000000400f35 &lt;+57&gt;: lea    0x18(%rsp),%rbp
</span></span><span class="line"><span class="cl">   0x0000000000400f3a &lt;+62&gt;: jmp    0x400f17 &lt;phase_2+27&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f3c &lt;+64&gt;: add    $0x28,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400f40 &lt;+68&gt;: pop    %rbx
</span></span><span class="line"><span class="cl">   0x0000000000400f41 &lt;+69&gt;: pop    %rbp
</span></span><span class="line"><span class="cl">   0x0000000000400f42 &lt;+70&gt;: retq   
</span></span><span class="line"><span class="cl">End of assembler dump.
</span></span></code></pre></div><ul>
<li>3-6：保存程序入口地址，变量等内容，就不再赘述了</li>
<li>7: 调用<code>read_six_numbers</code>函数，根据函数名我们可以猜测这个函数需要读入六个数字</li>
<li>8-9：比较寄存器<code>rsp</code>存的第一个数字是否等于<code>0x1</code>，如果等于就跳转到<code>phase_2+52</code>处继续执行，如果不等于就执行<code>explode_bomb</code>。栈中保存了六个输入的数字，保存顺序是从右往左，假如输入<code>1,2,3,4,5,6</code>。那么入栈的顺序就是<code>6,5,4,3,2,1</code>，寄存器<code>rsp</code>指向栈顶，也就是数字<code>1</code>的地址。</li>
<li>21:假设第一个数字正确，我们跳转到<code>&lt;+52&gt;</code>位置，也就是第 21 行，将<code>rsp+0x4</code>写入寄存器<code>rbx</code>，栈指针向上移动四个字节，也就是取第二个输入的参数，将它赋给寄存器<code>rbx</code></li>
<li>22：将<code>rsp+0x18</code>写入寄存器<code>rbp</code>，十六进制<code>0x18=24</code>，4 个字节一个数，刚好 6 个数，就是将输入参数的最后一个位置赋给寄存器<code>rbp</code></li>
<li>23：跳到<code>phase_2+27</code>继续执行</li>
<li>12：<code>rbx-0x4</code>赋给寄存器<code>eax</code>。第 21 行我们知道，<code>rbx</code>此时已经到第二个参数了，这一句就是说把第一个参数的值写入寄存器<code>eax</code></li>
<li>13：将<code>eax</code>翻一倍，第 8 行知道第一个参数值为<code>1</code>，所以此时<code>eax</code>值为<code>2</code></li>
<li>14-15：比较<code>eax</code>是否等于<code>rbx</code>。<code>rbx</code>此时保存的是第二个参数，这里也就是比较第二个参数是否等于<code>2</code>。如果等于跳转到<code>phase_2+41</code>位置，如果不等于就调用爆炸函数</li>
<li>17-18：假设第二个参数就是 2，我们跳过了炸弹来到第 17 行，将<code>rbx</code>继续上移，然后比较<code>rbp</code>是否等于<code>rbx</code>，我们知道<code>rbp</code>保存了最后一个参数的地址，所以这里的意思就是看看参数有没有到最后一个参数。</li>
<li>19：如果<code>rbx&lt;rbp</code>，意思就是还没到最后一个参数，就跳转到<code>phase_2+27</code></li>
<li>12：再次回到第 12 行，这里就是相当于一个循环了，让<code>rbx</code>一直向上移动，分别存入第 2，3，4，5，6 个参数，在移动到下一个参数时先保存当前参数到寄存器<code>eax</code>让其翻一倍，然后<code>rbx</code>再移动到下一个参数，比较<code>eax==rbx</code>。直到<code>rbx</code>越过了<code>rbp</code>。程序跳转到<code>phase_2+64</code>，将栈空间恢复。</li>
</ul>
<p>以上分析也可以得出答案了，我们只要输入一个以<code>1</code>为初值，公比为<code>2</code>，个数为<code>6</code>的等比数列就是答案，也就是<code>1 2 4 8 16 32</code>。</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="o">(</span>gdb<span class="o">)</span> c
</span></span><span class="line"><span class="cl">Continuing.
</span></span><span class="line"><span class="cl">Phase <span class="m">1</span> defused. How about the next one?
</span></span><span class="line"><span class="cl"><span class="m">1</span> <span class="m">2</span> <span class="m">4</span> <span class="m">8</span> <span class="m">16</span> <span class="m">32</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Breakpoint 6, 0x00000000004015c4 in phase_defused <span class="o">()</span>
</span></span><span class="line"><span class="cl"><span class="o">(</span>gdb<span class="o">)</span> s
</span></span><span class="line"><span class="cl">Single stepping <span class="k">until</span> <span class="nb">exit</span> from <span class="k">function</span> phase_defused,
</span></span><span class="line"><span class="cl">which has no line number information.
</span></span><span class="line"><span class="cl">main <span class="o">(</span><span class="nv">argc</span><span class="o">=</span>&lt;optimized out&gt;, <span class="nv">argv</span><span class="o">=</span>&lt;optimized out&gt;<span class="o">)</span> at bomb.c:84
</span></span><span class="line"><span class="cl"><span class="m">84</span>     printf<span class="o">(</span><span class="s2">&#34;That&#39;s number 2.  Keep going!\n&#34;</span><span class="o">)</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="o">(</span>gdb<span class="o">)</span> s
</span></span></code></pre></div><p>这个炸弹的作者应该再心狠手辣一点，把函数名换成<code>read_some_numbers</code>，这样我们就不得不看这个函数的内容了，因为这个函数里还有一个坑，这个坑在函数名字上一句被填了。那就是这个函数会对参数个数做判断，如果小于 5 就爆炸。</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) disas read_six_numbers
</span></span><span class="line"><span class="cl">Dump of assembler code for function read_six_numbers:
</span></span><span class="line"><span class="cl">   0x000000000040145c &lt;+0&gt;: sub    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000401460 &lt;+4&gt;: mov    %rsi,%rdx
</span></span><span class="line"><span class="cl">   0x0000000000401463 &lt;+7&gt;: lea    0x4(%rsi),%rcx
</span></span><span class="line"><span class="cl">   0x0000000000401467 &lt;+11&gt;: lea    0x14(%rsi),%rax
</span></span><span class="line"><span class="cl">   0x000000000040146b &lt;+15&gt;: mov    %rax,0x8(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401470 &lt;+20&gt;: lea    0x10(%rsi),%rax
</span></span><span class="line"><span class="cl">   0x0000000000401474 &lt;+24&gt;: mov    %rax,(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401478 &lt;+28&gt;: lea    0xc(%rsi),%r9
</span></span><span class="line"><span class="cl">   0x000000000040147c &lt;+32&gt;: lea    0x8(%rsi),%r8
</span></span><span class="line"><span class="cl">   0x0000000000401480 &lt;+36&gt;: mov    $0x4025c3,%esi
</span></span><span class="line"><span class="cl">   0x0000000000401485 &lt;+41&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x000000000040148a &lt;+46&gt;: callq  0x400bf0 &lt;__isoc99_sscanf@plt&gt;
</span></span><span class="line"><span class="cl">   0x000000000040148f &lt;+51&gt;: cmp    $0x5,%eax
</span></span><span class="line"><span class="cl">   0x0000000000401492 &lt;+54&gt;: jg     0x401499 &lt;read_six_numbers+61&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401494 &lt;+56&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401499 &lt;+61&gt;: add    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x000000000040149d &lt;+65&gt;: retq   
</span></span><span class="line"><span class="cl">End of assembler dump.
</span></span></code></pre></div><ul>
<li>3：申请 24 个字节栈空间</li>
<li>4：<code>rdx=rsi</code>，将输入参数的第一个参数放到寄存器<code>rdx</code>中，为啥是第一个参数，因为<code>rsi</code>现在保存的地址是栈顶位置，栈顶目前保存就是第一个参数。</li>
<li>5：<code>rcx = rsi + 4</code>，把第二个参数的地址传给寄存器<code>rcx</code></li>
<li>6：<code>rax = rsi + 20</code>，把第六个参数的地址传给寄存器<code>rax</code></li>
<li>7：<code>rsp + 8 = rax</code>第八个参数</li>
<li>8：<code>rax = rsi + 16</code>，把第五个参数传给</li>
<li>9：<code>rsp = rax</code>第七个参数</li>
<li>10：<code>r9 = rsi + 12</code>把第四个参数传给寄存器<code>r9</code></li>
<li>11：<code>r8 = rsi + 8</code>把第三个参数传给寄存器<code>r8</code></li>
<li>12：</li>
<li>13：<code>eax = 0</code></li>
<li>14：调用输入函数<code>sscanf</code></li>
<li>15-17：函数返回值个数与 5 比较，如果小于 5 就爆炸，否则返回</li>
</ul>
<h2 id="phase_3">phase_3</h2>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">   0x0000000000400f43 &lt;+0&gt;: sub    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400f47 &lt;+4&gt;: lea    0xc(%rsp),%rcx
</span></span><span class="line"><span class="cl">   0x0000000000400f4c &lt;+9&gt;: lea    0x8(%rsp),%rdx
</span></span><span class="line"><span class="cl">   0x0000000000400f51 &lt;+14&gt;: mov    $0x4025cf,%esi
</span></span><span class="line"><span class="cl">   0x0000000000400f56 &lt;+19&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f5b &lt;+24&gt;: callq  0x400bf0 &lt;__isoc99_sscanf@plt&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f60 &lt;+29&gt;: cmp    $0x1,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f63 &lt;+32&gt;: jg     0x400f6a &lt;phase_3+39&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f65 &lt;+34&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f6a &lt;+39&gt;: cmpl   $0x7,0x8(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000400f6f &lt;+44&gt;: ja     0x400fad &lt;phase_3+106&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f71 &lt;+46&gt;: mov    0x8(%rsp),%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f75 &lt;+50&gt;: jmpq   *0x402470(,%rax,8)
</span></span><span class="line"><span class="cl">   0x0000000000400f7c &lt;+57&gt;: mov    $0xcf,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f81 &lt;+62&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f83 &lt;+64&gt;: mov    $0x2c3,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f88 &lt;+69&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f8a &lt;+71&gt;: mov    $0x100,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f8f &lt;+76&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f91 &lt;+78&gt;: mov    $0x185,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f96 &lt;+83&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f98 &lt;+85&gt;: mov    $0xce,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400f9d &lt;+90&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400f9f &lt;+92&gt;: mov    $0x2aa,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fa4 &lt;+97&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fa6 &lt;+99&gt;: mov    $0x147,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fab &lt;+104&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fad &lt;+106&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fb2 &lt;+111&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fb7 &lt;+116&gt;: jmp    0x400fbe &lt;phase_3+123&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fb9 &lt;+118&gt;: mov    $0x137,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fbe &lt;+123&gt;: cmp    0xc(%rsp),%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fc2 &lt;+127&gt;: je     0x400fc9 &lt;phase_3+134&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fc4 &lt;+129&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fc9 &lt;+134&gt;: add    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400fcd &lt;+138&gt;: retq   
</span></span></code></pre></div><ul>
<li>1：开辟 24 字节的栈空间</li>
<li>2：<code>rcx = rsp + 12</code>第二个参数</li>
<li>3：<code>rdx = rsp + 8</code>第一个参数</li>
<li>4-8：和<code>phase_2</code>里<code>read_six_numbers</code>函数中的第 13 行开始一样，输入数据，判断一下输入参数的个数，只不过这里是返回值个数大于 1，如果参数个数正确就跳到<code>phase_3+39</code>也就是第 10 行，否则引爆炸弹。</li>
<li>10-11：如果<code>7 &lt; rsp + 8 等价于 7 &lt; rdx 等价于 7 &lt; 第一个参数</code>就跳转到<code>phase_3+106</code>，爆炸。这里确定第一个数必须小于 7</li>
<li>12：<code>eax = rsp + 8 等价于 eax = 第一个参数</code></li>
<li>13：跳转至<code>0x402470 + 8 * rax</code>处，具体跳转到哪里根据第一个值做判断</li>
<li>14：<code>eax = 207</code></li>
<li>15：跳转至<code>phase_3+123</code>,即 32 行</li>
<li>16：<code>eax = 707</code></li>
<li>17：跳转到 32 行</li>
<li>18：<code>eax = 256</code></li>
<li>19：跳转到 32 行</li>
<li>20：<code>eax = 389</code></li>
<li>21-27：以此类推</li>
<li>29：<code>eax = 0</code></li>
<li>30：</li>
<li>31：<code>eax = 311</code></li>
<li>32-34：比较<code>eax</code>和<code>rsp + 12</code> 等价于 比较 第二个参数和<code>eax</code>。如果相等就返回，如果不等就引爆。</li>
</ul>
<p>分析至此，我们也就知道了程序的大概流程，输入两个值，第一个值必须小于等于 7，第二个值根据第一个值来确定，具体等于多少，根据跳转表确定，因为第一个值有八个数，也就对应着汇编中八段寄存器<code>eax</code>赋值的过程，我们只要输入第一个合法的数值，然后再打印出寄存器<code>eax</code>的值，即可确定答案。</p>
<p>比如我们先测试一下第一个值为 0 时，对应的第二个值为多少，我们输入<code>0  10</code>，因为只是测试，第二个值任意。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">That&#39;s number 2.  Keep going! //接上个炸弹后面
</span></span><span class="line"><span class="cl">88     input = read_line();
</span></span><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">0 10              //输入测试答案
</span></span><span class="line"><span class="cl">89     phase_3(input);
</span></span><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">Breakpoint 4, 0x0000000000400f43 in phase_3 ()
</span></span><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">Single stepping until exit from function phase_3,
</span></span><span class="line"><span class="cl">which has no line number information.
</span></span><span class="line"><span class="cl">Breakpoint 2, 0x000000000040143a in explode_bomb ()
</span></span><span class="line"><span class="cl">(gdb) p $eax
</span></span><span class="line"><span class="cl">$14 = 207         //207即是答案
</span></span></code></pre></div><p>输入真正答案测试，</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">0 207                         //输入答案
</span></span><span class="line"><span class="cl">89     phase_3(input);
</span></span><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">Breakpoint 4, 0x0000000000400f43 in phase_3 ()
</span></span><span class="line"><span class="cl">(gdb) n
</span></span><span class="line"><span class="cl">Single stepping until exit from function phase_3,
</span></span><span class="line"><span class="cl">which has no line number information.
</span></span><span class="line"><span class="cl">main (argc=&lt;optimized out&gt;, argv=&lt;optimized out&gt;) at bomb.c:90
</span></span><span class="line"><span class="cl">90     phase_defused();    //炸弹拆除
</span></span><span class="line"><span class="cl">(gdb) 
</span></span><span class="line"><span class="cl">91     printf(&#34;Halfway there!\n&#34;);
</span></span></code></pre></div><p>我们上面说过，第一个值有八种可能，所以这题答案也有八个，我们只要挨个测试<code>0-7</code>，分别打印出寄存器<code>eax</code>的值就可以得到所有答案。他们分别是</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0 207
</span></span><span class="line"><span class="cl">1 311
</span></span><span class="line"><span class="cl">2 707
</span></span><span class="line"><span class="cl">3 256
</span></span><span class="line"><span class="cl">4 389
</span></span><span class="line"><span class="cl">5 206
</span></span><span class="line"><span class="cl">6 682
</span></span><span class="line"><span class="cl">7 327
</span></span></code></pre></div><h2 id="phase_4">phase_4</h2>
<p>行百里者半九十，NO</p>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) disas phase_4
</span></span><span class="line"><span class="cl">Dump of assembler code for function phase_4:
</span></span><span class="line"><span class="cl">   0x000000000040100c &lt;+0&gt;: sub    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000401010 &lt;+4&gt;: lea    0xc(%rsp),%rcx
</span></span><span class="line"><span class="cl">   0x0000000000401015 &lt;+9&gt;: lea    0x8(%rsp),%rdx
</span></span><span class="line"><span class="cl">   0x000000000040101a &lt;+14&gt;: mov    $0x4025cf,%esi
</span></span><span class="line"><span class="cl">   0x000000000040101f &lt;+19&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x0000000000401024 &lt;+24&gt;: callq  0x400bf0 &lt;__isoc99_sscanf@plt&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401029 &lt;+29&gt;: cmp    $0x2,%eax
</span></span><span class="line"><span class="cl">   0x000000000040102c &lt;+32&gt;: jne    0x401035 &lt;phase_4+41&gt;
</span></span><span class="line"><span class="cl">   0x000000000040102e &lt;+34&gt;: cmpl   $0xe,0x8(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401033 &lt;+39&gt;: jbe    0x40103a &lt;phase_4+46&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401035 &lt;+41&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x000000000040103a &lt;+46&gt;: mov    $0xe,%edx
</span></span><span class="line"><span class="cl">   0x000000000040103f &lt;+51&gt;: mov    $0x0,%esi
</span></span><span class="line"><span class="cl">   0x0000000000401044 &lt;+56&gt;: mov    0x8(%rsp),%edi
</span></span><span class="line"><span class="cl">   0x0000000000401048 &lt;+60&gt;: callq  0x400fce &lt;func4&gt;
</span></span><span class="line"><span class="cl">   0x000000000040104d &lt;+65&gt;: test   %eax,%eax
</span></span><span class="line"><span class="cl">   0x000000000040104f &lt;+67&gt;: jne    0x401058 &lt;phase_4+76&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401051 &lt;+69&gt;: cmpl   $0x0,0xc(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401056 &lt;+74&gt;: je     0x40105d &lt;phase_4+81&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401058 &lt;+76&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x000000000040105d &lt;+81&gt;: add    $0x18,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000401061 &lt;+85&gt;: retq   
</span></span></code></pre></div><ul>
<li>1-8：开辟空间，保存参数信息，调用输入函数，和上面的分析重复，不再赘述。注意的是第 6 行，<code>x/s 0x4025cf</code>可知两个参数是整型数值。</li>
<li>9-10：参数个数必须等于 2，否则引爆</li>
<li>11-12：<code>14</code>与<code>rsp + 8</code>比较，等价于<code>14</code>与第一个参数比较。表示第一个参数必须小于等于 14，否则引爆。</li>
<li>14：<code>edx = 14</code></li>
<li>15：<code>esi = 0</code></li>
<li>16：<code>edi = rsp + 8</code>即<code>edi = 第一个参数</code></li>
<li>17：调用函数<code>fun4</code>，参数分别为<code>edi 0 14</code></li>
<li>18：测试返回值是否为 0，如果不为 0，引爆</li>
<li>20-22：比较<code>0</code>和<code>rsp + 12</code>，如果不等，引爆，否则返回</li>
</ul>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(gdb) disas func4
</span></span><span class="line"><span class="cl">Dump of assembler code for function func4:
</span></span><span class="line"><span class="cl">   0x0000000000400fce &lt;+0&gt;: sub    $0x8,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000400fd2 &lt;+4&gt;: mov    %edx,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fd4 &lt;+6&gt;: sub    %esi,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fd6 &lt;+8&gt;: mov    %eax,%ecx
</span></span><span class="line"><span class="cl">   0x0000000000400fd8 &lt;+10&gt;: shr    $0x1f,%ecx
</span></span><span class="line"><span class="cl">   0x0000000000400fdb &lt;+13&gt;: add    %ecx,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400fdd &lt;+15&gt;: sar    %eax
</span></span><span class="line"><span class="cl">   0x0000000000400fdf &lt;+17&gt;: lea    (%rax,%rsi,1),%ecx
</span></span><span class="line"><span class="cl">   0x0000000000400fe2 &lt;+20&gt;: cmp    %edi,%ecx
</span></span><span class="line"><span class="cl">   0x0000000000400fe4 &lt;+22&gt;: jle    0x400ff2 &lt;func4+36&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fe6 &lt;+24&gt;: lea    -0x1(%rcx),%edx
</span></span><span class="line"><span class="cl">   0x0000000000400fe9 &lt;+27&gt;: callq  0x400fce &lt;func4&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400fee &lt;+32&gt;: add    %eax,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400ff0 &lt;+34&gt;: jmp    0x401007 &lt;func4+57&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400ff2 &lt;+36&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x0000000000400ff7 &lt;+41&gt;: cmp    %edi,%ecx
</span></span><span class="line"><span class="cl">   0x0000000000400ff9 &lt;+43&gt;: jge    0x401007 &lt;func4+57&gt;
</span></span><span class="line"><span class="cl">   0x0000000000400ffb &lt;+45&gt;: lea    0x1(%rcx),%esi
</span></span><span class="line"><span class="cl">   0x0000000000400ffe &lt;+48&gt;: callq  0x400fce &lt;func4&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401003 &lt;+53&gt;: lea    0x1(%rax,%rax,1),%eax
</span></span><span class="line"><span class="cl">   0x0000000000401007 &lt;+57&gt;: add    $0x8,%rsp
</span></span><span class="line"><span class="cl">   0x000000000040100b &lt;+61&gt;: retq   
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-C" data-lang="C"><span class="line"><span class="cl"><span class="nf">func</span> <span class="p">(</span><span class="n">edi</span><span class="p">,</span> <span class="n">esi</span><span class="p">,</span> <span class="n">edx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="c1">// edi = 第一个参数, esi = 0, edx = 14
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="n">edx</span>            <span class="c1">// 4:mov %edx, %eax
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="n">eax</span> <span class="o">-</span><span class="n">esi</span>       <span class="c1">// 5:sub esi, %eax
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="n">edx</span> <span class="o">-</span><span class="n">esi</span>
</span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="n">eax</span>            <span class="c1">// 6:mov %eax, %ecx
</span></span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span>
</span></span><span class="line"><span class="cl">   <span class="n">eсx</span> <span class="o">=</span> <span class="n">ecx</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span>      <span class="c1">// 7:shr  $0x1f, %ecx
</span></span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="p">(</span><span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span>
</span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="n">eax</span> <span class="o">+</span> <span class="n">ecx</span>      <span class="c1">// 8:add %ecx, %eax
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="p">(</span><span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span><span class="p">)</span> <span class="o">+</span> <span class="p">((</span><span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">)</span><span class="c1">//替换eax和ecx
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="n">eax</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">;</span>       <span class="c1">// 9:sar %eax
</span></span></span><span class="line"><span class="cl">   <span class="n">eax</span> <span class="o">=</span> <span class="p">((</span><span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span><span class="p">)</span> <span class="o">+</span><span class="p">((</span><span class="n">edx</span> <span class="o">-</span><span class="n">esi</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">))</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="n">eax</span> <span class="o">+</span> <span class="n">esi</span> <span class="o">*</span> <span class="mi">1</span>   <span class="c1">// 10:lea (rax,ersi,1), %ecx
</span></span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="p">((</span><span class="n">edx</span> <span class="o">-</span> <span class="n">esi</span><span class="p">)</span> <span class="o">+</span><span class="p">((</span><span class="n">edx</span> <span class="o">-</span><span class="n">esi</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">))</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">esi</span> <span class="o">*</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="p">((</span><span class="mi">14</span> <span class="o">-</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="p">((</span><span class="mi">14</span> <span class="o">-</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">))</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">   <span class="n">ecx</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="c1">// 11:cmp %edi, %ecx
</span></span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="n">ecx</span> <span class="o">&lt;=</span> <span class="n">edi</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">   <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="c1">// 12:jle 400ff2
</span></span></span><span class="line"><span class="cl">      <span class="n">eax</span> <span class="o">=</span> <span class="mi">0</span>    <span class="c1">// mov $0x0,%eax
</span></span></span><span class="line"><span class="cl">      <span class="c1">// 18:cmp %edi, %ecx
</span></span></span><span class="line"><span class="cl">      <span class="k">if</span><span class="p">(</span><span class="n">ecx</span> <span class="o">&gt;=</span> <span class="n">edi</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="c1">// 19:jge    0x401007 &lt;func4+57&gt;
</span></span></span><span class="line"><span class="cl">         <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">         <span class="c1">//由此可以得知道 edx == edi
</span></span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="phase_5">phase_5</h2>
<div class="highlight line-numbers"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">   0x0000000000401062 &lt;+0&gt;: push   %rbx
</span></span><span class="line"><span class="cl">   0x0000000000401063 &lt;+1&gt;: sub    $0x20,%rsp
</span></span><span class="line"><span class="cl">   0x0000000000401067 &lt;+5&gt;: mov    %rdi,%rbx
</span></span><span class="line"><span class="cl">   0x000000000040106a &lt;+8&gt;: mov    %fs:0x28,%rax
</span></span><span class="line"><span class="cl">   0x0000000000401073 &lt;+17&gt;: mov    %rax,0x18(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401078 &lt;+22&gt;: xor    %eax,%eax
</span></span><span class="line"><span class="cl">   0x000000000040107a &lt;+24&gt;: callq  0x40131b &lt;string_length&gt;
</span></span><span class="line"><span class="cl">   0x000000000040107f &lt;+29&gt;: cmp    $0x6,%eax
</span></span><span class="line"><span class="cl">   0x0000000000401082 &lt;+32&gt;: je     0x4010d2 &lt;phase_5+112&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401084 &lt;+34&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x0000000000401089 &lt;+39&gt;: jmp    0x4010d2 &lt;phase_5+112&gt;
</span></span><span class="line"><span class="cl">   0x000000000040108b &lt;+41&gt;: movzbl (%rbx,%rax,1),%ecx
</span></span><span class="line"><span class="cl">   0x000000000040108f &lt;+45&gt;: mov    %cl,(%rsp)
</span></span><span class="line"><span class="cl">   0x0000000000401092 &lt;+48&gt;: mov    (%rsp),%rdx
</span></span><span class="line"><span class="cl">   0x0000000000401096 &lt;+52&gt;: and    $0xf,%edx
</span></span><span class="line"><span class="cl">   0x0000000000401099 &lt;+55&gt;: movzbl 0x4024b0(%rdx),%edx
</span></span><span class="line"><span class="cl">   0x00000000004010a0 &lt;+62&gt;: mov    %dl,0x10(%rsp,%rax,1)
</span></span><span class="line"><span class="cl">   0x00000000004010a4 &lt;+66&gt;: add    $0x1,%rax
</span></span><span class="line"><span class="cl">   0x00000000004010a8 &lt;+70&gt;: cmp    $0x6,%rax
</span></span><span class="line"><span class="cl">   0x00000000004010ac &lt;+74&gt;: jne    0x40108b &lt;phase_5+41&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010ae &lt;+76&gt;: movb   $0x0,0x16(%rsp)
</span></span><span class="line"><span class="cl">   0x00000000004010b3 &lt;+81&gt;: mov    $0x40245e,%esi
</span></span><span class="line"><span class="cl">      0x00000000004010b8 &lt;+86&gt;: lea    0x10(%rsp),%rdi
</span></span><span class="line"><span class="cl">   0x00000000004010bd &lt;+91&gt;: callq  0x401338 &lt;strings_not_equal&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010c2 &lt;+96&gt;: test   %eax,%eax
</span></span><span class="line"><span class="cl">   0x00000000004010c4 &lt;+98&gt;: je     0x4010d9 &lt;phase_5+119&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010c6 &lt;+100&gt;: callq  0x40143a &lt;explode_bomb&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010cb &lt;+105&gt;: nopl   0x0(%rax,%rax,1)
</span></span><span class="line"><span class="cl">   0x00000000004010d0 &lt;+110&gt;: jmp    0x4010d9 &lt;phase_5+119&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010d2 &lt;+112&gt;: mov    $0x0,%eax
</span></span><span class="line"><span class="cl">   0x00000000004010d7 &lt;+117&gt;: jmp    0x40108b &lt;phase_5+41&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010d9 &lt;+119&gt;: mov    0x18(%rsp),%rax
</span></span><span class="line"><span class="cl">   0x00000000004010de &lt;+124&gt;: xor    %fs:0x28,%rax
</span></span><span class="line"><span class="cl">   0x00000000004010e7 &lt;+133&gt;: je     0x4010ee &lt;phase_5+140&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010e9 &lt;+135&gt;: callq  0x400b30 &lt;__stack_chk_fail@plt&gt;
</span></span><span class="line"><span class="cl">   0x00000000004010ee &lt;+140&gt;: add    $0x20,%rsp
</span></span><span class="line"><span class="cl">   0x00000000004010f2 &lt;+144&gt;: pop    %rbx
</span></span><span class="line"><span class="cl">   0x00000000004010f3 &lt;+145&gt;: retq   
</span></span></code></pre></div>]]></content:encoded>
    </item>
  </channel>
</rss>
