<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>jakevin的博客</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://jackwener.github.io/"/>
  <updated>2018-10-09T05:20:46.923Z</updated>
  <id>https://jackwener.github.io/</id>
  
  <author>
    <name>jakevin</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>ucore-lab1实验报告</title>
    <link href="https://jackwener.github.io/2018/10/09/ucore-lab1%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"/>
    <id>https://jackwener.github.io/2018/10/09/ucore-lab1实验报告/</id>
    <published>2018-10-09T05:19:03.000Z</published>
    <updated>2018-10-09T05:20:46.923Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ucore-lab1实验报告"><a href="#Ucore-lab1实验报告" class="headerlink" title="Ucore lab1实验报告"></a>Ucore lab1实验报告</h1><h2 id="第一部分"><a href="#第一部分" class="headerlink" title="第一部分"></a>第一部分</h2><h3 id="practice1"><a href="#practice1" class="headerlink" title="practice1"></a>practice1</h3><ol><li>为何开启A20，以及如何开启A20</li><li>如何初始化GDT表（什么是GDT和LDT）</li><li>如何使能和进入保护模式</li></ol><blockquote><p>Intel x86系列CPU有实模式和保护模式，实模式从8086开始就有，保护模式从80386开始引入。为了兼容，Intel x86系列CPU都支持实模式。现代操作系统都是运行在保护模式下（Intel x86系列CPU）。计算机启动时，默认的工作模式是实模式，为了让内核能运行在保护模式下，Bootloader需要从实模式切换到保护模式，切换步骤如下：</p><ol><li>准备好GDT(Global Descriptor Table)</li><li>关中断</li><li>加载GDT到GDTR寄存器</li><li>开启A20，让CPU寻址大于1M</li><li>开启CPU的保护模式，即把cr0寄存器第一个bit置1</li><li>跳转到保护模式代码</li></ol></blockquote><h2 id="practice2"><a href="#practice2" class="headerlink" title="practice2"></a>practice2</h2><ol><li>bootloader如何读取硬盘扇区的？</li><li>bootloader是如何加载ELF格式的OS？</li></ol><blockquote><p>计算机启动是从BIOS开始，再由BIOS决定从哪个设备启动以及启动顺序，比如先从DVD启动再从硬盘启动等。计算机启动后，BIOS根据配置找到启动设备，并读取这个设备的第0个扇区，把这个扇区的内容加载到0x7c00,之后让CPU从0x7c00开始执行，这时BIOS已经交出了计算机的控制权，由被加载的扇区程序接管计算机。</p><p>这第一个扇区的程序就叫Boot，它一般做一些准备工作，把操作系统内核加载进内存，并把控制权交给内核。由于Boot只能有一个扇区大小，即512字节，它所能做的工作很有限，因此它有可能不直接加载内核，而是加载一个叫Loader的程序，再由Loader加载内核。因为Loader不是BIOS直接加载的，所以它可以突破512字节的程序大小限制（在实模式下理论上可以达到1M）。如果Boot没有加载Loader而直接加载内核，我们可以把它叫做Bootloader。</p><p>Bootloader加载内核就要读取文件，在实模式下可以用BIOS的INT 13h中断。内核文件放在哪里，怎么查找读取，这里牵涉到文件系统，Bootloader要从硬盘（软盘）的文件系统中查找内核文件，因此Bootloader需要解析文件系统的能力。GRUB是一个专业的Bootloader，它对这些提供了很好的支持</p></blockquote><p><a href="https://blog.csdn.net/flydream0/article/details/8719036" target="_blank" rel="noopener">elf格式前提须知</a></p><p>lab1感觉没啥好写的…弃之</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;Ucore-lab1实验报告&quot;&gt;&lt;a href=&quot;#Ucore-lab1实验报告&quot; class=&quot;headerlink&quot; title=&quot;Ucore lab1实验报告&quot;&gt;&lt;/a&gt;Ucore lab1实验报告&lt;/h1&gt;&lt;h2 id=&quot;第一部分&quot;&gt;&lt;a href=&quot;#第
      
    
    </summary>
    
    
      <category term="OS" scheme="https://jackwener.github.io/tags/OS/"/>
    
      <category term="操作系统" scheme="https://jackwener.github.io/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    
  </entry>
  
  <entry>
    <title>ucore_lab2实验报告</title>
    <link href="https://jackwener.github.io/2018/09/28/ucore-lab2%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"/>
    <id>https://jackwener.github.io/2018/09/28/ucore-lab2实验报告/</id>
    <published>2018-09-28T04:45:17.000Z</published>
    <updated>2018-10-09T04:20:34.937Z</updated>
    
    <content type="html"><![CDATA[<h2 id="ucore-lab2实验报告"><a href="#ucore-lab2实验报告" class="headerlink" title="ucore lab2实验报告"></a>ucore lab2实验报告</h2><blockquote><p>实验二 主要针对完成Ucore的<strong>物理内存管理</strong></p></blockquote><h3 id="练习0"><a href="#练习0" class="headerlink" title="练习0"></a>练习0</h3><blockquote><p>key point:</p><p>利用meld工具进行比较与合并</p></blockquote><h3 id="练习1：实现first-fit练习物理内存分配算法"><a href="#练习1：实现first-fit练习物理内存分配算法" class="headerlink" title="练习1：实现first-fit练习物理内存分配算法"></a>练习1：实现first-fit练习物理内存分配算法</h3><p><a href="https://www.bookstack.cn/read/simple_os_book/zh-chapter-3-implement_pages_mem_managment.md" target="_blank" rel="noopener"><strong>介绍ucore很详细的总结</strong></a></p><blockquote><p>Note:</p><p>连续分配方式，是指为一个用户程序分配一个连续的内存空间。它主要包括单一连续分配、固定分区分配和动态分区分配。</p><h4 id="单一连续分配"><a href="#单一连续分配" class="headerlink" title="单一连续分配"></a>单一连续分配</h4><h4 id="固定分区分配"><a href="#固定分区分配" class="headerlink" title="固定分区分配"></a>固定分区分配</h4><h4 id="动态分区分配"><a href="#动态分区分配" class="headerlink" title="动态分区分配"></a>动态分区分配</h4><blockquote><p>动态分区分配又称为可变分区分配，是一种动态划分内存的分区方法。这种分区方法不预先将内存划分，而是在进程装入内存时，根据进程的大小动态地建立分区，并使分区的大小正好适合进程的需要。因此系统中分区的大小和数目是可变的</p></blockquote><p><img src="/images/ucore_lab2/1.jpg" alt="动态分区"></p><p>在进程装入或换入主存时，如果内存中有多个足够大的空闲块，操作系统必须确定分配哪个内存块给进程使用，这就是动态分区的分配策略，考虑以下几种算法：</p><ul><li>首次适应(First  Fit)算法：空闲分区以地址递增的次序链接。分配内存时顺序查找，找到大小能满足要求的第一个空闲分区。</li><li>最佳适应(Best  Fit)算法：空闲分区按容量递增形成分区链，找到第一个能满足要求的空闲分区。</li><li>最坏适应(Worst  Fit)算法：又称最大适应(Largest Fit)算法，空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区，也就是挑选出最大的分区。</li><li>邻近适应(Next  Fit)算法：又称循环首次适应算法，由首次适应算法演变而成。不同之处是分配内存时从上次查找结束的位置开始继续查找。</li></ul><p>在这几种方法中，首次适应算法不仅是最简单的，而且通常也是最好和最快的。在UNIX 系统的最初版本中，就是使用首次适应算法为进程分配内存空间，其中使用数组的数据结构 (而非链表）来实现。不过，首次适应算法会使得内存的低地址部分出现很多小的空闲分区，而每次分配查找时，都要经过这些分区，因此也增加了查找的开销。</p><p>邻近适应算法试图解决这个问题，但实际上，它常常会导致在内存的末尾分配空间（因为在一遍扫描中，内存前面部分使用后再释放时，不会参与分配)，分裂成小碎片。它通常比首次适应算法的结果要差。</p><p>最佳适应算法虽然称为“最佳”，但是性能通常很差，因为每次最佳的分配会留下很小的难以利用的内存块，它会产生最多的外部碎片。</p><p>最坏适应算法与最佳适应算法相反，选择最大的可用块，这看起来最不容易产生碎片，但是却把最大的连续内存划分开，会很快导致没有可用的大的内存块，因此性能也非常差。</p><p>Kunth和Shore分别就前三种方法对内存空间的利用情况做了模拟实验，结果表明：</p><p>首次适应算法可能比最佳适应法效果好，而它们两者一定比最大适应法效果好。另外注意,在算法实现时,分配操作中最佳适应法和最大适应法需要对可用块进行排序或遍历查找，而首次适应法和邻近适应法只需要简单查找；回收操作中，当回收的块与原来的空闲块相邻时（有三种相邻的情况，比较复杂)，需要将这些块合并。在算法实现时，使用数组或链表进行管理。除了内存的利用率，这里的算法开销也是操作系统设计需要考虑的一个因素。</p></blockquote><blockquote><p>为了与以后的分页机制配合，首先需要建立对整个计算机的每一个物理页的属性，用结构体Page来表示，它包含了映射此物理页的虚拟页个数，描述物理页属性的flags和双向链接各个Page结构的page_link双向链表。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt; <span class="class"><span class="keyword">struct</span> <span class="title">Page</span>&#123;</span></span><br><span class="line">&gt;     <span class="keyword">int</span> ref;</span><br><span class="line">&gt;     <span class="keyword">uint32_t</span> flags;</span><br><span class="line">&gt;     <span class="keyword">unsigned</span> <span class="keyword">int</span> property;</span><br><span class="line">&gt;     <span class="keyword">list_entry_t</span> page_link;</span><br><span class="line">&gt; &#125;<span class="number">123456</span></span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure></blockquote><blockquote><ul><li><p>ref</p><blockquote><p>  表示该页被页表的引用记数。如果这个页被页表引用了，即在某页表中有一个页表项设置一个虚拟页到这个Page管理的物理页的映射关系，就会把Page的ref加一。反之，若页表项取消，即映射关系解除，就减一。</p></blockquote></li><li><p>flags</p><blockquote><p>   表示此物理页的状态标记，有两种属性，bit 0表示是否被保留，如果被保留了则设为1，且不能放到空闲页链表中，即这样的页不是空闲页，不能动态分配与释放。比如内核代码占用的空间。bit 1表示此页是否是空闲的。如果设置为1，表示这页是空闲的，可以被分配；如果设置为0，表示这页已经被分配出去了，不能被再二次分配。</p></blockquote></li><li><p>property</p><blockquote><p>  用来记录某连续内存空闲块的大小（即地址连续的空闲页的个数）。这里需要注意的是用到此成员变量的这个Page比较特殊，是连续内存空闲地址最小的一夜（即第一页）。</p></blockquote></li><li><p>page_link</p><blockquote><p>  是便于把多个连续内存空闲块链接在一起的双向链表指针，连续内存空闲块利用这个页的成员变量page_link来链接比它地址小和大的其他连续内存空闲块</p></blockquote></li></ul><p>  为了有效的管理这些小连续内存空闲块，所有的连续内存空闲块可用一个双向链表来管理，便于分配和释放，为此定义一个<code>free_area_t</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt; <span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> &#123;</span></span><br><span class="line">&gt;     <span class="keyword">list_entry_t</span> free_list;         <span class="comment">// the list header</span></span><br><span class="line">&gt;     <span class="keyword">unsigned</span> <span class="keyword">int</span> nr_free;           <span class="comment">// number of free pages in this free list</span></span><br><span class="line">&gt; &#125; <span class="keyword">free_area_t</span>;<span class="number">1234</span></span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure></blockquote><blockquote><ul><li><code>free_list</code>是一个list_entry结构的双向链表指针</li><li><code>nr_free</code>则记录当前空闲页的个数</li></ul><p>有了这两个数据结构，就可以管理起来整个以页尾单位的物理内存空间</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">void</span></span><br><span class="line">default_init_memmap(struct Page *base, <span class="keyword">size_t</span> n)</span><br><span class="line">&#123;</span><br><span class="line">    assert(n &gt; <span class="number">0</span>);</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">p</span> = <span class="title">base</span>;</span></span><br><span class="line">    <span class="keyword">for</span> (; p != base + n; p++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 断言</span></span><br><span class="line">        assert(PageReserved(p));</span><br><span class="line">        p-&gt;flags = p-&gt;property = <span class="number">0</span>;</span><br><span class="line">        SetPageReserved(base);</span><br><span class="line">        <span class="comment">// 引用位 置0</span></span><br><span class="line">        set_page_ref(p, <span class="number">0</span>);</span><br><span class="line">        list_add_before(&amp;free_list, &amp;(p-&gt;page_link));</span><br><span class="line">    &#125;</span><br><span class="line">    base-&gt;property = n;</span><br><span class="line">    <span class="comment">// SetPageProperty(base);</span></span><br><span class="line">    nr_free += n;</span><br><span class="line">    <span class="comment">// list_add(&amp;free_list, &amp;(base-&gt;page_link));</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *</span></span><br><span class="line"><span class="class"><span class="title">default_alloc_pages</span>(<span class="title">size_t</span> <span class="title">n</span>) &#123;</span></span><br><span class="line">    assert(n &gt; <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (n &gt; nr_free) &#123;<span class="comment">//当空闲页不够时，返回NULL</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">list_entry_t</span> *le = &amp;free_list;</span><br><span class="line">    <span class="keyword">while</span> ((le = list_next(le)) != &amp;free_list) &#123;<span class="comment">//遍历所有指针</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">p</span> = <span class="title">le2page</span>(<span class="title">le</span>, <span class="title">page_link</span>);</span><span class="comment">//转换为页结构</span></span><br><span class="line">        <span class="keyword">if</span> (p-&gt;property &gt;= n) &#123;<span class="comment">//如果找到空闲页大小大于等于n时选中</span></span><br><span class="line">            <span class="keyword">int</span> i;</span><br><span class="line">            <span class="keyword">list_entry_t</span> *len;</span><br><span class="line">            <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; n; i++)<span class="comment">//初始化分配内存</span></span><br><span class="line">            &#123;</span><br><span class="line">                len = list_next(le);</span><br><span class="line">                <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">p2</span> = <span class="title">le2page</span>(<span class="title">temp_le</span>, <span class="title">page_link</span>);</span>    <span class="comment">//转换页结构</span></span><br><span class="line">                SetPageReserved(p2);  <span class="comment">//初始化标志位</span></span><br><span class="line">                ClearPageProperty(p2);   </span><br><span class="line">                list_del(le);  <span class="comment">//清除双向链表指针</span></span><br><span class="line">                le = len;  </span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(p-&gt;property &gt; n)</span><br><span class="line">            &#123;  </span><br><span class="line">                <span class="comment">//若大小&gt;n,只取大小为n的块</span></span><br><span class="line">                (le2page(le,page_link))-&gt;property = p-&gt;property - n;  </span><br><span class="line">            &#125;  </span><br><span class="line">            ClearPageProperty(p);  <span class="comment">//初始化标志位</span></span><br><span class="line">            SetPageReserved(p);  </span><br><span class="line">            nr_free -= n;  <span class="comment">//空闲页大小-n</span></span><br><span class="line">            <span class="keyword">return</span> p;  </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">NULL</span>;<span class="comment">//分配失败</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">void</span></span><br><span class="line">default_free_pages(struct Page *base, <span class="keyword">size_t</span> n) &#123;</span><br><span class="line">    assert(n &gt; <span class="number">0</span>);</span><br><span class="line">    assert(PageReserved(base));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">list_entry_t</span> *le = &amp;free_list;<span class="comment">//找合适的位置</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">p</span> = <span class="title">base</span>;</span></span><br><span class="line">    <span class="keyword">while</span>((le=list_next(le)) != &amp;free_list) </span><br><span class="line">    &#123;</span><br><span class="line">        p = le2page(le, page_link);</span><br><span class="line">        <span class="keyword">if</span>(p &gt; base)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(p = base; p &lt; base + n; p++)<span class="comment">//在之前插入n个空闲页</span></span><br><span class="line">    &#123;</span><br><span class="line">        list_add_before(le, &amp;(p-&gt;page_link));</span><br><span class="line">        p-&gt;flags = <span class="number">0</span>;<span class="comment">//设置标志</span></span><br><span class="line">        set_page_ref(p, <span class="number">0</span>);</span><br><span class="line">        ClearPageProperty(p);</span><br><span class="line">        SetPageProperty(p);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    base-&gt;property = n;<span class="comment">//设置连续大小为n</span></span><br><span class="line">    <span class="comment">//如果是高位，则向高地址合并</span></span><br><span class="line">    p = le2page(le,page_link);</span><br><span class="line">    <span class="keyword">if</span>(base + base-&gt;property == p )</span><br><span class="line">    &#123;</span><br><span class="line">        base-&gt;property += p-&gt;property;</span><br><span class="line">        p-&gt;property = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//如果是低位且在范围内，则向低地址合并</span></span><br><span class="line">    le = list_prev(&amp;(base-&gt;page_link));</span><br><span class="line">    p = le2page(le, page_link);</span><br><span class="line">    <span class="keyword">if</span>(le != &amp;free_list &amp;&amp; p == base<span class="number">-1</span>)<span class="comment">//满足条件，未分配则合并</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">while</span>(le != &amp;free_list)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(p-&gt;property)<span class="comment">//当连续时</span></span><br><span class="line">            &#123;</span><br><span class="line">                p-&gt;property += base-&gt;property;</span><br><span class="line">                base-&gt;property = <span class="number">0</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            le = list_prev(le);</span><br><span class="line">            p = le2page(le,page_link);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    nr_free += n;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="练习2：实现寻找虚拟地址对应的页表项"><a href="#练习2：实现寻找虚拟地址对应的页表项" class="headerlink" title="练习2：实现寻找虚拟地址对应的页表项"></a>练习2：实现寻找虚拟地址对应的页表项</h3><blockquote><h4 id="页表机制"><a href="#页表机制" class="headerlink" title="页表机制"></a>页表机制</h4><p>请求分页系统的页表机制不同于基本分页系统，请求分页系统在一个作业运行之前不要求全部一次性调入内存，因此在作业的运行过程中，必然会出现要访问的页面不在内存的情况，如何发现和处理这种情况是请求分页系统必须解决的两个基本问题。为此，在请求页表项中增加了四个字段，如图</p><p><img src="/images/ucore_lab2/2.png" alt="图2"></p><p>增加的四个字段说明如下：</p><ul><li>状态位P：用于指示该页是否已调入内存，供程序访问时参考。</li><li>访问字段A：用于记录本页在一段时间内被访问的次数，或记录本页最近己有多长时间未被访问，供置换算法换出页面时参考。</li><li>修改位M：标识该页在调入内存后是否被修改过。</li><li>外存地址：用于指出该页在外存上的地址，通常是物理块号，供调入该页时参考。</li></ul><h4 id="缺页中断机构"><a href="#缺页中断机构" class="headerlink" title="缺页中断机构"></a>缺页中断机构</h4><p>在请求分页系统中，每当所要访问的页面不在内存时，便产生一个缺页中断，请求操作系统将所缺的页调入内存。此时应将缺页的进程阻塞（调页完成唤醒)，如果内存中有空闲块，则分配一个块，将要调入的页装入该块，并修改页表中相应页表项，若此时内存中没有空闲块，则要淘汰某页（若被淘汰页在内存期间被修改过，则要将其写回外存)。</p><p>缺页中断作为中断同样要经历，诸如保护CPU环境、分析中断原因、转入缺页中断处理程序、恢复CPU环境等几个步骤。但与一般的中断相比，它有以下两个明显的区别：</p><ul><li>在指令执行期间产生和处理中断信号，而非一条指令执行完后，属于内部中断。</li><li>一条指令在执行期间，可能产生多次缺页中断。</li></ul><h4 id="地址变换机构"><a href="#地址变换机构" class="headerlink" title="地址变换机构"></a>地址变换机构</h4><p>请求分页系统中的地址变换机构，是在分页系统地址变换机构的基础上，为实现虚拟内存，又增加了某些功能而形成的。</p><p><img src="/images/ucore_lab2/3.jpg" alt="图三"></p><p>如图3-25所示，在进行地址变换时，先检索快表：</p><ul><li>若找到要访问的页，便修改页表项中的访问位（写指令则还须重置修改位)，然后利用页表项中给出的物理块号和页内地址形成物理地址。</li><li>若未找到该页的页表项，应到内存中去查找页表，再对比页表项中的状态位P，看该页是否已调入内存，未调入则产生缺页中断，请求从外存把该页调入内存。</li></ul><p><a href="https://blog.csdn.net/linshenyuan1213/article/details/81324020" target="_blank" rel="noopener"><strong>注意自己了解高端内存概念</strong></a></p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//typedef uintptr_t pde_t;</span></span><br><span class="line">    <span class="keyword">pde_t</span> *pdep = &amp;pgdir[PDX(la)];  <span class="comment">// (1)获取页表</span></span><br><span class="line">    <span class="keyword">if</span> (!(*pdep &amp; PTE_P))             <span class="comment">// (2)假设页目录项不存在</span></span><br><span class="line">    &#123;      </span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">page</span>;</span></span><br><span class="line">        <span class="keyword">if</span> (!create || (page = alloc_page()) == <span class="literal">NULL</span>) <span class="comment">// (3) check if creating is needed, then alloc page for page table</span></span><br><span class="line">        &#123;    <span class="comment">//假如不需要分配或是分配失败</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        set_page_ref(page, <span class="number">1</span>);                      <span class="comment">// (4)设置被引用1次</span></span><br><span class="line">        <span class="keyword">uintptr_t</span> pa = page2pa(page);                  <span class="comment">// (5)得到该页物理地址</span></span><br><span class="line">        <span class="built_in">memset</span>(KADDR(pa), <span class="number">0</span>, PGSIZE);                  <span class="comment">// (6)物理地址转虚拟地址，并初始化</span></span><br><span class="line">        *pdep = pa | PTE_U | PTE_W | PTE_P;            <span class="comment">// (7)设置可读，可写，存在位</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> &amp;((<span class="keyword">pte_t</span> *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];     <span class="comment">// (8) return page table entry</span></span><br><span class="line">    <span class="comment">//KADDR(PDE_ADDR(*pdep)):这部分是由页目录项地址得到关联的页表物理地址，再转成虚拟地址</span></span><br><span class="line">    <span class="comment">//PTX(la)：返回虚拟地址la的页表项索引</span></span><br><span class="line">    <span class="comment">//最后返回的是虚拟地址la对应的页表项入口地址</span></span><br></pre></td></tr></table></figure><h3 id="练习3-释放某虚地址所在的页并取消对应二级页表项的映射"><a href="#练习3-释放某虚地址所在的页并取消对应二级页表项的映射" class="headerlink" title="练习3: 释放某虚地址所在的页并取消对应二级页表项的映射"></a>练习3: 释放某虚地址所在的页并取消对应二级页表项的映射</h3><blockquote><p>释放某虚拟地址所在的页并取消对应的二级页表项的映射（需要编程） </p><p>当释放一个包含某虚地址的物理内存页时，需要让对应此物理内存页的管理数据结构Page做相关的清除</p><p>处理，使得次物理内存页成为空闲；另外还需把表示虚地址与物理地址对应关系的二级页表项清除</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (*ptep &amp; PTE_P)                 <span class="comment">//(1) check if this page table entry is present</span></span><br><span class="line">    &#123;      <span class="comment">//假如页表项存在</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">Page</span> *<span class="title">page</span> = <span class="title">pte2page</span>(*<span class="title">ptep</span>);</span><span class="comment">//(2)找到页表项的那一页信息</span></span><br><span class="line">        <span class="keyword">if</span> (page_ref_dec(page) == <span class="number">0</span>)<span class="comment">//(3)如果没有被引用</span></span><br><span class="line">        &#123; </span><br><span class="line">            free_page(page);<span class="comment">//(4)释放该页</span></span><br><span class="line">        &#125;</span><br><span class="line">        *ptep = <span class="number">0</span>;         <span class="comment">//(5)该页目录项清零</span></span><br><span class="line">        tlb_invalidate(pgdir, la); <span class="comment">//(6) flush tlb当修改的页表是进程正在使用的那些页表，使之无效</span></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;ucore-lab2实验报告&quot;&gt;&lt;a href=&quot;#ucore-lab2实验报告&quot; class=&quot;headerlink&quot; title=&quot;ucore lab2实验报告&quot;&gt;&lt;/a&gt;ucore lab2实验报告&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;实验二 主要针对完
      
    
    </summary>
    
    
      <category term="OS" scheme="https://jackwener.github.io/tags/OS/"/>
    
      <category term="操作系统" scheme="https://jackwener.github.io/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    
  </entry>
  
  <entry>
    <title>hit-os-lab2</title>
    <link href="https://jackwener.github.io/2018/06/09/hit-os-lab2/"/>
    <id>https://jackwener.github.io/2018/06/09/hit-os-lab2/</id>
    <published>2018-06-09T02:28:21.000Z</published>
    <updated>2018-06-09T02:28:21.778Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>hit-os-lab1</title>
    <link href="https://jackwener.github.io/2018/06/09/hit-os-lab1/"/>
    <id>https://jackwener.github.io/2018/06/09/hit-os-lab1/</id>
    <published>2018-06-09T02:28:05.000Z</published>
    <updated>2018-06-09T02:28:05.298Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>CSAPP attacklab（伪）报告</title>
    <link href="https://jackwener.github.io/2018/05/29/attacklab/"/>
    <id>https://jackwener.github.io/2018/05/29/attacklab/</id>
    <published>2018-05-29T12:55:29.000Z</published>
    <updated>2018-05-29T15:06:36.939Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>脑袋一片浆糊，辣鸡而茫然</p></blockquote><h1 id="Attack-Lab"><a href="#Attack-Lab" class="headerlink" title="Attack Lab"></a>Attack Lab</h1><p>此处Lab的主要目的是利用程序中的缓冲区溢出漏洞来实现对系统的攻击</p><h1 id="Level１"><a href="#Level１" class="headerlink" title="Level１"></a>Level１</h1><p>第一个关卡不要求向程序中注入代码，而是需要输入一个「引爆字符串」来改变程序的运行轨迹，重定向运行另外一个函数。在 ctarget 中，getbuf 被函数 test 调用：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">int</span> val;</span><br><span class="line">  val = getbuf();</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">"No exploit.  Getbuf returned 0x%x\n"</span>, val);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们希望 getbuf() 在返回后，调用函数 touch1 而不是输出 val 的值。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">touch1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  vlevel = <span class="number">1</span>;</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">"Touch1!: You called touch1()\n"</span>);</span><br><span class="line">  validate(<span class="number">1</span>);</span><br><span class="line">  <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>首先反汇编：<code>objdump -d ctarget &gt; touch.s</code></p><p>我们可以看到，getbuf 将 %rsp 移动了 0x28 也就是 40 字节。这也就意味着，在往上 4 个字节，就是返回到 test 的返回地址。所以，我们就可以利用缓冲区溢出将返回地址修改掉。</p><p>可以看到 touch1 的开始地址在 0x004017c0，所以我们输入的字符串可以是<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">c0 17 40 00</span><br></pre></td></tr></table></figure></p><p>然后，我们将这个字符文件转换为字节码 ./hex2raw &lt; touch1.txt &gt; touch1solve.txt，然后执行 ./ctarget -q -i touch1solve.txt</p><h1 id="Level2"><a href="#Level2" class="headerlink" title="Level2"></a>Level2</h1><p>第二阶段要求向程序中注入一小段代码，ctarget 中的 touch2 的 C 语言代码为：<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">touch2</span><span class="params">(<span class="keyword">unsigned</span> val)</span> </span>&#123;</span><br><span class="line">  vlevel = <span class="number">2</span>;    <span class="comment">/*Part of validation protocol*/</span></span><br><span class="line">  <span class="keyword">if</span> (val == cookie) &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Touch2!: You called touch2(0x%.8x)\n"</span>, val);</span><br><span class="line">    validate(<span class="number">2</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Misfire: You called touch2(0x%.8x)\n"</span>, val);</span><br><span class="line">    fail(<span class="number">2</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>这里使用缓存区作为代码执行区域，缓存区溢出后，将返回地址写为缓存区首地址，然后执行缓存区所存的指令，首先先找出缓冲区首地址</p><p>不多bb,看图；<br><img src="/images/attacklab1.png" alt="图片1"></p><p>可以看到首地址为0x5561dc78，顺便看到第6行也就是0x28个字节之后存放的原返回地址。</p><p>和Level１一样，覆盖原返回地址，另外还要写入攻击指令。<br>先将指令转为机器码。</p><blockquote><p>movq $0x59b997fa,%rdi # rdi = cookie</p></blockquote><blockquote><p>movq $0x5561dc98,%rsp # 将rsp设为存放在栈中的touch2地址的地址<br>ret # 读取rsp指向的地址并跳转</p></blockquote><p>利用gcc -c命令将汇编语句编译成机器码，再objdump -d生成的文件就可以间接地看到最终的机器码。</p><p>得到答案为<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">48 c7 c7 fa 97 b9 59 48</span><br><span class="line">c7 c4 98 dc 61 55 c3 00</span><br><span class="line">00 00 00 00 00 00 00 00</span><br><span class="line">00 00 00 00 00 00 00 00</span><br><span class="line">ec 17 40 00 00 00 00 00</span><br><span class="line">78 dc 61 55 00 00 00 00</span><br></pre></td></tr></table></figure></p><h1 id="Level3"><a href="#Level3" class="headerlink" title="Level3"></a>Level3</h1><p>第三阶段同样要实现代码注入攻击，但是要传入一个额外的字符串。</p><p>在 ctarget 中 hexmatch 和 touch3 的 C 语言代码如下：<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* compare string to hex represention of unsigned value */</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">hexmatch</span><span class="params">(<span class="keyword">unsigned</span> val, <span class="keyword">char</span> *sval)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">char</span> cbuf[<span class="number">110</span>];</span><br><span class="line">  <span class="comment">/* make position of check string unpredictable*/</span></span><br><span class="line">  <span class="keyword">char</span>* s = cbuf + random() % <span class="number">100</span>;</span><br><span class="line">  <span class="built_in">sprintf</span>(s, <span class="string">"%.8x"</span>, val);</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">strncmp</span>(sval, s, <span class="number">9</span>) == <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">touch3</span><span class="params">(<span class="keyword">char</span> *sval)</span> </span>&#123;</span><br><span class="line">  vlevel = <span class="number">3</span>;</span><br><span class="line">  <span class="keyword">if</span> (hexmatch(cookie, sval)) &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Touch3!: You called You called touch3(\"%s\")\n"</span>, sval)</span><br><span class="line">    validate(<span class="number">3</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Misfire: You called touch3(\"%s\")\n"</span>, sval);</span><br><span class="line">    fail(<span class="number">3</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>我们需要在引爆字符串中包含自己 cookie 的字符串表示，这个字符串应该是 8 个 16 进制数字，并以 0 为结尾。这个字符串的地址应该被保存在 %rdi 中。当函数 hexmatch 和 strncmp 被调用的时候，他们会把参数保存到栈上，这会覆盖 getbuf 写入的部分内容。所以，我们需要小心引爆字符串的存放位置。避开调用hexmatch和strncmp保存在栈上的位置。如果目标字符串存放的位置比touch3存放地址更低，在最终字符串对比的时候会发现rdi指向地址的内容发生了改变。</p><p>汇编代码为：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mov $0x5561dcb8,%rdi</span><br><span class="line">pushq $0x4018fa</span><br><span class="line">ret</span><br></pre></td></tr></table></figure></p><p>构造字符串为：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">48 c7 c7 b8</span><br><span class="line">dc 61 55 68</span><br><span class="line">fa 18 40 00</span><br><span class="line">c3 00 00 00</span><br><span class="line">35 39 62 39</span><br><span class="line">39 37 66 61</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">78 dc 61 55</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">00 00 00 00</span><br><span class="line">35 39 62 39</span><br><span class="line">39 37 66 61</span><br><span class="line">00 00 00 00</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;脑袋一片浆糊，辣鸡而茫然&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;Attack-Lab&quot;&gt;&lt;a href=&quot;#Attack-Lab&quot; class=&quot;headerlink&quot; title=&quot;Attack Lab&quot;&gt;&lt;/a&gt;Attack La
      
    
    </summary>
    
    
      <category term="CSAPP" scheme="https://jackwener.github.io/tags/CSAPP/"/>
    
  </entry>
  
  <entry>
    <title>汇编语言-王爽-实验任务</title>
    <link href="https://jackwener.github.io/2018/05/11/assasAnswer/"/>
    <id>https://jackwener.github.io/2018/05/11/assasAnswer/</id>
    <published>2018-05-11T09:17:46.000Z</published>
    <updated>2018-05-19T10:44:52.307Z</updated>
    
    <content type="html"><![CDATA[<h1 id="扯话"><a href="#扯话" class="headerlink" title="扯话"></a>扯话</h1><p>开始啃汇编啦,看过CSAPP第三章后,感觉上手还是比较友好的</p><p>准备顺序大概是</p><p>王爽汇编语言  -&gt;  x86汇编语言:从实模式到保护模式  -&gt;   操作系统</p><h1 id="实验"><a href="#实验" class="headerlink" title="实验"></a>实验</h1><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><blockquote><p>书上的环境是在windows下,由于我是使用的linux发行版deepin,所以选择了一些工具代替</p></blockquote><blockquote><p>试了一下,现在用win10去使用DOS估计也不是特别简单,干脆就用LINUX了</p></blockquote><p>使用dosemu模拟DOS环境</p><h3 id="安装dosemu"><a href="#安装dosemu" class="headerlink" title="安装dosemu"></a>安装dosemu</h3><p>只需要一句简单的命令行即可安装dosemu</p><p><code>sudo apt-get install dosemu</code></p><h3 id="安装MASM6-115-0"><a href="#安装MASM6-115-0" class="headerlink" title="安装MASM6.115.0"></a>安装MASM<del>6.11</del>5.0</h3><p><del>在下载完MASM6.11后，在HOME文件夹下解压，于是我们得到了MASM611的安装文件夹<br>后续安装后,使用过程出现了缺少dosxnt.exe文件的报错,google后折腾了一个小时左右,后面还是换版本了</del></p><p>使用的是MASM5.0</p><blockquote><p>dosemu下看到的C盘和D盘只是虚拟出来的，对应的目录在~/.dosemu/drives 下。</p></blockquote><p>下载解压后,将link.exe和masm.exe放到C盘下,直接使用就可以了</p><p>具体使用书上有解释,就不赘述了.</p><h2 id="实验1-查看CPU和内存，用机器指令和汇编指令编程"><a href="#实验1-查看CPU和内存，用机器指令和汇编指令编程" class="headerlink" title="实验1 查看CPU和内存，用机器指令和汇编指令编程"></a>实验1 查看CPU和内存，用机器指令和汇编指令编程</h2><ol><li>使用Debug，将下面的程序段写入内存，逐条执行，观察每条指令执行后，CPU中相关寄存器的变化。</li></ol><table><thead><tr><th>机器码</th><th>汇编指令</th><th>执行后相关寄存器变化</th></tr></thead><tbody><tr><td>b8 20 4e</td><td>mov ax, 4E20H</td><td>AX=4E20H</td></tr><tr><td>05 16 14</td><td>add ax, 1416H</td><td>AX=6236H</td></tr><tr><td>bb 00 20</td><td>mov bx, 2000H</td><td>BX=2000H</td></tr><tr><td>01 d8</td><td>add ax, bx</td><td>AX=8236H</td></tr><tr><td>89 c3</td><td>mov bx, ax</td><td>BX=8236H</td></tr><tr><td>01 d8</td><td>add ax, bx</td><td>AX=046CH</td></tr><tr><td>b8 1a 00</td><td>mov ax, 001AH</td><td>AX=001AH</td></tr><tr><td>bb 26 00</td><td>mov bx, 0026H</td><td>BX=0026H</td></tr><tr><td>00 d8</td><td>add al, bl</td><td>AX=0040H</td></tr><tr><td>00 dc</td><td>add ah, bl</td><td>AX=2640H</td></tr><tr><td>00 c7</td><td>add bh, al</td><td>BX=4026H</td></tr><tr><td>b4 00</td><td>mov ah, 0</td><td>AX=0040H</td></tr><tr><td>00 d8</td><td>add al, bl</td><td>AX=0066H</td></tr><tr><td>04 9c</td><td>add al, 9CH</td><td>AX=0002H</td></tr></tbody></table><blockquote><p>提示，可用E命令和A命令以两种方式将指令写入内存。注意用T命令执行时，CS:IP的指向。</p></blockquote><p>2.将下面3条指令写入从2000:0开始的内存单元中，利用这3条指令计算2的8次方。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">mov ax, 1</span><br><span class="line">add ax, ax</span><br><span class="line">jmp 2000:0003</span><br></pre></td></tr></table></figure><p>一个循环,很好理解</p><p>3.查看内存中的内容。</p><p>PC机主板上的ROM写有一个生产日期，在内存FFF00H～FFFFFH的某几个单元中，请找到这个生产日期并试图改变它。<br>提示，如果读者对实验的结果感到疑惑，请仔细阅读第1章中的1.15节。</p><blockquote><p>用D命令能看到储存在FFF0:00F5-00FC之间,xx/xx/xx ,模拟器是可以改的,然后真实情况应该是不可以改的(猜测),应该是写死了,无写权限</p></blockquote><h2 id="实验二"><a href="#实验二" class="headerlink" title="实验二"></a>实验二</h2><ol><li>使用Debug，将下面的程序段写入内存，逐条执行，根据指令执行后的实验运行情况填空。</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">mov ax, ffff</span><br><span class="line">mov ds, ax</span><br><span class="line">mov ax, 2200</span><br><span class="line">mov ss, ax</span><br><span class="line">mov sp, 1000</span><br><span class="line">mov ax,[0]  ;ax = _____</span><br><span class="line">add ax,[2]  ;ax = _____</span><br><span class="line">mov bx,[4]  ;bx = _____</span><br><span class="line">add bx,[6]  ;bx = _____</span><br><span class="line">push ax     ;sp = _____ 修改的内存单元的地址是_____内容为_____</span><br><span class="line">push bx     ;sp = _____ 修改的内存单元的地址是_____内容为_____</span><br><span class="line">pop ax      ;sp = _____ ax = _____</span><br><span class="line">pop bx      ;sp = _____ bx = _____</span><br><span class="line">push [4]    ;sp = _____ 修改的内存单元的地址是_____内容为_____</span><br><span class="line">push [6]    ;sp = _____ 修改的内存单元的地址是_____内容为_____</span><br></pre></td></tr></table></figure><p>结果<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">5bea</span><br><span class="line">00e0</span><br><span class="line">32f0</span><br><span class="line">2f32</span><br><span class="line">00FE 220FE 25EE</span><br><span class="line">00FC 220FC 5F37</span><br><span class="line">00FE 5F37</span><br><span class="line">0100 25EE</span><br><span class="line">00FE 220FE 3002</span><br><span class="line">00FC 220FC 2F35</span><br></pre></td></tr></table></figure></p><p>2.仔细观察图3.19中的实验过程，然后分析：为什么2000:0～2000:f中的内容会发生改变？</p><p>在使用T命令时,产生了中断，为了保护现场，CPU将CS和IP,此时的位置,入栈，导致了内存相关位置内容的改变。</p><h2 id="实验三"><a href="#实验三" class="headerlink" title="实验三"></a>实验三</h2><ol><li>将下面的程序保存为t1.asm文件，将其生成可执行文件t1.exe。</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">assume cs:codesg</span><br><span class="line">codesg segment</span><br><span class="line">mov ax, 2000H</span><br><span class="line">mov ss, ax</span><br><span class="line">mov sp, 0</span><br><span class="line">add sp, 10</span><br><span class="line">pop ax</span><br><span class="line">pop bx</span><br><span class="line">push ax</span><br><span class="line">push bx</span><br><span class="line">pop ax</span><br><span class="line">pop bx</span><br><span class="line">mov ax, 4c00h</span><br><span class="line">int 21h</span><br><span class="line">codesg ends</span><br><span class="line">end</span><br></pre></td></tr></table></figure><p>这个没什么好说的….</p><ol><li>用Debug跟踪t1.exe的执行过程，写出每一步执行后，相关寄存器中的内容和栈顶的内容。</li></ol><table><thead><tr><th>结果</th></tr></thead><tbody><tr><td>ax 2000H</td></tr><tr><td>ss 2000H</td></tr><tr><td>sp 0000H</td></tr><tr><td>sp 000AH</td></tr><tr><td>ax 0 sp 000cH</td></tr><tr><td>bx 0 sp 000EH</td></tr><tr><td>sp 000cH</td></tr><tr><td>sp 000AH</td></tr><tr><td>ax 0 sp 000cH</td></tr><tr><td>bx 0 sp 000EH</td></tr><tr><td>ax 4c00H</td></tr><tr><td>empty</td></tr></tbody></table><ol><li>PSP头两个字节为CD 20,用debug加载t1.exe.查看PSP内容：</li></ol><p>PSP区域地址范围为:ds:0~ds:ff.用d命令查看即可</p><h2 id="实验四"><a href="#实验四" class="headerlink" title="实验四"></a>实验四</h2><ol><li>编程，向内存0:200～0:23F依此传送数据0～63（3FH）。</li></ol><p>见下</p><ol><li>编程，向内存0:200～0:23F依此传送数据0～63（3FH），程序中只能使用9条指令，9条指令中包括“mov ax, 4c00h”和“int 21h”。</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">assume cs:code</span><br><span class="line">code segment</span><br><span class="line">mov ax, 0020h</span><br><span class="line">mov ds, ax</span><br><span class="line">mov bx, 0</span><br><span class="line">mov cx, 64</span><br><span class="line">s:   mov [bx], bl ;此处注意![bx]为一字节,用bl</span><br><span class="line">inc bl</span><br><span class="line">loop s</span><br><span class="line">mov ax, 4c00h</span><br><span class="line">int 21h</span><br><span class="line">code ends</span><br><span class="line">end</span><br></pre></td></tr></table></figure><ol><li>下面的程序的功能是将“mov ax, 4c00h”之前的指令复制到内存的0:200处，补全程序，上机调试，跟踪运行结果。</li></ol><p>下面的程序的功能是将“mov ax, 4c00h”之前的指令复制到内存的0:200处，补全程序，上机调试，跟踪运行结果。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">assume cs:code</span><br><span class="line">code segment</span><br><span class="line">mov ax, _____</span><br><span class="line">mov ds, ax</span><br><span class="line">mov ax, 0020h</span><br><span class="line">mov es, ax</span><br><span class="line">mov bx, 0</span><br><span class="line">mov cx, _____</span><br><span class="line">s:      mov al, [bx]</span><br><span class="line">mov es:[bx], al</span><br><span class="line">inc bx</span><br><span class="line">loop s</span><br><span class="line">mov ax, 4c00h</span><br><span class="line">int 21h</span><br><span class="line">code ends</span><br><span class="line">end</span><br></pre></td></tr></table></figure><p>程序入口为cs:0(ip=0),所以第一空处传递段地址为cs</p><p>而程序总代码长度可通过debug加载后通过u命令看出.先将第二空位随便设为1，加载后观察mov ax,4c00h之前代码为0000~0016h，总长度为23.</p><h2 id="实验5-编写、调试具有多个段的程序"><a href="#实验5-编写、调试具有多个段的程序" class="headerlink" title="实验5 编写、调试具有多个段的程序"></a>实验5 编写、调试具有多个段的程序</h2><h3 id="1-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"><a href="#1-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。" class="headerlink" title="1.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"></a>1.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。</h3><p>答案：</p><p>data段中的数据不变。</p><p>07f3、07f4、07f2（答案不唯一）</p><p>X-2、X-1</p><h3 id="2-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"><a href="#2-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。" class="headerlink" title="2.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"></a>2.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。</h3><p>答案：</p><p>data段中的数据不变。</p><p>07f3、07f4、07f2（答案不唯一）</p><p>X-2、X-1</p><p>可以知道：数据段空间大小为定义数据所需的16字节的最小整数倍</p><p>([N]+1) * 16   (字节对齐)</p><h3 id="3-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"><a href="#3-将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。" class="headerlink" title="3.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。"></a>3.将下面的程序编译连接，用Debug加载、跟踪，然后回答问题。</h3><p>答案:</p><p>(3) x+3 x+4</p><h3 id="4-如果将1-2-3-题中的最后一条伪指令“end-start”改为“end”（也就是说，不指明程序的入口），则哪个程序仍然可以正确执行？请说明原因。"><a href="#4-如果将1-2-3-题中的最后一条伪指令“end-start”改为“end”（也就是说，不指明程序的入口），则哪个程序仍然可以正确执行？请说明原因。" class="headerlink" title="4.如果将1. 2. 3.题中的最后一条伪指令“end start”改为“end”（也就是说，不指明程序的入口），则哪个程序仍然可以正确执行？请说明原因。"></a>4.如果将1. 2. 3.题中的最后一条伪指令“end start”改为“end”（也就是说，不指明程序的入口），则哪个程序仍然可以正确执行？请说明原因。</h3><p>答案：<br>程序3，在不指明程序入口的情况下，程序默认按照顺序从头开始执行.</p><h3 id="5-程序如下，编写code段中的代码，将a段和b段中的数据依此相加，将结果存到c段中。"><a href="#5-程序如下，编写code段中的代码，将a段和b段中的数据依此相加，将结果存到c段中。" class="headerlink" title="5.程序如下，编写code段中的代码，将a段和b段中的数据依此相加，将结果存到c段中。"></a>5.程序如下，编写code段中的代码，将a段和b段中的数据依此相加，将结果存到c段中。</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">start:</span><br><span class="line">      mov ax, a</span><br><span class="line">      mov ds, ax</span><br><span class="line">      mov ax, b</span><br><span class="line">      mov es, ax</span><br><span class="line">      mov ax, c</span><br><span class="line">      mov ss, ax</span><br><span class="line">      mov bx 0</span><br><span class="line">      mov cx 8</span><br><span class="line">      s:</span><br><span class="line">      mov al, [bx]</span><br><span class="line">      add al, es:[bx]</span><br><span class="line">      mov ss:[bx], al</span><br><span class="line">      inc bx</span><br><span class="line">      loop s</span><br><span class="line"></span><br><span class="line">      mov ax, 4c00H</span><br><span class="line">      int 21h</span><br></pre></td></tr></table></figure><h3 id="6-程序如下，编写code段中的代码，用push指令将a段中的前8个字型数据，逆序存储到b段中。"><a href="#6-程序如下，编写code段中的代码，用push指令将a段中的前8个字型数据，逆序存储到b段中。" class="headerlink" title="6.程序如下，编写code段中的代码，用push指令将a段中的前8个字型数据，逆序存储到b段中。"></a>6.程序如下，编写code段中的代码，用push指令将a段中的前8个字型数据，逆序存储到b段中。</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">start:</span><br><span class="line">mov ax, b</span><br><span class="line">mov ss, ax</span><br><span class="line">mov sp, 16</span><br><span class="line">mov ax, a</span><br><span class="line">mov ds, ax</span><br><span class="line">mov bx, 0</span><br><span class="line">mov cx, 8</span><br><span class="line">s:</span><br><span class="line">push [bx]</span><br><span class="line">add bx,2</span><br><span class="line">loop s</span><br><span class="line"></span><br><span class="line">mov ax, 4c00H</span><br><span class="line">int 21h</span><br></pre></td></tr></table></figure><h2 id="实验6-实践课程中的程序"><a href="#实验6-实践课程中的程序" class="headerlink" title="实验6 实践课程中的程序"></a>实验6 实践课程中的程序</h2><p>1.将课程中所有讲解过的程序上机调试，用Debug跟踪其执行过程，并在过程中进一步理解所讲内容。</p><p>2.编程，完成问题7.9中的程序</p><p>解决方案有书上三种,用的是栈储存<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">start:</span><br><span class="line">mov ax, codesg</span><br><span class="line">mov ds, ax</span><br><span class="line">moe ax, stacksg</span><br><span class="line">mov ss, ax</span><br><span class="line">mov sp, 16</span><br><span class="line">mov bx, 0</span><br><span class="line">mov cx, 4</span><br><span class="line"></span><br><span class="line">s:</span><br><span class="line">push cx</span><br><span class="line">mov cx, 4</span><br><span class="line">mov si, 0</span><br><span class="line"></span><br><span class="line">s0:</span><br><span class="line">mov al, [bx+si+3]</span><br><span class="line">and al, 11011111b</span><br><span class="line">mov [bx+si+3], al</span><br><span class="line">inc si</span><br><span class="line">loop s0</span><br><span class="line">add bx,16</span><br><span class="line"></span><br><span class="line">pop cx</span><br><span class="line">loop s</span><br><span class="line"></span><br><span class="line">mov ax,4c00H</span><br><span class="line">int 21h</span><br></pre></td></tr></table></figure></p><h2 id="实验7-寻址方式在结构化数据访问中的应用"><a href="#实验7-寻址方式在结构化数据访问中的应用" class="headerlink" title="实验7 寻址方式在结构化数据访问中的应用"></a>实验7 寻址方式在结构化数据访问中的应用</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line">assume cs:codesg, ss:stack</span><br><span class="line"></span><br><span class="line">data segment</span><br><span class="line">db &apos;1975&apos;, &apos;1976&apos;, &apos;1977&apos;, &apos;1978&apos;, &apos;1979&apos;, &apos;1980&apos;, &apos;1981&apos;, &apos;1982&apos;, &apos;1983&apos;</span><br><span class="line">db &apos;1984&apos;, &apos;1985&apos;, &apos;1986&apos;, &apos;1987&apos;, &apos;1988&apos;, &apos;1989&apos;, &apos;1990&apos;, &apos;1991&apos;, &apos;1992&apos;</span><br><span class="line">db &apos;1993&apos;, &apos;1994&apos;, &apos;1995&apos;</span><br><span class="line"></span><br><span class="line">dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514</span><br><span class="line">dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000</span><br><span class="line"></span><br><span class="line">dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226</span><br><span class="line">dw 11542, 14430, 15257, 17800</span><br><span class="line">data ends</span><br><span class="line"></span><br><span class="line">table segment</span><br><span class="line">db 21 dup (&apos;year summ ne ?? &apos;)</span><br><span class="line">table ends</span><br><span class="line"></span><br><span class="line">stack segment</span><br><span class="line">dw 8 dup (0)         ;存放cx</span><br><span class="line">stack ends</span><br><span class="line"></span><br><span class="line">codesg segment</span><br><span class="line">start:</span><br><span class="line">mov ax, stack</span><br><span class="line">mov ss, ax</span><br><span class="line">mov sp, 16</span><br><span class="line">mov ax, table</span><br><span class="line">mov ds, dx</span><br><span class="line">mov ax, date</span><br><span class="line">mov es, ax</span><br><span class="line"></span><br><span class="line">mov bx, 0</span><br><span class="line">mov cx, 21</span><br><span class="line">mov si, 0</span><br><span class="line">year:</span><br><span class="line">push cx</span><br><span class="line">mov cx, 4</span><br><span class="line">mov di, 0</span><br><span class="line">s:</span><br><span class="line">mov al, es:[si]</span><br><span class="line">mov [bx+di], al</span><br><span class="line">inc si</span><br><span class="line">inc di</span><br><span class="line">loop s</span><br><span class="line">add bx,16</span><br><span class="line">pop cx</span><br><span class="line">loop s</span><br><span class="line"></span><br><span class="line">mov cx, 21</span><br><span class="line">mov bx, 0</span><br><span class="line">income:</span><br><span class="line">mov ax, es:[si]</span><br><span class="line">mov 5[bx], ax</span><br><span class="line">add si, 2</span><br><span class="line">mov ax, es:[si]</span><br><span class="line">mov 7[bx], ax</span><br><span class="line">add si, 2</span><br><span class="line">add bx, 16</span><br><span class="line">loop income</span><br><span class="line"></span><br><span class="line">mov cx, 21</span><br><span class="line">mov bx, 0</span><br><span class="line">staff:  mov ax, es:[si]</span><br><span class="line">mov [10+bx], ax</span><br><span class="line">add si, 2</span><br><span class="line">add bx, 16</span><br><span class="line">loop staff</span><br><span class="line"></span><br><span class="line">mov cx, 21</span><br><span class="line">mov bx, 0</span><br><span class="line">average:mov ax, [bx+5]</span><br><span class="line">mov dx, [bx+7]</span><br><span class="line">div word ptr [bx+10]</span><br><span class="line">mov [13+bx], ax</span><br><span class="line">add bx, 16</span><br><span class="line">loop average</span><br><span class="line"></span><br><span class="line">mov ax, 4c00h</span><br><span class="line">int 21h</span><br><span class="line"></span><br><span class="line">codesg ends</span><br><span class="line">end start</span><br></pre></td></tr></table></figure><h2 id="实验8-分析一个奇怪的程序"><a href="#实验8-分析一个奇怪的程序" class="headerlink" title="实验8 分析一个奇怪的程序"></a>实验8 分析一个奇怪的程序</h2><p>分析下面的程序，在运行前思考，这个程序可以正确返回吗？<br>运行后再思考：为什么是这种结果？<br>通过这个程序加深对相关内容的理解。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">assume cs:codesg</span><br><span class="line">codesg segment</span><br><span class="line">mov ax, 4c00h</span><br><span class="line">int 21h</span><br><span class="line">start: mov ax, 0</span><br><span class="line">s:     nop</span><br><span class="line">nop</span><br><span class="line">mov di, offset s</span><br><span class="line">mov si, offset s2</span><br><span class="line">mov ax, cs:[si]</span><br><span class="line">mov cs:[di], ax</span><br><span class="line">s0:    jmp short s</span><br><span class="line">s1:    mov ax, 0</span><br><span class="line">int 21h</span><br><span class="line">mov ax, 0</span><br><span class="line">s2:    jmp short s1</span><br><span class="line">nop</span><br><span class="line">codesg ends</span><br><span class="line">end start</span><br></pre></td></tr></table></figure><blockquote><p>jmp short 标号、jmp near ptr 标号、jcxz 标号、loop 标号等几种汇编指令，它们对 IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。不包含转移的目的地址，而包含的是到目的地址的位移距离。方便了程序段在内存中的浮动装配。</p></blockquote><p>能成功返回,通过ax将s2的地址传送到s,<code>jmp short s</code>实际跳转到s2,而s2中<code>jmp short s1</code>计算的是s1,s2之间的偏移量,然后加上s的地址,实际跳转到首地址,完成返回</p><h2 id="实验9-根据材料编程"><a href="#实验9-根据材料编程" class="headerlink" title="实验9 根据材料编程"></a>实验9 根据材料编程</h2><p>编程：在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’welcome to masm!’。<br>编程所需的只是通过阅读、分析下面的材料获得。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">assume ds:data, cs:code</span><br><span class="line"></span><br><span class="line">data segment</span><br><span class="line">db &apos;welcome to masm!&apos;</span><br><span class="line">data ends</span><br><span class="line"></span><br><span class="line">code segment</span><br><span class="line">start:  mov ax, data</span><br><span class="line">mov ds, ax</span><br><span class="line">mov ax, 0B800H</span><br><span class="line">mov es, ax</span><br><span class="line"></span><br><span class="line">mov bx, 1664</span><br><span class="line">mov si, 0</span><br><span class="line">mov cx, 16</span><br><span class="line">char1:  mov al, [si]</span><br><span class="line">mov ah, 10000010B</span><br><span class="line">mov es:[bx], ax</span><br><span class="line">add bx, 2</span><br><span class="line">inc si</span><br><span class="line">loop char1</span><br><span class="line"></span><br><span class="line">mov bx, 1824</span><br><span class="line">mov si, 0</span><br><span class="line">mov cx, 16</span><br><span class="line">char2:  mov al, [si]</span><br><span class="line">mov ah, 10100100B</span><br><span class="line">mov es:[bx], ax</span><br><span class="line">add bx, 2</span><br><span class="line">inc si</span><br><span class="line">loop char2</span><br><span class="line"></span><br><span class="line">mov bx, 1984</span><br><span class="line">mov si, 0</span><br><span class="line">mov cx, 16</span><br><span class="line">char3:  mov al, [si]</span><br><span class="line">mov ah, 11110001B</span><br><span class="line">mov es:[bx], ax</span><br><span class="line">add bx, 2</span><br><span class="line">inc si</span><br><span class="line">loop char3</span><br><span class="line"></span><br><span class="line">mov ax, 4C00H</span><br><span class="line">int 21H</span><br><span class="line">code ends</span><br><span class="line">end start</span><br></pre></td></tr></table></figure><h2 id="实验10-编写子程序"><a href="#实验10-编写子程序" class="headerlink" title="实验10 编写子程序"></a>实验10 编写子程序</h2><h3 id="1-显示字符串"><a href="#1-显示字符串" class="headerlink" title="1.显示字符串"></a>1.显示字符串</h3><blockquote><p>注意事项：</p></blockquote><blockquote><p>1.计算偏移地址的时候，以bx作为偏移量，ax不行</p></blockquote><blockquote><p>例如 es：[bx+si]  而不是 es:[ax+si]</p></blockquote><blockquote><p>2.子程序开始的时候把所有的寄存器入栈，方便接下来使用，结束的时候出栈</p></blockquote><blockquote><p>3.计算数组偏移地址的时候，用mul</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line">assume cs:code,ds:data,ss:stack  </span><br><span class="line"></span><br><span class="line">data segment  </span><br><span class="line">    db &apos;welcome to masm!&apos;,0  </span><br><span class="line">data ends  </span><br><span class="line"></span><br><span class="line">stack segment  </span><br><span class="line">    dw 8 dup (0)  </span><br><span class="line">stack ends  </span><br><span class="line"></span><br><span class="line">code segment  </span><br><span class="line">start:  mov dh,8  </span><br><span class="line">    mov dl,3      ;第八行,第三列  </span><br><span class="line"></span><br><span class="line">    mov cl,2      ;颜色  </span><br><span class="line"></span><br><span class="line">    mov ax,data  </span><br><span class="line">    mov ds,ax     ;ds指向数据段  </span><br><span class="line"></span><br><span class="line">    mov si,0  </span><br><span class="line">    call show_str  </span><br><span class="line"></span><br><span class="line">    mov ax,4c00h  </span><br><span class="line">    int 21h  </span><br><span class="line"></span><br><span class="line">show_str:  </span><br><span class="line">    push dx  </span><br><span class="line">    push cx  </span><br><span class="line">    push ax  </span><br><span class="line">    push ss  </span><br><span class="line">    push si    ;子程序开始所有寄存器入栈  </span><br><span class="line"></span><br><span class="line">    mov ax,0B800h  </span><br><span class="line">    mov es,ax    ;es指向显示的起始地址  </span><br><span class="line"></span><br><span class="line">;计算行偏移量  </span><br><span class="line">    mov al,0a0h ;160个字节一行  </span><br><span class="line">    dec dh      ;行号减一,00 - dh-1  共dh行  </span><br><span class="line">    mul dh      ;相乘  结果放在ax里  </span><br><span class="line">    mov bx,ax   ;偏移量  </span><br><span class="line"></span><br><span class="line">    mov al,2   ;一列两个字符  </span><br><span class="line">    dec dl      ;列号减一,00 -dl-1 共dl列  </span><br><span class="line">    mul al  </span><br><span class="line">    add bx,ax  ;偏移地址计算完成  </span><br><span class="line"></span><br><span class="line">    mov di,0     ;di字符读取时候每次的偏移 每次加1  </span><br><span class="line">    mov si,0  </span><br><span class="line"></span><br><span class="line">    mov al,cl   ;颜色暂时保存在al里 cx需要用到  </span><br><span class="line">s1:   </span><br><span class="line">    mov ch,0    ;置0  </span><br><span class="line">    mov cl,ds:[di]  ;字符放在cl里  </span><br><span class="line">    jcxz ok  </span><br><span class="line">    mov ch,al     </span><br><span class="line">    mov es:[bx+si],cx   ;字符颜色一起放入显示位置  </span><br><span class="line"></span><br><span class="line">    add si,2  </span><br><span class="line">    inc di  </span><br><span class="line">jmp short s1  </span><br><span class="line">ok:   </span><br><span class="line">    pop si    ;子程序开始所有寄存器入栈  </span><br><span class="line">    pop ss  </span><br><span class="line">    pop ax  </span><br><span class="line">    pop cx  </span><br><span class="line">    pop dx  </span><br><span class="line">    ret</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;扯话&quot;&gt;&lt;a href=&quot;#扯话&quot; class=&quot;headerlink&quot; title=&quot;扯话&quot;&gt;&lt;/a&gt;扯话&lt;/h1&gt;&lt;p&gt;开始啃汇编啦,看过CSAPP第三章后,感觉上手还是比较友好的&lt;/p&gt;
&lt;p&gt;准备顺序大概是&lt;/p&gt;
&lt;p&gt;王爽汇编语言  -&amp;gt;  x8
      
    
    </summary>
    
    
      <category term="汇编语言" scheme="https://jackwener.github.io/tags/%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80/"/>
    
  </entry>
  
  <entry>
    <title>CSAPP bomblab（伪）报告</title>
    <link href="https://jackwener.github.io/2018/05/11/bombLab/"/>
    <id>https://jackwener.github.io/2018/05/11/bombLab/</id>
    <published>2018-05-10T17:00:00.000Z</published>
    <updated>2018-05-11T07:56:19.972Z</updated>
    
    <content type="html"><![CDATA[<p>上个月就开始搞CSAPP了,之前书没看好,LAB做起来也磕磕绊绊.把书的第三章重新看了遍后,再来做.</p><p>另外,大概也要定个计划把汇编学了</p><p>之前GDB一直不太会用,通过这个机会也是学习了下,后面希望提升自己的学习力,什么不会遇上了能快速的学习.</p><blockquote><p>注意不要让bomb爆炸,虽然我们不会被扣分…..我一开始都是直接炸来炸去的…..</p></blockquote><p>每做完一个部分,就可以将答案保持在<code>solution.txt</code>中,避免重复输入,使用<code>set args ./solution.txt</code>来设置答案</p><h2 id="phase-1"><a href="#phase-1" class="headerlink" title="phase_1"></a>phase_1</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disassemble phase_1</span><br><span class="line">Dump of assembler code for function phase_1:</span><br><span class="line">   0x0000000000400ee0 &lt;+0&gt;:sub    $0x8,%rsp</span><br><span class="line">   0x0000000000400ee4 &lt;+4&gt;:mov    $0x402400,%esi</span><br><span class="line">   0x0000000000400ee9 &lt;+9&gt;:callq  0x401338 &lt;strings_not_equal&gt;</span><br><span class="line">   0x0000000000400eee &lt;+14&gt;:test   %eax,%eax</span><br><span class="line">   0x0000000000400ef0 &lt;+16&gt;:je     0x400ef7 &lt;phase_1+23&gt;</span><br><span class="line">   0x0000000000400ef2 &lt;+18&gt;:callq  0x40143a &lt;explode_bomb&gt;</span><br><span class="line">   0x0000000000400ef7 &lt;+23&gt;:add    $0x8,%rsp</span><br><span class="line">   0x0000000000400efb &lt;+27&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure><p>补个知识</p><blockquote></blockquote><ol><li>常用寄存器有16个，分为x86通用寄存器以及r8-r15寄存器。</li><li>通用寄存器中，函数执行前后必须保持原始的寄存器有3个：是rbx、rbp、rsp。rx寄存器中，最后4个必须保持原值：r12、r13、r14、r15。<br>保持原值的意义是为了让当前函数有可信任的寄存器，减小在函数调用过程中的保存&amp;恢复操作。除了rbp、rsp用于特定用途外，其余5个寄存器可随意使用。</li><li>通用寄存器中，不必假设保存值可随意使用的寄存器有5个：是rax、rcx、rdx、rdi、rsi。其中rax用于第一个返回寄存器（当 然也可以用于其它用途），rdx用于第二个返回寄存器（在调用函数时也用于第三个参数寄存器）。rcx用于第四个参数。rdi用于第一个参数。rsi用于 第二个函数参数。</li><li>r8、r9分配用于第5、第6个参数。</li></ol><p>第一题还是不难的,注意到<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">0x0000000000400ee4 &lt;+4&gt;:mov    $0x402400,%esi</span><br><span class="line">0x0000000000400ee9 &lt;+9&gt;:callq  0x401338 &lt;strings_not_equal&gt;</span><br></pre></td></tr></table></figure></p><p>从0x402400读入一个数到%esi,然后作为第二个参数传入函数中<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(gdb) x/s 0x402400</span><br><span class="line">0x402400:&quot;Border relations with Canada have never been better.&quot;</span><br></pre></td></tr></table></figure></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">break phase_1</span><br><span class="line">run</span><br><span class="line">输入一个字符串</span><br><span class="line">print (char*)$rdi   第一个参数</span><br></pre></td></tr></table></figure><p>发现第一个参数就是我们输入的,和第二个$0x402400处的对比,然后return 0就不会炸</p><h2 id="phase-2"><a href="#phase-2" class="headerlink" title="phase_2"></a>phase_2</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas phase_2</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function phase_2:</span><br><span class="line">   <span class="number">0x0000000000400efc</span> &lt;+<span class="number">0</span>&gt;:push   %rbp</span><br><span class="line">   <span class="number">0x0000000000400efd</span> &lt;+<span class="number">1</span>&gt;:push   %rbx</span><br><span class="line">   <span class="number">0x0000000000400efe</span> &lt;+<span class="number">2</span>&gt;:sub    $<span class="number">0x28</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000400f02</span> &lt;+<span class="number">6</span>&gt;:mov    %rsp,%rsi</span><br><span class="line">   <span class="number">0x0000000000400f05</span> &lt;+<span class="number">9</span>&gt;:callq  <span class="number">0x40145c</span> &lt;read_six_numbers&gt;</span><br><span class="line">   <span class="number">0x0000000000400f0a</span> &lt;+<span class="number">14</span>&gt;:cmpl   $<span class="number">0x1</span>,(%rsp)   #比较第一个数 和 <span class="number">1</span></span><br><span class="line">   <span class="number">0x0000000000400f0e</span> &lt;+<span class="number">18</span>&gt;:je     <span class="number">0x400f30</span> &lt;phase_2+<span class="number">52</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f10</span> &lt;+<span class="number">20</span>&gt;:callq  <span class="number">0x40143a</span>   #炸炸炸 &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000400f15</span> &lt;+<span class="number">25</span>&gt;:jmp    <span class="number">0x400f30</span> &lt;phase_2+<span class="number">52</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f17</span> &lt;+<span class="number">27</span>&gt;:mov    <span class="number">-0x4</span>(%rbx),%eax  保存rbx的值给%eax</span><br><span class="line">   <span class="number">0x0000000000400f1a</span> &lt;+<span class="number">30</span>&gt;:add    %eax,%eax   #乘以<span class="number">2</span></span><br><span class="line">   <span class="number">0x0000000000400f1c</span> &lt;+<span class="number">32</span>&gt;:cmp    %eax,(%rbx)   #第二个数和之前数的<span class="number">2</span>倍比较</span><br><span class="line">   <span class="number">0x0000000000400f1e</span> &lt;+<span class="number">34</span>&gt;:je     <span class="number">0x400f25</span> &lt;phase_2+<span class="number">41</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f20</span> &lt;+<span class="number">36</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000400f25</span> &lt;+<span class="number">41</span>&gt;:add    $<span class="number">0x4</span>,%rbx</span><br><span class="line">   <span class="number">0x0000000000400f29</span> &lt;+<span class="number">45</span>&gt;:cmp    %rbp,%rbx   # 比较是否为最后一个值</span><br><span class="line">   <span class="number">0x0000000000400f2c</span> &lt;+<span class="number">48</span>&gt;:jne    <span class="number">0x400f17</span> &lt;phase_2+<span class="number">27</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f2e</span> &lt;+<span class="number">50</span>&gt;:jmp    <span class="number">0x400f3c</span> &lt;phase_2+<span class="number">64</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f30</span> &lt;+<span class="number">52</span>&gt;:lea    <span class="number">0x4</span>(%rsp),%rbx</span><br><span class="line">   <span class="number">0x0000000000400f35</span> &lt;+<span class="number">57</span>&gt;:lea    <span class="number">0x18</span>(%rsp),%rbp</span><br><span class="line">   <span class="number">0x0000000000400f3a</span> &lt;+<span class="number">62</span>&gt;:jmp    <span class="number">0x400f17</span> &lt;phase_2+<span class="number">27</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f3c</span> &lt;+<span class="number">64</span>&gt;:add    $<span class="number">0x28</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000400f40</span> &lt;+<span class="number">68</span>&gt;:pop    %rbx</span><br><span class="line">   <span class="number">0x0000000000400f41</span> &lt;+<span class="number">69</span>&gt;:pop    %rbp</span><br><span class="line">   <span class="number">0x0000000000400f42</span> &lt;+<span class="number">70</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure><p>提醒还是有的,注意&lt;read_six_numbers&gt;<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas read_six_numbers</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function read_six_numbers:</span><br><span class="line">   <span class="number">0x000000000040145c</span> &lt;+<span class="number">0</span>&gt;:sub    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000401460</span> &lt;+<span class="number">4</span>&gt;:mov    %rsi,%rdx</span><br><span class="line">   <span class="number">0x0000000000401463</span> &lt;+<span class="number">7</span>&gt;:lea    <span class="number">0x4</span>(%rsi),%rcx</span><br><span class="line">   <span class="number">0x0000000000401467</span> &lt;+<span class="number">11</span>&gt;:lea    <span class="number">0x14</span>(%rsi),%rax</span><br><span class="line">   <span class="number">0x000000000040146b</span> &lt;+<span class="number">15</span>&gt;:mov    %rax,<span class="number">0x8</span>(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401470</span> &lt;+<span class="number">20</span>&gt;:lea    <span class="number">0x10</span>(%rsi),%rax</span><br><span class="line">   <span class="number">0x0000000000401474</span> &lt;+<span class="number">24</span>&gt;:mov    %rax,(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401478</span> &lt;+<span class="number">28</span>&gt;:lea    <span class="number">0xc</span>(%rsi),%r9</span><br><span class="line">   <span class="number">0x000000000040147c</span> &lt;+<span class="number">32</span>&gt;:lea    <span class="number">0x8</span>(%rsi),%r8</span><br><span class="line">   <span class="number">0x0000000000401480</span> &lt;+<span class="number">36</span>&gt;:mov    $<span class="number">0x4025c3</span>,%esi</span><br><span class="line">   <span class="number">0x0000000000401485</span> &lt;+<span class="number">41</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x000000000040148a</span> &lt;+<span class="number">46</span>&gt;:callq  <span class="number">0x400bf0</span> &lt;__isoc99_sscanf@plt&gt;</span><br><span class="line">   <span class="number">0x000000000040148f</span> &lt;+<span class="number">51</span>&gt;:cmp    $<span class="number">0x5</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000401492</span> &lt;+<span class="number">54</span>&gt;:jg     <span class="number">0x401499</span> &lt;read_six_numbers+<span class="number">61</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401494</span> &lt;+<span class="number">56</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000401499</span> &lt;+<span class="number">61</span>&gt;:add    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x000000000040149d</span> &lt;+<span class="number">65</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure></p><p>可以看出,这个函数是读了6个32位整数,首先有0x18 = 24 = 6 x 4,4x8位就是32位,另外下面的代码也有读入过程.</p><p><del>继续看phase_2</del></p><p><del>cmpl   $0x1,(%rsp)`比较第一个数 和 1</del></p><p>直接写注释来的好.(⊙﹏⊙)</p><p>大概就是1乘以2 ,然后重复…</p><p>答案就是<code>1 2 4 8 16 32</code></p><p>然后设置断点验证即可</p><h2 id="phase-3"><a href="#phase-3" class="headerlink" title="phase_3"></a>phase_3</h2><p><del>不肝了,今天1.30睡的,明天7.00起,要不然给自己耳光.对应刚刚才写了的随想,肝帝计划,计划容易一时,难在坚持,加油,明早继续更</del></p><p>2.00睡不着,起来更</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas phase_3</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function phase_3:</span><br><span class="line">   <span class="number">0x0000000000400f43</span> &lt;+<span class="number">0</span>&gt;:sub    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000400f47</span> &lt;+<span class="number">4</span>&gt;:lea    <span class="number">0xc</span>(%rsp),%rcx</span><br><span class="line">   <span class="number">0x0000000000400f4c</span> &lt;+<span class="number">9</span>&gt;:lea    <span class="number">0x8</span>(%rsp),%rdx</span><br><span class="line">   <span class="number">0x0000000000400f51</span> &lt;+<span class="number">14</span>&gt;:mov    $<span class="number">0x4025cf</span>,%esi</span><br><span class="line">   <span class="number">0x0000000000400f56</span> &lt;+<span class="number">19</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f5b</span> &lt;+<span class="number">24</span>&gt;:callq  <span class="number">0x400bf0</span> &lt;__isoc99_sscanf@plt&gt;</span><br><span class="line">   <span class="number">0x0000000000400f60</span> &lt;+<span class="number">29</span>&gt;:cmp    $<span class="number">0x1</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f63</span> &lt;+<span class="number">32</span>&gt;:jg     <span class="number">0x400f6a</span> &lt;phase_3+<span class="number">39</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f65</span> &lt;+<span class="number">34</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000400f6a</span> &lt;+<span class="number">39</span>&gt;:cmpl   $<span class="number">0x7</span>,<span class="number">0x8</span>(%rsp)</span><br><span class="line">   <span class="number">0x0000000000400f6f</span> &lt;+<span class="number">44</span>&gt;:ja     <span class="number">0x400fad</span> &lt;phase_3+<span class="number">106</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f71</span> &lt;+<span class="number">46</span>&gt;:mov    <span class="number">0x8</span>(%rsp),%eax</span><br><span class="line">   <span class="number">0x0000000000400f75</span> &lt;+<span class="number">50</span>&gt;:jmpq   *<span class="number">0x402470</span>(,%rax,<span class="number">8</span>)</span><br><span class="line">   <span class="number">0x0000000000400f7c</span> &lt;+<span class="number">57</span>&gt;:mov    $<span class="number">0xcf</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f81</span> &lt;+<span class="number">62</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f83</span> &lt;+<span class="number">64</span>&gt;:mov    $<span class="number">0x2c3</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f88</span> &lt;+<span class="number">69</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f8a</span> &lt;+<span class="number">71</span>&gt;:mov    $<span class="number">0x100</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f8f</span> &lt;+<span class="number">76</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f91</span> &lt;+<span class="number">78</span>&gt;:mov    $<span class="number">0x185</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f96</span> &lt;+<span class="number">83</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f98</span> &lt;+<span class="number">85</span>&gt;:mov    $<span class="number">0xce</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400f9d</span> &lt;+<span class="number">90</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400f9f</span> &lt;+<span class="number">92</span>&gt;:mov    $<span class="number">0x2aa</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400fa4</span> &lt;+<span class="number">97</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400fa6</span> &lt;+<span class="number">99</span>&gt;:mov    $<span class="number">0x147</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400fab</span> &lt;+<span class="number">104</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400fad</span> &lt;+<span class="number">106</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000400fb2</span> &lt;+<span class="number">111</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400fb7</span> &lt;+<span class="number">116</span>&gt;:jmp    <span class="number">0x400fbe</span> &lt;phase_3+<span class="number">123</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400fb9</span> &lt;+<span class="number">118</span>&gt;:mov    $<span class="number">0x137</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400fbe</span> &lt;+<span class="number">123</span>&gt;:cmp    <span class="number">0xc</span>(%rsp),%eax</span><br><span class="line">   <span class="number">0x0000000000400fc2</span> &lt;+<span class="number">127</span>&gt;:je     <span class="number">0x400fc9</span> &lt;phase_3+<span class="number">134</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400fc4</span> &lt;+<span class="number">129</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000400fc9</span> &lt;+<span class="number">134</span>&gt;:add    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000400fcd</span> &lt;+<span class="number">138</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure><p>注意到<code>jmpq   *0x402470(,%rax,8)</code>我们可以发现程序使用了跳转表<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">(gdb) x/1xg 0x402470</span><br><span class="line">0x402470:0x0000000000400f7c</span><br><span class="line">(gdb) x/1xg 0x402478</span><br><span class="line">0x402478:0x0000000000400fb9</span><br><span class="line">(gdb) x/1xg 0x402480</span><br><span class="line">0x402480:0x0000000000400f83</span><br><span class="line">(gdb) x/1xg 0x402488</span><br><span class="line">0x402488:0x0000000000400f8a</span><br><span class="line">(gdb) x/1xg 0x402490</span><br><span class="line">0x402490:0x0000000000400f91</span><br><span class="line">(gdb) x/1xg 0x402498</span><br><span class="line">0x402498:0x0000000000400f98</span><br><span class="line">(gdb) x/1xg 0x4024a0</span><br><span class="line">0x4024a0:0x0000000000400f9f</span><br><span class="line">(gdb) x/1xg 0x4024a8</span><br><span class="line">0x4024a8:0x0000000000400fa6</span><br></pre></td></tr></table></figure></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">%rax(输入参数1)       跳转地址            0xc(%rsp)(输入参数2)</span><br><span class="line">0               0x0000000000400f7c       0xcf  207</span><br><span class="line">1               0x0000000000400fb9       0x137 311</span><br><span class="line">2               0x0000000000400f83       0x2c3 707</span><br><span class="line">3               0x0000000000400f8a       0x100 256</span><br><span class="line">4               0x0000000000400f91       0x185 389</span><br><span class="line">5               0x0000000000400f98       0xce  206</span><br><span class="line">6               0x0000000000400f9f       0x2aa 682</span><br><span class="line">7               0x0000000000400fa6       0x147 327</span><br></pre></td></tr></table></figure><p>ok啦</p><h2 id="phase-4"><a href="#phase-4" class="headerlink" title="phase_4"></a>phase_4</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas phase_4</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function phase_4:</span><br><span class="line">   <span class="number">0x000000000040100c</span> &lt;+<span class="number">0</span>&gt;:sub    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000401010</span> &lt;+<span class="number">4</span>&gt;:lea    <span class="number">0xc</span>(%rsp),%rcx</span><br><span class="line">   <span class="number">0x0000000000401015</span> &lt;+<span class="number">9</span>&gt;:lea    <span class="number">0x8</span>(%rsp),%rdx</span><br><span class="line">   <span class="number">0x000000000040101a</span> &lt;+<span class="number">14</span>&gt;:mov    $<span class="number">0x4025cf</span>,%esi</span><br><span class="line">   <span class="number">0x000000000040101f</span> &lt;+<span class="number">19</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000401024</span> &lt;+<span class="number">24</span>&gt;:callq  <span class="number">0x400bf0</span> &lt;__isoc99_sscanf@plt&gt;</span><br><span class="line">   <span class="number">0x0000000000401029</span> &lt;+<span class="number">29</span>&gt;:cmp    $<span class="number">0x2</span>,%eax</span><br><span class="line">   <span class="number">0x000000000040102c</span> &lt;+<span class="number">32</span>&gt;:jne    <span class="number">0x401035</span> &lt;phase_4+<span class="number">41</span>&gt;</span><br><span class="line">   <span class="number">0x000000000040102e</span> &lt;+<span class="number">34</span>&gt;:cmpl   $<span class="number">0xe</span>,<span class="number">0x8</span>(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401033</span> &lt;+<span class="number">39</span>&gt;:jbe    <span class="number">0x40103a</span> &lt;phase_4+<span class="number">46</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401035</span> &lt;+<span class="number">41</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x000000000040103a</span> &lt;+<span class="number">46</span>&gt;:mov    $<span class="number">0xe</span>,%edx</span><br><span class="line">   <span class="number">0x000000000040103f</span> &lt;+<span class="number">51</span>&gt;:mov    $<span class="number">0x0</span>,%esi</span><br><span class="line">   <span class="number">0x0000000000401044</span> &lt;+<span class="number">56</span>&gt;:mov    <span class="number">0x8</span>(%rsp),%edi</span><br><span class="line">   <span class="number">0x0000000000401048</span> &lt;+<span class="number">60</span>&gt;:callq  <span class="number">0x400fce</span> &lt;func4&gt;</span><br><span class="line">   <span class="number">0x000000000040104d</span> &lt;+<span class="number">65</span>&gt;:test   %eax,%eax</span><br><span class="line">   <span class="number">0x000000000040104f</span> &lt;+<span class="number">67</span>&gt;:jne    <span class="number">0x401058</span> &lt;phase_4+<span class="number">76</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401051</span> &lt;+<span class="number">69</span>&gt;:cmpl   $<span class="number">0x0</span>,<span class="number">0xc</span>(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401056</span> &lt;+<span class="number">74</span>&gt;:je     <span class="number">0x40105d</span> &lt;phase_4+<span class="number">81</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401058</span> &lt;+<span class="number">76</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x000000000040105d</span> &lt;+<span class="number">81</span>&gt;:add    $<span class="number">0x18</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000401061</span> &lt;+<span class="number">85</span>&gt;:retq</span><br></pre></td></tr></table></figure><p>注意到<code>jne    0x401058 &lt;phase_4+76&gt;</code>,发现这个函数jump到了自己,应该是个递归函数<br><code>disas func4</code><br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas func4</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function func4:</span><br><span class="line">   <span class="number">0x0000000000400fce</span> &lt;+<span class="number">0</span>&gt;:sub    $<span class="number">0x8</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000400fd2</span> &lt;+<span class="number">4</span>&gt;:mov    %edx,%eax</span><br><span class="line">   <span class="number">0x0000000000400fd4</span> &lt;+<span class="number">6</span>&gt;:sub    %esi,%eax</span><br><span class="line">   <span class="number">0x0000000000400fd6</span> &lt;+<span class="number">8</span>&gt;:mov    %eax,%ecx</span><br><span class="line">   <span class="number">0x0000000000400fd8</span> &lt;+<span class="number">10</span>&gt;:shr    $<span class="number">0x1f</span>,%ecx</span><br><span class="line">   <span class="number">0x0000000000400fdb</span> &lt;+<span class="number">13</span>&gt;:add    %ecx,%eax</span><br><span class="line">   <span class="number">0x0000000000400fdd</span> &lt;+<span class="number">15</span>&gt;:sar    %eax</span><br><span class="line">   <span class="number">0x0000000000400fdf</span> &lt;+<span class="number">17</span>&gt;:lea    (%rax,%rsi,<span class="number">1</span>),%ecx</span><br><span class="line">   <span class="number">0x0000000000400fe2</span> &lt;+<span class="number">20</span>&gt;:cmp    %edi,%ecx</span><br><span class="line">   <span class="number">0x0000000000400fe4</span> &lt;+<span class="number">22</span>&gt;:jle    <span class="number">0x400ff2</span> &lt;func4+<span class="number">36</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400fe6</span> &lt;+<span class="number">24</span>&gt;:lea    <span class="number">-0x1</span>(%rcx),%edx</span><br><span class="line">   <span class="number">0x0000000000400fe9</span> &lt;+<span class="number">27</span>&gt;:callq  <span class="number">0x400fce</span> &lt;func4&gt;</span><br><span class="line">   <span class="number">0x0000000000400fee</span> &lt;+<span class="number">32</span>&gt;:add    %eax,%eax</span><br><span class="line">   <span class="number">0x0000000000400ff0</span> &lt;+<span class="number">34</span>&gt;:jmp    <span class="number">0x401007</span> &lt;func4+<span class="number">57</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400ff2</span> &lt;+<span class="number">36</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000400ff7</span> &lt;+<span class="number">41</span>&gt;:cmp    %edi,%ecx</span><br><span class="line">   <span class="number">0x0000000000400ff9</span> &lt;+<span class="number">43</span>&gt;:jge    <span class="number">0x401007</span> &lt;func4+<span class="number">57</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000400ffb</span> &lt;+<span class="number">45</span>&gt;:lea    <span class="number">0x1</span>(%rcx),%esi</span><br><span class="line">   <span class="number">0x0000000000400ffe</span> &lt;+<span class="number">48</span>&gt;:callq  <span class="number">0x400fce</span> &lt;func4&gt;</span><br><span class="line">   <span class="number">0x0000000000401003</span> &lt;+<span class="number">53</span>&gt;:lea    <span class="number">0x1</span>(%rax,%rax,<span class="number">1</span>),%eax</span><br><span class="line">   <span class="number">0x0000000000401007</span> &lt;+<span class="number">57</span>&gt;:add    $<span class="number">0x8</span>,%rsp</span><br><span class="line">   <span class="number">0x000000000040100b</span> &lt;+<span class="number">61</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func4</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="keyword">int</span> c)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> result;</span><br><span class="line">    result = c;</span><br><span class="line">    result = result - b;</span><br><span class="line">    <span class="keyword">int</span> tmp = result;</span><br><span class="line">    tmp = (<span class="keyword">unsigned</span>)tmp &gt;&gt; <span class="number">31</span>;</span><br><span class="line">    result = result + tmp;</span><br><span class="line">    result = result / <span class="number">2</span>;</span><br><span class="line">    tmp = result + b;</span><br><span class="line">    <span class="keyword">if</span>(tmp &gt; a)</span><br><span class="line">    &#123;</span><br><span class="line">        c = tmp - <span class="number">1</span>;</span><br><span class="line">        result = func4(a, b, c);</span><br><span class="line">        <span class="keyword">return</span> (<span class="number">2</span> * result);</span><br><span class="line">    &#125;</span><br><span class="line">    result = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span>(tmp &lt; a)</span><br><span class="line">    &#123;</span><br><span class="line">        b = tmp + <span class="number">1</span>;</span><br><span class="line">        result = func4(a, b, c);</span><br><span class="line">        <span class="keyword">return</span> (<span class="number">1</span> + <span class="number">2</span> * result);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>因此phase_4破译可能结果为：</p></blockquote><blockquote><p>0 0</p></blockquote><blockquote><p>1 0</p></blockquote><blockquote><p>3 0</p></blockquote><blockquote><p>7 0</p></blockquote><h2 id="phase-5"><a href="#phase-5" class="headerlink" title="phase_5"></a>phase_5</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas phase_5</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function phase_5:</span><br><span class="line">   <span class="number">0x0000000000401062</span> &lt;+<span class="number">0</span>&gt;:push   %rbx</span><br><span class="line">   <span class="number">0x0000000000401063</span> &lt;+<span class="number">1</span>&gt;:sub    $<span class="number">0x20</span>,%rsp</span><br><span class="line">   <span class="number">0x0000000000401067</span> &lt;+<span class="number">5</span>&gt;:mov    %rdi,%rbx   %rdi保存输入的字符串指针</span><br><span class="line">   <span class="number">0x000000000040106a</span> &lt;+<span class="number">8</span>&gt;:mov    %fs:<span class="number">0x28</span>,%rax</span><br><span class="line">   <span class="number">0x0000000000401073</span> &lt;+<span class="number">17</span>&gt;:mov    %rax,<span class="number">0x18</span>(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401078</span> &lt;+<span class="number">22</span>&gt;:xor    %eax,%eax</span><br><span class="line">   <span class="number">0x000000000040107a</span> &lt;+<span class="number">24</span>&gt;:callq  <span class="number">0x40131b</span> &lt;string_length&gt;   计算输入字符串长度</span><br><span class="line">   <span class="number">0x000000000040107f</span> &lt;+<span class="number">29</span>&gt;:cmp    $<span class="number">0x6</span>,%eax   判断输入字符串长度是否等于<span class="number">6</span></span><br><span class="line">   <span class="number">0x0000000000401082</span> &lt;+<span class="number">32</span>&gt;:je     <span class="number">0x4010d2</span> &lt;phase_5+<span class="number">112</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401084</span> &lt;+<span class="number">34</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000401089</span> &lt;+<span class="number">39</span>&gt;:jmp    <span class="number">0x4010d2</span> &lt;phase_5+<span class="number">112</span>&gt;</span><br><span class="line">   <span class="number">0x000000000040108b</span> &lt;+<span class="number">41</span>&gt;:movzbl (%rbx,%rax,<span class="number">1</span>),%ecx  复制输入字符串的第%rax个字符到%ecx中</span><br><span class="line">   <span class="number">0x000000000040108f</span> &lt;+<span class="number">45</span>&gt;:mov    %cl,(%rsp)</span><br><span class="line">   <span class="number">0x0000000000401092</span> &lt;+<span class="number">48</span>&gt;:mov    (%rsp),%rdx</span><br><span class="line">   <span class="number">0x0000000000401096</span> &lt;+<span class="number">52</span>&gt;:<span class="keyword">and</span>    $<span class="number">0xf</span>,%edx</span><br><span class="line">   <span class="number">0x0000000000401099</span> &lt;+<span class="number">55</span>&gt;:movzbl <span class="number">0x4024b0</span>(%rdx),%edx</span><br><span class="line">   <span class="number">0x00000000004010a0</span> &lt;+<span class="number">62</span>&gt;:mov    %dl,<span class="number">0x10</span>(%rsp,%rax,<span class="number">1</span>)</span><br><span class="line">   <span class="number">0x00000000004010a4</span> &lt;+<span class="number">66</span>&gt;:add    $<span class="number">0x1</span>,%rax  偏移量+<span class="number">1</span></span><br><span class="line">   <span class="number">0x00000000004010a8</span> &lt;+<span class="number">70</span>&gt;:cmp    $<span class="number">0x6</span>,%rax  判断%rax是否等于<span class="number">6</span>,不等于<span class="number">6</span>继续循环</span><br><span class="line">   <span class="number">0x00000000004010ac</span> &lt;+<span class="number">74</span>&gt;:jne    <span class="number">0x40108b</span> &lt;phase_5+<span class="number">41</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004010ae</span> &lt;+<span class="number">76</span>&gt;:movb   $<span class="number">0x0</span>,<span class="number">0x16</span>(%rsp)</span><br><span class="line">   <span class="number">0x00000000004010b3</span> &lt;+<span class="number">81</span>&gt;:mov    $<span class="number">0x40245e</span>,%esi</span><br><span class="line">   <span class="number">0x00000000004010b8</span> &lt;+<span class="number">86</span>&gt;:lea    <span class="number">0x10</span>(%rsp),%rdi</span><br><span class="line">   <span class="number">0x00000000004010bd</span> &lt;+<span class="number">91</span>&gt;:callq  <span class="number">0x401338</span> &lt;strings_not_equal&gt;     判断%esi和%rdi指向的字符串是否相等</span><br><span class="line">   <span class="number">0x00000000004010c2</span> &lt;+<span class="number">96</span>&gt;:test   %eax,%eax</span><br><span class="line">   <span class="number">0x00000000004010c4</span> &lt;+<span class="number">98</span>&gt;:je     <span class="number">0x4010d9</span> &lt;phase_5+<span class="number">119</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004010c6</span> &lt;+<span class="number">100</span>&gt;:callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x00000000004010cb</span> &lt;+<span class="number">105</span>&gt;:nopl   <span class="number">0x0</span>(%rax,%rax,<span class="number">1</span>)</span><br><span class="line">   <span class="number">0x00000000004010d0</span> &lt;+<span class="number">110</span>&gt;:jmp    <span class="number">0x4010d9</span> &lt;phase_5+<span class="number">119</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004010d2</span> &lt;+<span class="number">112</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x00000000004010d7</span> &lt;+<span class="number">117</span>&gt;:jmp    <span class="number">0x40108b</span> &lt;phase_5+<span class="number">41</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004010d9</span> &lt;+<span class="number">119</span>&gt;:mov    <span class="number">0x18</span>(%rsp),%rax</span><br><span class="line">   <span class="number">0x00000000004010de</span> &lt;+<span class="number">124</span>&gt;:xor    %fs:<span class="number">0x28</span>,%rax</span><br><span class="line">   <span class="number">0x00000000004010e7</span> &lt;+<span class="number">133</span>&gt;:je     <span class="number">0x4010ee</span> &lt;phase_5+<span class="number">140</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004010e9</span> &lt;+<span class="number">135</span>&gt;:callq  <span class="number">0x400b30</span> &lt;__stack_chk_fail@plt&gt;</span><br><span class="line">   <span class="number">0x00000000004010ee</span> &lt;+<span class="number">140</span>&gt;:add    $<span class="number">0x20</span>,%rsp</span><br><span class="line">   <span class="number">0x00000000004010f2</span> &lt;+<span class="number">144</span>&gt;:pop    %rbx</span><br><span class="line">   <span class="number">0x00000000004010f3</span> &lt;+<span class="number">145</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas string_length</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function string_length:</span><br><span class="line">   <span class="number">0x000000000040131b</span> &lt;+<span class="number">0</span>&gt;:cmpb   $<span class="number">0x0</span>,(%rdi)</span><br><span class="line">   <span class="number">0x000000000040131e</span> &lt;+<span class="number">3</span>&gt;:je     <span class="number">0x401332</span> &lt;string_length+<span class="number">23</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401320</span> &lt;+<span class="number">5</span>&gt;:mov    %rdi,%rdx</span><br><span class="line">   <span class="number">0x0000000000401323</span> &lt;+<span class="number">8</span>&gt;:add    $<span class="number">0x1</span>,%rdx</span><br><span class="line">   <span class="number">0x0000000000401327</span> &lt;+<span class="number">12</span>&gt;:mov    %edx,%eax</span><br><span class="line">   <span class="number">0x0000000000401329</span> &lt;+<span class="number">14</span>&gt;:sub    %edi,%eax</span><br><span class="line">   <span class="number">0x000000000040132b</span> &lt;+<span class="number">16</span>&gt;:cmpb   $<span class="number">0x0</span>,(%rdx)</span><br><span class="line">   <span class="number">0x000000000040132e</span> &lt;+<span class="number">19</span>&gt;:jne    <span class="number">0x401323</span> &lt;string_length+<span class="number">8</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401330</span> &lt;+<span class="number">21</span>&gt;:repz retq## secret_phase</span><br><span class="line">   <span class="number">0x0000000000401332</span> &lt;+<span class="number">23</span>&gt;:mov    $<span class="number">0x0</span>,%eax</span><br><span class="line">   <span class="number">0x0000000000401337</span> &lt;+<span class="number">28</span>&gt;:retq   </span><br><span class="line">End of assembler dump.</span><br><span class="line">(gdb)</span><br></pre></td></tr></table></figure><p>这个可以说是phase_1的升版本了,注意到<code>movzbl (%rbx,%rax,1),%ecx  复制输入字符串的第%rax个字符到%ecx中</code>每次取该字符串的一个字符,然后比对,然后+1,并且由开始的代码可知.字符串是6字符<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(gdb) x/s 0x4024b0</span><br><span class="line">0x4024b0 &lt;array.3449&gt;:&quot;maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?&quot;</span><br><span class="line">(gdb) x/s 0x40245e</span><br><span class="line">0x40245e:&quot;flyers&quot;</span><br></pre></td></tr></table></figure></p><h2 id="phase-6"><a href="#phase-6" class="headerlink" title="phase_6"></a>phase_6</h2><blockquote><p>第6个好难啊 QAQ</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line">(gdb) disas phase_6</span><br><span class="line">Dump of assembler code <span class="keyword">for</span> function phase_6:</span><br><span class="line">   <span class="number">0x00000000004010f4</span> &lt;+<span class="number">0</span>&gt;: push   %r14                                将被调用者保存寄存器压入栈</span><br><span class="line">   <span class="number">0x00000000004010f6</span> &lt;+<span class="number">2</span>&gt;: push   %r13</span><br><span class="line">   <span class="number">0x00000000004010f8</span> &lt;+<span class="number">4</span>&gt;: push   %r12</span><br><span class="line">   <span class="number">0x00000000004010fa</span> &lt;+<span class="number">6</span>&gt;: push   %rbp</span><br><span class="line">   <span class="number">0x00000000004010fb</span> &lt;+<span class="number">7</span>&gt;: push   %rbx                                %rsp = <span class="number">0x7fffffffe2c0</span></span><br><span class="line">   <span class="number">0x00000000004010fc</span> &lt;+<span class="number">8</span>&gt;: sub    $<span class="number">0x50</span>,%rsp                          分配栈空间 %rsp = <span class="number">0x7fffffffe270</span></span><br><span class="line">   <span class="number">0x0000000000401100</span> &lt;+<span class="number">12</span>&gt;:    mov    %rsp,%r13</span><br><span class="line"></span><br><span class="line">   <span class="number">0x0000000000401103</span> &lt;+<span class="number">15</span>&gt;:    mov    %rsp,%rsi</span><br><span class="line">   <span class="number">0x0000000000401106</span> &lt;+<span class="number">18</span>&gt;:    callq  <span class="number">0x40145c</span> &lt;read_six_numbers&gt;     读入<span class="number">6</span>个值,保存至从 %rsi 开始的地址</span><br><span class="line"></span><br><span class="line">   <span class="number">0x000000000040110b</span> &lt;+<span class="number">23</span>&gt;:    mov    %rsp,%r14</span><br><span class="line">   <span class="number">0x000000000040110e</span> &lt;+<span class="number">26</span>&gt;:    mov    $<span class="number">0x0</span>,%r12d                      %r12 置<span class="number">0</span>,并且%r13 %r14 %rbp 均和 %rsp 指向相同地址 <span class="number">0x7fffffffe270</span></span><br><span class="line"></span><br><span class="line">   <span class="number">0x0000000000401114</span> &lt;+<span class="number">32</span>&gt;:    mov    %r13,%rbp</span><br><span class="line">   <span class="number">0x0000000000401117</span> &lt;+<span class="number">35</span>&gt;:    mov    <span class="number">0x0</span>(%r13),%eax                  将第 %r13 指向的输入数复制到 %eax</span><br><span class="line">   <span class="number">0x000000000040111b</span> &lt;+<span class="number">39</span>&gt;:    sub    $<span class="number">0x1</span>,%eax                       将输入数减<span class="number">1</span></span><br><span class="line">   <span class="number">0x000000000040111e</span> &lt;+<span class="number">42</span>&gt;:    cmp    $<span class="number">0x5</span>,%eax                       判断输入数是否小于等于<span class="number">6</span>,因为上一步中减<span class="number">1</span>操作</span><br><span class="line">   <span class="number">0x0000000000401121</span> &lt;+<span class="number">45</span>&gt;:    jbe    <span class="number">0x401128</span> &lt;phase_6+<span class="number">52</span>&gt;           若大于<span class="number">6</span>,则调用 explode_bomb</span><br><span class="line">   <span class="number">0x0000000000401123</span> &lt;+<span class="number">47</span>&gt;:    callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">=========================================================================================================================================================</span><br><span class="line">   <span class="number">0x0000000000401128</span> &lt;+<span class="number">52</span>&gt;:    add    $<span class="number">0x1</span>,%r12d                      将 %r12 加<span class="number">1</span></span><br><span class="line">   <span class="number">0x000000000040112c</span> &lt;+<span class="number">56</span>&gt;:    cmp    $<span class="number">0x6</span>,%r12d                      判断 %r12 是否等于<span class="number">6</span></span><br><span class="line">   <span class="number">0x0000000000401130</span> &lt;+<span class="number">60</span>&gt;:    je     <span class="number">0x401153</span> &lt;phase_6+<span class="number">95</span>&gt;           若等于<span class="number">6</span>,跳转,否则继续执行</span><br><span class="line">   <span class="number">0x0000000000401132</span> &lt;+<span class="number">62</span>&gt;:    mov    %r12d,%ebx                      将 %r12 复制到 %ebx</span><br><span class="line"></span><br><span class="line">   <span class="number">0x0000000000401135</span> &lt;+<span class="number">65</span>&gt;:    movslq %ebx,%rax                       将 %ebx 符号位扩展复制到 %rax</span><br><span class="line">   <span class="number">0x0000000000401138</span> &lt;+<span class="number">68</span>&gt;:    mov    (%rsp,%rax,<span class="number">4</span>),%eax              将第 %ebx 输入数复制到 %eax</span><br><span class="line">   <span class="number">0x000000000040113b</span> &lt;+<span class="number">71</span>&gt;:    cmp    %eax,<span class="number">0x0</span>(%rbp)                  比较 %r13 指向的输入数和 第 %ebx 输入数 是否相等</span><br><span class="line">   <span class="number">0x000000000040113e</span> &lt;+<span class="number">74</span>&gt;:    jne    <span class="number">0x401145</span> &lt;phase_6+<span class="number">81</span>&gt;           如果相等,则调用 explode_bomb</span><br><span class="line">   <span class="number">0x0000000000401140</span> &lt;+<span class="number">76</span>&gt;:    callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x0000000000401145</span> &lt;+<span class="number">81</span>&gt;:    add    $<span class="number">0x1</span>,%ebx                       将 %ebx 加<span class="number">1</span></span><br><span class="line">   <span class="number">0x0000000000401148</span> &lt;+<span class="number">84</span>&gt;:    cmp    $<span class="number">0x5</span>,%ebx                       判断 %ebx 是否小于等于<span class="number">5</span></span><br><span class="line">   <span class="number">0x000000000040114b</span> &lt;+<span class="number">87</span>&gt;:    jle    <span class="number">0x401135</span> &lt;phase_6+<span class="number">65</span>&gt;           若小于等于,跳转,否则继续执行;该循环判断 %r13 指向的数据和其后输入数不相等</span><br><span class="line"></span><br><span class="line">   <span class="number">0x000000000040114d</span> &lt;+<span class="number">89</span>&gt;:    add    $<span class="number">0x4</span>,%r13                       将 %r13 指向下一个输入数,该循环判断所有的输入数全部不相等</span><br><span class="line">   <span class="number">0x0000000000401151</span> &lt;+<span class="number">93</span>&gt;:    jmp    <span class="number">0x401114</span> &lt;phase_6+<span class="number">32</span>&gt;</span><br><span class="line">=========================================================================================================================================================</span><br><span class="line">   <span class="number">0x0000000000401153</span> &lt;+<span class="number">95</span>&gt;:    lea    <span class="number">0x18</span>(%rsp),%rsi                 将 %rsi 指向栈中跳过读入数据位置作为结束标记,并且 %r14 仍和 %rsp 指向同一个位置</span><br><span class="line">   <span class="number">0x0000000000401158</span> &lt;+<span class="number">100</span>&gt;:   mov    %r14,%rax                       将 %r14 复制到 %rax</span><br><span class="line">   <span class="number">0x000000000040115b</span> &lt;+<span class="number">103</span>&gt;:   mov    $<span class="number">0x7</span>,%ecx</span><br><span class="line">   <span class="number">0x0000000000401160</span> &lt;+<span class="number">108</span>&gt;:   mov    %ecx,%edx                       将立即数<span class="number">0x7</span>复制到 %edx</span><br><span class="line">   <span class="number">0x0000000000401162</span> &lt;+<span class="number">110</span>&gt;:   sub    (%rax),%edx                     立即数<span class="number">7</span>减去 %r14 指向的数据</span><br><span class="line">   <span class="number">0x0000000000401164</span> &lt;+<span class="number">112</span>&gt;:   mov    %edx,(%rax)                     将<span class="number">7</span>减的结果存回 %r14 执行的内存单元</span><br><span class="line">   <span class="number">0x0000000000401166</span> &lt;+<span class="number">114</span>&gt;:   add    $<span class="number">0x4</span>,%rax                       %rax 指向下一个输入数</span><br><span class="line">   <span class="number">0x000000000040116a</span> &lt;+<span class="number">118</span>&gt;:   cmp    %rsi,%rax                       比较是否达到输入数组的末尾,</span><br><span class="line">   <span class="number">0x000000000040116d</span> &lt;+<span class="number">121</span>&gt;:   jne    <span class="number">0x401160</span> &lt;phase_6+<span class="number">108</span>&gt;          该循环使用立即数<span class="number">7</span>减去每个输入数据</span><br><span class="line">==========================================================================================================================================================</span><br><span class="line">   <span class="number">0x000000000040116f</span> &lt;+<span class="number">123</span>&gt;:   mov    $<span class="number">0x0</span>,%esi                       将 %rsi 置<span class="number">0</span></span><br><span class="line">   <span class="number">0x0000000000401174</span> &lt;+<span class="number">128</span>&gt;:   jmp    <span class="number">0x401197</span> &lt;phase_6+<span class="number">163</span>&gt;</span><br><span class="line"></span><br><span class="line">   <span class="number">0x0000000000401176</span> &lt;+<span class="number">130</span>&gt;:   mov    <span class="number">0x8</span>(%rdx),%rdx                  将 <span class="number">0x8</span>(%rdx) 指向内存单元的内容复制到 %rdx, 指向链表下一个元素</span><br><span class="line">   <span class="number">0x000000000040117a</span> &lt;+<span class="number">134</span>&gt;:   add    $<span class="number">0x1</span>,%eax                       将 %eax 加<span class="number">1</span></span><br><span class="line">   <span class="number">0x000000000040117d</span> &lt;+<span class="number">137</span>&gt;:   cmp    %ecx,%eax                       比较 %ecx 和 %eax 是否相等</span><br><span class="line">   <span class="number">0x000000000040117f</span> &lt;+<span class="number">139</span>&gt;:   jne    <span class="number">0x401176</span> &lt;phase_6+<span class="number">130</span>&gt;          不相等,继续遍历链表,最终 %rdx 指向链表的第 %ecx 个节点</span><br><span class="line">   <span class="number">0x0000000000401181</span> &lt;+<span class="number">141</span>&gt;:   jmp    <span class="number">0x401188</span> &lt;phase_6+<span class="number">148</span>&gt;</span><br><span class="line">   <span class="number">0x0000000000401183</span> &lt;+<span class="number">143</span>&gt;:   mov    $<span class="number">0x6032d0</span>,%edx                  重置链表首地址</span><br><span class="line">   <span class="number">0x0000000000401188</span> &lt;+<span class="number">148</span>&gt;:   mov    %rdx,<span class="number">0x20</span>(%rsp,%rsi,<span class="number">2</span>)</span><br><span class="line">   <span class="number">0x000000000040118d</span> &lt;+<span class="number">153</span>&gt;:   add    $<span class="number">0x4</span>,%rsi</span><br><span class="line">   <span class="number">0x0000000000401191</span> &lt;+<span class="number">157</span>&gt;:   cmp    $<span class="number">0x18</span>,%rsi</span><br><span class="line">   <span class="number">0x0000000000401195</span> &lt;+<span class="number">161</span>&gt;:   je     <span class="number">0x4011ab</span> &lt;phase_6+<span class="number">183</span>&gt;</span><br><span class="line"></span><br><span class="line">   <span class="number">0x0000000000401197</span> &lt;+<span class="number">163</span>&gt;:   mov    (%rsp,%rsi,<span class="number">1</span>),%ecx              将 (%rsp + %rsi) 指向的数据复制到 %ecx</span><br><span class="line">   <span class="number">0x000000000040119a</span> &lt;+<span class="number">166</span>&gt;:   cmp    $<span class="number">0x1</span>,%ecx                       比较 %ecx 是否小于等于<span class="number">1</span></span><br><span class="line">   <span class="number">0x000000000040119d</span> &lt;+<span class="number">169</span>&gt;:   jle    <span class="number">0x401183</span> &lt;phase_6+<span class="number">143</span>&gt;          若小于等于,跳转,否则继续执行, 等于<span class="number">1</span>, %edx 直接指向链表首地址</span><br><span class="line">   <span class="number">0x000000000040119f</span> &lt;+<span class="number">171</span>&gt;:   mov    $<span class="number">0x1</span>,%eax                       将 %eax 置<span class="number">1</span></span><br><span class="line">   <span class="number">0x00000000004011a4</span> &lt;+<span class="number">176</span>&gt;:   mov    $<span class="number">0x6032d0</span>,%edx                  将 %rdx 指向内存单元 <span class="number">0x6032d0</span></span><br><span class="line">   <span class="number">0x00000000004011a9</span> &lt;+<span class="number">181</span>&gt;:   jmp    <span class="number">0x401176</span> &lt;phase_6+<span class="number">130</span>&gt;          跳转; 该循环根据输入数将链表中对应的第输入数个节点的地址复制到 <span class="number">0x20</span>(%rsp) 开始的栈中</span><br><span class="line"> ==========================================================================================================================================================</span><br><span class="line">   <span class="number">0x00000000004011ab</span> &lt;+<span class="number">183</span>&gt;:   mov    <span class="number">0x20</span>(%rsp),%rbx                 将<span class="number">0x20</span>(%rsp)的链表节点地址复制到 %rbx</span><br><span class="line">   <span class="number">0x00000000004011b0</span> &lt;+<span class="number">188</span>&gt;:   lea    <span class="number">0x28</span>(%rsp),%rax                 将 %rax 指向栈中下一个链表节点的地址</span><br><span class="line">   <span class="number">0x00000000004011b5</span> &lt;+<span class="number">193</span>&gt;:   lea    <span class="number">0x50</span>(%rsp),%rsi                 将 %rsi 指向保存的链表节点地址的末尾</span><br><span class="line">   <span class="number">0x00000000004011ba</span> &lt;+<span class="number">198</span>&gt;:   mov    %rbx,%rcx</span><br><span class="line"></span><br><span class="line">   <span class="number">0x00000000004011bd</span> &lt;+<span class="number">201</span>&gt;:   mov    (%rax),%rdx</span><br><span class="line">   <span class="number">0x00000000004011c0</span> &lt;+<span class="number">204</span>&gt;:   mov    %rdx,<span class="number">0x8</span>(%rcx)                  将栈中指向的后一个节点的地址复制到前一个节点的地址位置</span><br><span class="line">   <span class="number">0x00000000004011c4</span> &lt;+<span class="number">208</span>&gt;:   add    $<span class="number">0x8</span>,%rax                       移动到下一个节点</span><br><span class="line">   <span class="number">0x00000000004011c8</span> &lt;+<span class="number">212</span>&gt;:   cmp    %rsi,%rax                       判断<span class="number">6</span>个节点是否遍历完毕</span><br><span class="line">   <span class="number">0x00000000004011cb</span> &lt;+<span class="number">215</span>&gt;:   je     <span class="number">0x4011d2</span> &lt;phase_6+<span class="number">222</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004011cd</span> &lt;+<span class="number">217</span>&gt;:   mov    %rdx,%rcx</span><br><span class="line">   <span class="number">0x00000000004011d0</span> &lt;+<span class="number">220</span>&gt;:   jmp    <span class="number">0x4011bd</span> &lt;phase_6+<span class="number">201</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004011d2</span> &lt;+<span class="number">222</span>&gt;:   movq   $<span class="number">0x0</span>,<span class="number">0x8</span>(%rdx)                  该循环按照<span class="number">7</span>减去输入数据的索引重新调整链表</span><br><span class="line">==========================================================================================================================================================</span><br><span class="line">   <span class="number">0x00000000004011da</span> &lt;+<span class="number">230</span>&gt;:   mov    $<span class="number">0x5</span>,%ebp</span><br><span class="line">   <span class="number">0x00000000004011df</span> &lt;+<span class="number">235</span>&gt;:   mov    <span class="number">0x8</span>(%rbx),%rax                  将 %rax 指向 %rbx 下一个链表节点</span><br><span class="line">   <span class="number">0x00000000004011e3</span> &lt;+<span class="number">239</span>&gt;:   mov    (%rax),%eax</span><br><span class="line">   <span class="number">0x00000000004011e5</span> &lt;+<span class="number">241</span>&gt;:   cmp    %eax,(%rbx)                     比较链表节点中第一个字段值的大小,如果前一个节点值大于后一个节点值,跳转</span><br><span class="line">   <span class="number">0x00000000004011e7</span> &lt;+<span class="number">243</span>&gt;:   jge    <span class="number">0x4011ee</span> &lt;phase_6+<span class="number">250</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004011e9</span> &lt;+<span class="number">245</span>&gt;:   callq  <span class="number">0x40143a</span> &lt;explode_bomb&gt;</span><br><span class="line">   <span class="number">0x00000000004011ee</span> &lt;+<span class="number">250</span>&gt;:   mov    <span class="number">0x8</span>(%rbx),%rbx                  将 %rbx 向后移动,指向栈中下一个链表节点的地址</span><br><span class="line">   <span class="number">0x00000000004011f2</span> &lt;+<span class="number">254</span>&gt;:   sub    $<span class="number">0x1</span>,%ebp                       判断循环是否结束,该循环判断栈中重新调整后的链表节点是否按照降序排列</span><br><span class="line">   <span class="number">0x00000000004011f5</span> &lt;+<span class="number">257</span>&gt;:   jne    <span class="number">0x4011df</span> &lt;phase_6+<span class="number">235</span>&gt;</span><br><span class="line">   <span class="number">0x00000000004011f7</span> &lt;+<span class="number">259</span>&gt;:   add    $<span class="number">0x50</span>,%rsp</span><br><span class="line">   <span class="number">0x00000000004011fb</span> &lt;+<span class="number">263</span>&gt;:   pop    %rbx</span><br><span class="line">   <span class="number">0x00000000004011fc</span> &lt;+<span class="number">264</span>&gt;:   pop    %rbp</span><br><span class="line">   <span class="number">0x00000000004011fd</span> &lt;+<span class="number">265</span>&gt;:   pop    %r12</span><br><span class="line">   <span class="number">0x00000000004011ff</span> &lt;+<span class="number">267</span>&gt;:   pop    %r13</span><br><span class="line">   <span class="number">0x0000000000401201</span> &lt;+<span class="number">269</span>&gt;:   pop    %r14</span><br><span class="line">   <span class="number">0x0000000000401203</span> &lt;+<span class="number">271</span>&gt;:   retq</span><br><span class="line">End of assembler dump.</span><br></pre></td></tr></table></figure><h2 id="secret-phase"><a href="#secret-phase" class="headerlink" title="secret_phase"></a>secret_phase</h2>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;上个月就开始搞CSAPP了,之前书没看好,LAB做起来也磕磕绊绊.把书的第三章重新看了遍后,再来做.&lt;/p&gt;
&lt;p&gt;另外,大概也要定个计划把汇编学了&lt;/p&gt;
&lt;p&gt;之前GDB一直不太会用,通过这个机会也是学习了下,后面希望提升自己的学习力,什么不会遇上了能快速的学习.&lt;/p
      
    
    </summary>
    
    
      <category term="CSAPP" scheme="https://jackwener.github.io/tags/CSAPP/"/>
    
  </entry>
  
  <entry>
    <title>though1</title>
    <link href="https://jackwener.github.io/2018/05/10/though1/"/>
    <id>https://jackwener.github.io/2018/05/10/though1/</id>
    <published>2018-05-10T12:20:07.000Z</published>
    <updated>2018-05-12T12:05:15.728Z</updated>
    
    <content type="html"><![CDATA[<h3 id="一日随想-老子TMD要肝爆"><a href="#一日随想-老子TMD要肝爆" class="headerlink" title="一日随想 老子TMD要肝爆"></a>一日随想 老子TMD要肝爆</h3><p><strong>今天和伍juju聊了一些,有了很多感想,和他聊天的过程中一不小心聊到了他的作息,他说他日常睡4.5-5.5个小时,养生睡6-7个小时,虽然之前就知道他睡的很短,但还是<br>被这个情况震惊到了.</strong></p><p><strong>我想了很多,其实我很多时候只是不愿意下功夫,走些歪路,想什么所谓的高效,其实都是狗屁,TMD本身就是干能解决的事情想那么多?大家都是水平差不多的,还真能效率高很多很多?今天又继续开始看第二次CSAPP,发现第一次看的都是什么鬼,漏了多少东西?多少东西没懂?你再高效能抵得过认认真真一点一点的刷,看2遍认真思考吗?我发现我就是自己过得太安逸了,遇到困难抱怨,害怕而不去解决,没那种 TMD就是干 的精神.</strong></p><p><strong>很多事情确实需要效率,但是!!!很多事情也需要肝,我希望自己成为一个能忍受肝的人,愿意肝的人,愿意主动解决问题的人,学计算机知识让我确实收获了非常非常多,不仅仅是知识上的,让我看到了自己很多的缺陷,加油!伍大佬说的也很多,很多事情越早做越有价值,越能拿到更多资源,可以滚雪球,这是自己凭肝 肝出来的,现在肝的多,后面过得好,就和高考一个样,高中努力,上好大学,资源多,后面容易发展.晚肝不如早肝,另外为自己喜欢的东西肝,我觉得也是一个很开心的事,肝!!!!</strong></p><p>后面写博客记录肝的过程!!!加油!!!</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h3 id=&quot;一日随想-老子TMD要肝爆&quot;&gt;&lt;a href=&quot;#一日随想-老子TMD要肝爆&quot; class=&quot;headerlink&quot; title=&quot;一日随想 老子TMD要肝爆&quot;&gt;&lt;/a&gt;一日随想 老子TMD要肝爆&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;今天和伍juju聊了一些,有了很多感
      
    
    </summary>
    
    
      <category term="随想" scheme="https://jackwener.github.io/tags/%E9%9A%8F%E6%83%B3/"/>
    
  </entry>
  
  <entry>
    <title>linux/unix系统编程手册 8章习题</title>
    <link href="https://jackwener.github.io/2018/05/09/tlpi8%E7%AB%A0%E4%B9%A0%E9%A2%98/"/>
    <id>https://jackwener.github.io/2018/05/09/tlpi8章习题/</id>
    <published>2018-05-09T12:03:03.000Z</published>
    <updated>2018-05-11T04:35:32.911Z</updated>
    
    <content type="html"><![CDATA[<h2 id="第8章"><a href="#第8章" class="headerlink" title="第8章"></a>第8章</h2><h3 id="笔记"><a href="#笔记" class="headerlink" title="笔记"></a>笔记</h3><blockquote><p>肠胃病每周大概都有那么几次,今天又犯了,整个人身体都不太好,没啥精神,写点总结文字,当做看后复习.</p></blockquote><p><strong>后面tlpi这本书就不会继续更了,把它当成一本工具书,用的时候翻阅.</strong></p><p>第8章主要是介绍了用户和组的一些基本知识,为后面更深入的知识做了铺垫,介绍了讲了用户和组，还有记录用户的密码文件/etc/passwd，shadow密码文件/etc/shadow还有组文件/etc/group。</p><p>每个用户都有唯一的用户名和相关的用户标识符（UID）。用户可以属于一个或多个组，每个组都有唯一的组名和相关的组标识符（GID）。</p><p>用户和组的用途为：1、可以确定各种系统资源的所有权；2、对赋予进程访问上述资源的权限加以控制。</p><p>密码文件/etc/passwd<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">jakevin@jakevin-PC:~$ cat /etc/passwd</span><br><span class="line">root:x:0:0:root:/root:/bin/bash</span><br><span class="line">daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin</span><br><span class="line">bin:x:2:2:bin:/bin:/usr/sbin/nologin</span><br><span class="line">sys:x:3:3:sys:/dev:/usr/sbin/nologin</span><br><span class="line">sync:x:4:65534:sync:/bin:/bin/sync</span><br><span class="line">games:x:5:60:games:/usr/games:/usr/sbin/nologin</span><br><span class="line">man:x:6:12:man:/var/cache/man:/usr/sbin/nologin</span><br><span class="line">lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin</span><br><span class="line">mail:x:8:8:mail:/var/mail:/usr/sbin/nologin</span><br><span class="line">news:x:9:9:news:/var/spool/news:/usr/sbin/nologin</span><br><span class="line">uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin</span><br><span class="line">proxy:x:13:13:proxy:/bin:/usr/sbin/nologin</span><br><span class="line">www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin</span><br><span class="line">backup:x:34:34:backup:/var/backups:/usr/sbin/nologin</span><br><span class="line">list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin</span><br><span class="line">irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin</span><br><span class="line">gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin</span><br><span class="line">nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin</span><br><span class="line">systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false</span><br><span class="line">systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false</span><br><span class="line">systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false</span><br><span class="line">systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false</span><br><span class="line">_apt:x:104:65534::/nonexistent:/bin/false</span><br><span class="line">messagebus:x:105:108::/var/run/dbus:/bin/false</span><br><span class="line">strongswan:x:106:65534::/var/lib/strongswan:/usr/sbin/nologin</span><br><span class="line">dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/bin/false</span><br><span class="line">usbmux:x:108:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false</span><br><span class="line">geoclue:x:109:114::/var/lib/geoclue:/bin/false</span><br><span class="line">nm-openconnect:x:110:115:NetworkManager OpenConnect plugin,,,:/var/lib/NetworkManager:/bin/false</span><br><span class="line">nm-openvpn:x:111:116:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/bin/false</span><br><span class="line">lightdm:x:112:118:Light Display Manager:/var/lib/lightdm:/bin/false</span><br><span class="line">pulse:x:113:119:PulseAudio daemon,,,:/var/run/pulse:/bin/false</span><br><span class="line">hplip:x:114:7:HPLIP system user,,,:/var/run/hplip:/bin/false</span><br><span class="line">avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false</span><br><span class="line">gluster:x:116:123::/var/lib/glusterd:/bin/false</span><br><span class="line">jakevin:x:1000:1000::/home/jakevin:/bin/bash</span><br><span class="line">miredo:x:117:65534::/var/run/miredo:/bin/false</span><br><span class="line">sshd:x:118:65534::/run/sshd:/usr/sbin/nologin</span><br><span class="line">mysql:x:119:125:MySQL Server,,,:/nonexistent:/bin/false</span><br></pre></td></tr></table></figure></p><p>第一个字段是登录名；第二个字段是经过加密后的密码（x），实际上经过加密后的密码是存放在shadow密码文件；</p><p>第三个字段是用户的ID（UID）；第四个字段是组ID（GID）；第五个字段是注释；</p><p>第六个字段是主目录，是用户登录后的初始路径；第七个字段是登录shell。</p><p>实际存放密码的shadow 密码文件/etc/shadow<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">jakevin:$6$tnTgvJYU$OhoUNZNIeNU7rlZf/f14oD2g.Uz8SbrnWeZbR4yL4XXRvzbCeijsAZE7Y9HlzU4thKVBVcqucwntJBi/4BoY60:15880:0:99999:7:::</span><br><span class="line">mysql:!:15905:0:99999:7:::</span><br><span class="line">ftp:*:16039:0:99999:7:::</span><br><span class="line">telnetd:*:16180:0:99999:7:::</span><br></pre></td></tr></table></figure></p><p>第一个字段为用户登录名，第二个字段为见过加密后的密码，后面的字段为与安全性相关的字段。</p><p>看组文件/etc/group</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line">jakevin@jakevin-PC:~$ cat /etc/group</span><br><span class="line">root:x:0:</span><br><span class="line">daemon:x:1:</span><br><span class="line">bin:x:2:</span><br><span class="line">sys:x:3:</span><br><span class="line">adm:x:4:</span><br><span class="line">tty:x:5:</span><br><span class="line">disk:x:6:</span><br><span class="line">lp:x:7:jakevin</span><br><span class="line">mail:x:8:</span><br><span class="line">news:x:9:</span><br><span class="line">uucp:x:10:</span><br><span class="line">man:x:12:</span><br><span class="line">proxy:x:13:</span><br><span class="line">kmem:x:15:</span><br><span class="line">dialout:x:20:</span><br><span class="line">fax:x:21:</span><br><span class="line">voice:x:22:</span><br><span class="line">cdrom:x:24:</span><br><span class="line">floppy:x:25:</span><br><span class="line">tape:x:26:</span><br><span class="line">sudo:x:27:jakevin</span><br><span class="line">audio:x:29:pulse</span><br><span class="line">dip:x:30:</span><br><span class="line">www-data:x:33:</span><br><span class="line">backup:x:34:</span><br><span class="line">operator:x:37:</span><br><span class="line">list:x:38:</span><br><span class="line">irc:x:39:</span><br><span class="line">src:x:40:</span><br><span class="line">gnats:x:41:</span><br><span class="line">shadow:x:42:</span><br><span class="line">utmp:x:43:</span><br><span class="line">video:x:44:</span><br><span class="line">sasl:x:45:</span><br><span class="line">plugdev:x:46:</span><br><span class="line">staff:x:50:</span><br><span class="line">games:x:60:</span><br><span class="line">users:x:100:jakevin</span><br><span class="line">nogroup:x:65534:</span><br><span class="line">systemd-journal:x:101:</span><br><span class="line">systemd-timesync:x:102:</span><br><span class="line">systemd-network:x:103:</span><br><span class="line">systemd-resolve:x:104:</span><br><span class="line">systemd-bus-proxy:x:105:</span><br><span class="line">input:x:106:</span><br><span class="line">crontab:x:107:</span><br><span class="line">messagebus:x:108:</span><br><span class="line">netdev:x:109:jakevin</span><br><span class="line">bluetooth:x:110:</span><br><span class="line">ssl-cert:x:111:</span><br><span class="line">ssh:x:112:</span><br><span class="line">lpadmin:x:113:jakevin</span><br><span class="line">geoclue:x:114:</span><br><span class="line">nm-openconnect:x:115:</span><br><span class="line">nm-openvpn:x:116:</span><br><span class="line">scanner:x:117:jakevin</span><br><span class="line">lightdm:x:118:</span><br><span class="line">pulse:x:119:</span><br><span class="line">pulse-access:x:120:</span><br><span class="line">avahi:x:121:</span><br><span class="line">rdma:x:122:</span><br><span class="line">gluster:x:123:</span><br><span class="line">sambashare:x:124:jakevin</span><br><span class="line">jakevin:x:1000:</span><br><span class="line">bumblebee:x:999:jakevin</span><br><span class="line">autologin:x:998:jakevin</span><br><span class="line">wireshark:x:1001:jakevin</span><br><span class="line">mysql:x:125:</span><br><span class="line">docker:x:997:jakevin</span><br><span class="line">kvm:x:126:</span><br></pre></td></tr></table></figure><p>第一个字段是组的名称，第二个字段是经过加密的密码，第三个字段是组ID（GID），第四个字段是用户列表。</p><p>对于加密后的密码存放在类似/etc/shadow的文件（/etc/gshadow），格式如下：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">jakevin@jakevin-PC:~$ sudo cat /etc/gshadow</span><br><span class="line">[sudo] jakevin 的密码：</span><br><span class="line">root:*::</span><br><span class="line">daemon:*::</span><br><span class="line">bin:*::</span><br><span class="line">sys:*::</span><br><span class="line">adm:*::</span><br><span class="line">tty:*::</span><br><span class="line">disk:*::</span><br><span class="line">lp:*::jakevin</span><br><span class="line">mail:*::</span><br><span class="line">news:*::</span><br><span class="line">uucp:*::</span><br><span class="line">man:*::</span><br><span class="line">proxy:*::</span><br><span class="line">kmem:*::</span><br><span class="line">dialout:*::</span><br><span class="line">fax:*::</span><br><span class="line">voice:*::</span><br><span class="line">cdrom:*::</span><br><span class="line">floppy:*::</span><br></pre></td></tr></table></figure><h3 id="习题8-1"><a href="#习题8-1" class="headerlink" title="习题8.1"></a>习题8.1</h3><p>书上的习题应该是错的,也就是注释部分,结果是1000 ,0和题目描述不符</p><p><del>~搜了下,改成下面的就是一样的了,说是因为,指针指向的地址一样,但自己没想明白,先搁着吧….</del>~</p><p>更:<br>问题就出在这个存储用户信息的结构体上面，它是由getpw函数在程序中自定义的一块静态存储区，而且每调用一次getpw函数，这个静态存储区就会被重写一次</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pwd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span>&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">passwd</span> *<span class="title">p1</span>, *<span class="title">p2</span>;</span></span><br><span class="line">    p1 = getpwnam(<span class="string">"jakevin"</span>);</span><br><span class="line">    p2 = getpwnam(<span class="string">"root"</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%ld %ld\n"</span>,(<span class="keyword">long</span>)p1-&gt;pw_uid,(<span class="keyword">long</span>)p2-&gt;pw_uid);</span><br><span class="line">    <span class="comment">/* printf("%ld %ld\n", (long)(getpwnam("jakevin")-&gt;pw_uid), (long)(getpwnam("root")-&gt;pw_uid));</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>—–身体不好,感觉此章没看好,待更—–</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;第8章&quot;&gt;&lt;a href=&quot;#第8章&quot; class=&quot;headerlink&quot; title=&quot;第8章&quot;&gt;&lt;/a&gt;第8章&lt;/h2&gt;&lt;h3 id=&quot;笔记&quot;&gt;&lt;a href=&quot;#笔记&quot; class=&quot;headerlink&quot; title=&quot;笔记&quot;&gt;&lt;/a&gt;笔记&lt;/h3&gt;&lt;b
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
      <category term="unix系统编程手册" scheme="https://jackwener.github.io/tags/unix%E7%B3%BB%E7%BB%9F%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C/"/>
    
  </entry>
  
  <entry>
    <title>linux/unix系统编程手册 7章习题</title>
    <link href="https://jackwener.github.io/2018/05/08/tlpi7%E7%AB%A0%E4%B9%A0%E9%A2%98/"/>
    <id>https://jackwener.github.io/2018/05/08/tlpi7章习题/</id>
    <published>2018-05-08T05:48:49.000Z</published>
    <updated>2018-05-08T08:03:23.511Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>看的过程中发现自己C学的很不好啊 ……</p><p>之前CSAPP没坚持下来,后面把CSAPP搞定吧…</p><p>太菜了╮(╯▽╰)╭</p></blockquote><h3 id="7-1"><a href="#7-1" class="headerlink" title="7-1"></a>7-1</h3><p> 修改程序清单7-1中的程序，在每次malloc后打印program break 的值。指定一个较小的内存分配尺寸，观察现象，证明的每次malloc后program break分配了超过所需的内存区域。</p><p> 7-1 修改程序清单7-1中的程序，在每次malloc后打印program break 的值。指定一个较小的内存分配尺寸，观察现象，证明的每次malloc后program break分配了超过所需的内存区域。<br>我们可以通过一个更简单的程序来实现观察所需的功能。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;malloc.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"now : %10p\n"</span>, sbrk(<span class="number">0</span>));</span><br><span class="line">    <span class="keyword">char</span> * a;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i&lt;<span class="number">10</span>; i++)</span><br><span class="line">    &#123;   </span><br><span class="line">        a = <span class="built_in">malloc</span>(<span class="number">50000</span>);</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"%d : %10p\n"</span>,i, sbrk(<span class="number">0</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>运行程序输出如下：</p><blockquote><p>now : 0xaf060fc000</p></blockquote><blockquote><p>0 : 0xaf0611d000</p></blockquote><blockquote><p>1 : 0xaf0611d000</p></blockquote><blockquote><p>2 : 0xaf06141000</p></blockquote><blockquote><p>3 : 0xaf06141000</p></blockquote><blockquote><p>4 : 0xaf06141000</p></blockquote><blockquote><p>5 : 0xaf06166000</p></blockquote><blockquote><p>6 : 0xaf06166000</p></blockquote><blockquote><p>7 : 0xaf06166000</p></blockquote><blockquote><p>8 : 0xaf0618b000</p></blockquote><blockquote><p>9 : 0xaf0618b000</p></blockquote><p>我们可以看到每次实际上边界分配了空间大于我们所需的空间。</p><h3 id="7-2"><a href="#7-2" class="headerlink" title="7-2"></a>7-2</h3><p>实现malloc()和free()。<br>根据课本可以知道，malloc和free是对堆操作的包装，也就是brk函数的包装，在堆空间进行的数据结构的操作</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;看的过程中发现自己C学的很不好啊 ……&lt;/p&gt;
&lt;p&gt;之前CSAPP没坚持下来,后面把CSAPP搞定吧…&lt;/p&gt;
&lt;p&gt;太菜了╮(╯▽╰)╭&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;7-1&quot;&gt;&lt;a href=&quot;#7-1&quot; class=&quot;
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
      <category term="unix系统编程手册" scheme="https://jackwener.github.io/tags/unix%E7%B3%BB%E7%BB%9F%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C/"/>
    
  </entry>
  
  <entry>
    <title>linux/unix系统编程手册 6章习题</title>
    <link href="https://jackwener.github.io/2018/05/07/tlpi6%E7%AB%A0%E4%B9%A0%E9%A2%98/"/>
    <id>https://jackwener.github.io/2018/05/07/tlpi6章习题/</id>
    <published>2018-05-07T09:22:22.000Z</published>
    <updated>2018-05-08T08:03:35.114Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>定了个小计划,大概能2-3天看一章并做习题,这套书感觉也可能不会看完,实在太多了,看了1本之后估计后面当手册翻翻</p></blockquote><blockquote><p>这章环境那一些看的不太懂2333</p></blockquote><h3 id="6-1"><a href="#6-1" class="headerlink" title="6-1"></a>6-1</h3><blockquote><p>编译程序清单6-1中的程序，使用ls -l命令显示可执行文件的大小，解释为什么可执行文件的大小远小于10MB，但是程序中包含了一个10MB的数组？</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="keyword">char</span> globBuf[<span class="number">65536</span>];</span><br><span class="line"><span class="keyword">int</span> primes[] = &#123;<span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>&#125;;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">square</span><span class="params">(<span class="keyword">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> result;</span><br><span class="line">    result = x * x;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">doCalc</span><span class="params">(<span class="keyword">int</span> val)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"The square of %d is %d\n"</span>, val, square(val));</span><br><span class="line">    <span class="keyword">if</span> (val &lt; <span class="number">1000</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">int</span> t;</span><br><span class="line">        t = val * val * val;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"The cube of %d is %d\n"</span>, val, t);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> key = <span class="number">9973</span>;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">char</span> mbuf[<span class="number">10240000</span>];</span><br><span class="line">    <span class="keyword">char</span>* p;</span><br><span class="line">    p = <span class="built_in">malloc</span>(<span class="number">1024</span>);</span><br><span class="line">    doCalc(key);</span><br><span class="line">    <span class="built_in">exit</span>(EXIT_SUCCESS);</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>编译后占用体积的部分主要是</p><blockquote><p>char globBuf[65536];</p></blockquote><p>至于</p><blockquote><p>static int key = 9973;</p></blockquote><blockquote><p>static char mbuf[10240000];</p></blockquote><p>未初始化的部分不分配空间,后面等程序加载器分配</p><h3 id="6-2"><a href="#6-2" class="headerlink" title="6-2"></a>6-2</h3><p>编写程序，观察longjmp函数试图跳转到一个已经返回的函数中会出现什么。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;setjmp.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line">jmp_buf env;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">x</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (setjmp(env) == <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"1\n"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"2\n"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">y</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    longjmp(env, <span class="number">1</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"3\n"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    x();</span><br><span class="line">    y();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"4\n"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>出现</p><p>1</p><p>2</p><p>4</p><p>原因书上有解释,尝试返回一个释放了的栈帧.<br>这个题按着书上 滥用longjmp()部分写就可以了</p><h3 id="6-3"><a href="#6-3" class="headerlink" title="6-3"></a>6-3</h3><p>使用getenv()函数，putenv()函数来实现setenv()和unsetenv()函数。unsetenv函数需要将多个同名的环境变量都移除。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;定了个小计划,大概能2-3天看一章并做习题,这套书感觉也可能不会看完,实在太多了,看了1本之后估计后面当手册翻翻&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;这章环境那一些看的不太懂2333&lt;/p&gt;
&lt;/blockquote
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
      <category term="unix系统编程手册" scheme="https://jackwener.github.io/tags/unix%E7%B3%BB%E7%BB%9F%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C/"/>
    
  </entry>
  
  <entry>
    <title>linux/unix系统编程手册 5章习题</title>
    <link href="https://jackwener.github.io/2018/05/06/tlpi5%E7%AB%A0%E4%B9%A0%E9%A2%98/"/>
    <id>https://jackwener.github.io/2018/05/06/tlpi5章习题/</id>
    <published>2018-05-06T08:20:51.000Z</published>
    <updated>2018-05-07T14:46:31.597Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>一本书600页,2本1000多页,好多啊 QAQ</p></blockquote><h3 id="5-1"><a href="#5-1" class="headerlink" title="5-1"></a>5-1</h3><p>请使用标准I/O系统调用（open和lseek）和off_t数据类型修改程序清单5-3中的程序。将宏_FILE_OFFSET_BITS的值设置为64进行编译，并测试该程序是否能够成功创建一个大文件。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> _FILE_OFFSET_BITS 64</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> fd;</span><br><span class="line">    <span class="keyword">off_t</span> off;</span><br><span class="line">    <span class="keyword">if</span> (argc != <span class="number">3</span> ||<span class="built_in">strcmp</span>(argv[<span class="number">1</span>], <span class="string">"--help"</span>) == <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"pathname or offset erroe"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    fd = open(argv[<span class="number">1</span>],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);</span><br><span class="line">    <span class="keyword">if</span>(fd == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"open error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    off = atoll(argv[<span class="number">2</span>]);</span><br><span class="line">    <span class="keyword">if</span>(lseek(fd,off,SEEK_SET) == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"lseek error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(write(fd,<span class="string">"test"</span>,SEEK_SET) == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"write error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><blockquote><p>编译运行结果好像是错的…没查出Bug,照着书上打的,应该感觉没问题 (? _ ?)</p></blockquote><h3 id="5-2"><a href="#5-2" class="headerlink" title="5-2"></a>5-2</h3><p>编写一个程序，使用O_APPEND标志并以写方式打开一个已存在的文件，且将文件偏移量置于文件起始处，在写入数据。数据会显示在文件中的哪个位置？为什么？</p><p>在设置了O_APPEND标志后，对打开文件的写入操作write会变成一个包含有文件偏移和写入的一个原子操作，强制在文件的结尾写入，所以在写入之前使用lseek也没有办法改变写入的位置。但是可以通过lseek在文件的任意位置读取。</p><h3 id="5-3"><a href="#5-3" class="headerlink" title="5-3"></a>5-3</h3><p>编写程序，接受最多3个命令参数</p><blockquote><p>$ atomic_append filename num-bytes [x]</p></blockquote><p>该程序打开或创建指定文件，然后每次调用write()写入一个字节的方式，向文件结尾添加num-bytes个字节。若没有参数x，使用O_APPEND标志打开文件，否则不使用该标志打开文件。而是使用lseek(fd,0,SEEK_END)并write来追加内容。运行如下命令，解释ls -l两个文件大小的为什么不同。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i, fd, flags, numBytes;</span><br><span class="line">    <span class="keyword">off_t</span> off;</span><br><span class="line"></span><br><span class="line">    flags = O_RDWR | O_CREAT;</span><br><span class="line">    <span class="keyword">if</span>(argc &lt; <span class="number">3</span> || <span class="built_in">strcmp</span>(argv[<span class="number">1</span>], <span class="string">"--help"</span>) == <span class="number">0</span> )</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"parameter error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(argc != <span class="number">4</span>)</span><br><span class="line">        flags = flags | O_APPEND;</span><br><span class="line"></span><br><span class="line">    numBytes = atoi(argv[<span class="number">2</span>]);</span><br><span class="line"></span><br><span class="line">    fd = open(argv[<span class="number">1</span>], flags, S_IRUSR | S_IWUSR);</span><br><span class="line">    <span class="keyword">if</span>(fd == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"open error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">char</span> buff = <span class="string">'a'</span>;</span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; numBytes; ++i)&#123;</span><br><span class="line">        <span class="keyword">if</span>(argc &gt; <span class="number">3</span> &amp;&amp; argv[<span class="number">3</span>] == <span class="string">"x"</span>)</span><br><span class="line">            <span class="keyword">if</span>(lseek(fd, <span class="number">0</span>, SEEK_END) == <span class="number">-1</span>)</span><br><span class="line">                &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"lseek error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(write(fd, &amp;buff, <span class="number">1</span>) != <span class="number">1</span>)</span><br><span class="line">            &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"write error"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果</p><blockquote><p>jakevin@jakevin-PC:~/Linux系统编程手册$ ./automic_append f1 1000000 &amp; ./automic_append f1 1000000<br>[1] 7783</p></blockquote><blockquote><p>jakevin@jakevin-PC:~/Linux系统编程手册$ ./automic_append f2 1000000 x &amp; ./automic_append f2 1000000 x<br>[2] 7789<br>[1]   已完成               ./automic_append f1 1000000<br>[2]+  已完成               ./automic_append f2 1000000 x</p></blockquote><blockquote><p>jakevin@jakevin-PC:~/Linux系统编程手册$ ls -l f1 f2</p></blockquote><blockquote><p>-rw——- 1 jakevin jakevin 2000000 May  7 17:00 f1</p></blockquote><blockquote><p>-rw——- 1 jakevin jakevin 1000000 May  7 17:00 f2</p></blockquote><p>原因书上很清楚了,类似独占文件的那个例子</p><h3 id="5-4"><a href="#5-4" class="headerlink" title="5-4"></a>5-4</h3><p>使用fcntl()和close()来实现dup()和dup2()。dup2()在处理oldfd和newfd相等时，应检查oldfd是否有效，测试fcntl(oldfd, F_GETFL)是否成功就可以达到这一点。若oldfd无效，则dup2返回-1，并将errno置为EBADF。</p><blockquote><p>注意点:使用fcntl()和close()来实现dup()和dup2()。务必牢记dup2()需要处理的一种特殊情况，即oldfd与newfd相等。这时，应检查oldfd是否有效，测试fcntl(oldfd, F_GETFL)是否成功就能达到这一目标。若oldfd无效，则dup2()将返回-1,并将errno置为EBADF。</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;  </span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fcntl</span><span class="params">(<span class="keyword">int</span> filedes, <span class="keyword">int</span> cmd, ...)</span></span>;</span><br></pre></td></tr></table></figure><p>当第二个参数cmd=F_DUPFD时，它的作用是根据filedes复制一个新文件描述符。此时，fcntl相当于dup和dup2函数。<br>第三个参数指出新复制的文件描述符是一个等于或大于该参数的可用文件描述符，且不能等于一个已有的文件描述符。如果第三个参数等于一个已有文件描述符，则取一个大于该参数的一个可用描述符。</p><p>DUPFD：duplicate（复制）File（文件）Description（描述）</p><h3 id="5-5"><a href="#5-5" class="headerlink" title="5-5"></a>5-5</h3><p>编写一程序，验证文件描述符及其副本是否共享了文件偏移量和打开文件的状态标识。</p><h3 id="5-6"><a href="#5-6" class="headerlink" title="5-6"></a>5-6</h3><p> 说明下列代码中每次执行write后，输出文件的内容是什么，为什么。<br> <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">fd1 = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);</span><br><span class="line"> fd2 = dup(fd1);</span><br><span class="line"> fd3 = open(file, O_RDWR);</span><br><span class="line"> write(fd1, <span class="string">"Hello,"</span>, <span class="number">6</span>);</span><br><span class="line"> write(fd2, <span class="string">" world"</span>, <span class="number">6</span>);</span><br><span class="line"> <span class="comment">//这里按照答案的解释，应该是有一个空格在world前面的，书上可能是印错了</span></span><br><span class="line"> lseek(fd2, <span class="number">0</span>, SEEK_SET);</span><br><span class="line"> write(fd1, <span class="string">"HELLO,"</span>, <span class="number">6</span>);</span><br><span class="line"> write(fd3, <span class="string">"Gidday"</span>, <span class="number">6</span>);</span><br></pre></td></tr></table></figure></p><blockquote><p>第一次write，文件变成了Hello,，第二次写入，继续在后面加上world，注意这里应该是有一个空格的，否则最后和答案对不上。第三次write，由于偏移至头，所以第三次覆盖了第一次的6个字符，变成了HELLO, world，第四次fd3的偏移量是0，所以也是从头开始写，覆盖了第三次的HELLO变成了Gidday world</p></blockquote><h3 id="5-7"><a href="#5-7" class="headerlink" title="5-7"></a>5-7</h3><p> 使用read()、write()、malloc()实现readv，writev函数功能。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;一本书600页,2本1000多页,好多啊 QAQ&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;5-1&quot;&gt;&lt;a href=&quot;#5-1&quot; class=&quot;headerlink&quot; title=&quot;5-1&quot;&gt;&lt;/a&gt;5-1&lt;/h3&gt;&lt;p&gt;请使用标准I/
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
      <category term="unix系统编程手册" scheme="https://jackwener.github.io/tags/unix%E7%B3%BB%E7%BB%9F%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C/"/>
    
  </entry>
  
  <entry>
    <title>linux/unix系统编程手册 4章习题</title>
    <link href="https://jackwener.github.io/2018/05/04/tlpi4%E7%AB%A0%E4%B9%A0%E9%A2%98/"/>
    <id>https://jackwener.github.io/2018/05/04/tlpi4章习题/</id>
    <published>2018-05-04T06:21:00.000Z</published>
    <updated>2018-05-07T09:33:32.948Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>作为一个咸鱼废了好久,期中很多考试,复习有点无聊,开始之前准备看的linux/unix系统编程手册</p></blockquote><p>另外去官网找源代码和头文件,make失败,尝试了一会儿就放弃了,毕竟影响不大</p><h3 id="4-1"><a href="#4-1" class="headerlink" title="4-1"></a>4-1</h3><p>tee命令是从标准输入中读取数据，直至文件结尾，随后将数据写入标准输出和命令行参数所指定的文件。请使用I/O系统调用实现tee命令。默认情况下，若已存在与命令行参数指定文件名同名的文件，tee命令将其覆盖。或者，当使用-a命令时，则在同名文件后面追加数据。</p><p>tee –help<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$ tee --help</span><br><span class="line">用法：tee [选项]... [文件]...</span><br><span class="line">将标准输入复制到每个指定文件，并显示到标准输出。</span><br><span class="line"></span><br><span class="line">  -a, --append          内容追加到给定的文件而非覆盖</span><br><span class="line">  -i, --ignore-interrupts       忽略中断信号</span><br><span class="line">  -p                        diagnose errors writing to non pipes</span><br><span class="line">      --output-error[=MODE]   set behavior on write error.  See MODE below</span><br><span class="line">      --help            显示此帮助信息并退出</span><br><span class="line">      --version         显示版本信息并退出</span><br></pre></td></tr></table></figure></p><p>实现这个命令主要是这章介绍的 通用I/O模型 中的open(),close(),read(),write().<br>另外使用到了附录中的getopt();</p><blockquote><p>另外感觉自己只有看到习题才能起看书的兴致,果然以后看书先看题再看书也不错</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">teeConfigStruct</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">int</span> a;</span><br><span class="line">    <span class="keyword">char</span> *outputPath;</span><br><span class="line">    <span class="keyword">int</span> outputFd;</span><br><span class="line">&#125; teeConfig;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getArgs</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *<span class="keyword">const</span> argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> opt;</span><br><span class="line">    <span class="keyword">if</span> ((opt = getopt(argc, argv, <span class="string">"a"</span>)) != <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        teeConfig.a = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">switch</span> (opt)</span><br><span class="line">        &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">'a'</span>:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"追加模式\n"</span>);</span><br><span class="line">            teeConfig.a = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"参数错误\n"</span>);</span><br><span class="line">            _exit(<span class="number">0</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (argc - optind &lt; <span class="number">1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"参数太少\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    teeConfig.outputPath = argv[optind];</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"输出路径 %s \n"</span>, teeConfig.outputPath);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> * <span class="keyword">const</span> argv[])</span></span>&#123;</span><br><span class="line">    getArgs(argc, argv);</span><br><span class="line">    <span class="keyword">int</span> outputFileFlag;</span><br><span class="line">    <span class="keyword">if</span>(teeConfig.a == <span class="number">1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        outputFileFlag =O_RDWR | O_CREAT | O_APPEND;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        outputFileFlag = O_RDWR | O_CREAT | O_TRUNC;</span><br><span class="line">    &#125;</span><br><span class="line">    teeConfig.outputFd = open(teeConfig.outputPath, outputFileFlag, <span class="number">0777</span>);</span><br><span class="line">    <span class="keyword">if</span> (teeConfig.outputFd == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"无法打开输出文件!\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">char</span> buff;</span><br><span class="line">    <span class="keyword">while</span> (read(STDIN_FILENO, &amp;buff, <span class="number">1</span>) &gt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"%c"</span>, buff);</span><br><span class="line">        <span class="keyword">if</span> (write(teeConfig.outputFd, &amp;buff, <span class="number">1</span>) == <span class="number">-1</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"无法写入输出文件!\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (close(teeConfig.outputFd) == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"无法关闭输出文件!\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="4-2"><a href="#4-2" class="headerlink" title="4-2"></a>4-2</h3><p>编写一个类似于cp命令的程序，当使用该程序复制一个包含空洞的文件时，能够使得目标文件和源文件内容保持一致</p><p>这个程序思路比较简单，读取源文件的一个字符，如果是0的话，使用lseek右移一个文件偏移量。否则将字符写入目标文件中。</p><p>文件空洞 ：当文件的偏移量大于文件的当前长度时，文件结尾到新写入数据之间的空间称为文件空洞。读取文件空洞的内容会返回以0填充的缓冲区。</p><p>　　　　　“空洞是否占用磁盘空间由文件系统决定”<br>　　　　　“如果空洞的边界落在块内，而非恰好落在块的边界上，则会分配一个完整的块来存储数据，块中与空洞相关的部分则以空字节填充”—-书本提示</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">copyConfigStruct</span>&#123;</span></span><br><span class="line">    <span class="keyword">int</span> inputFd;</span><br><span class="line">    <span class="keyword">int</span> outputFd;</span><br><span class="line">    <span class="keyword">char</span> *intputPath;</span><br><span class="line">    <span class="keyword">char</span> *outputPath;</span><br><span class="line">&#125;copyConfig;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *<span class="keyword">const</span> argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(argc &lt;<span class="number">3</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"参数过少\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    copyConfig.intputPath = argv[<span class="number">1</span>];</span><br><span class="line">    copyConfig.outputPath = argv[<span class="number">2</span>];</span><br><span class="line">    copyConfig.inputFd = open(copyConfig.intputPath,O_RDONLY);</span><br><span class="line">    <span class="keyword">if</span>(copyConfig.inputFd == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"打开文件失败\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">     copyConfig.outputFd = open(copyConfig.outputPath, O_RDWR|O_TRUNC|O_CREAT, <span class="number">0777</span>);</span><br><span class="line">    <span class="keyword">if</span>(copyConfig.outputFd == <span class="number">-1</span>)&#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"输出文件打开失败！\n"</span>);</span><br><span class="line">        _exit(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">char</span> buff;</span><br><span class="line">    <span class="keyword">while</span>( read(copyConfig.inputFd, &amp;buff, <span class="number">1</span>) &gt; <span class="number">0</span> )&#123;</span><br><span class="line">        <span class="keyword">if</span> (buff == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(lseek(copyConfig.outputFd, <span class="number">1</span>, SEEK_CUR) == <span class="number">-1</span>)&#123;</span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">"跳过空洞失败！\n"</span>);</span><br><span class="line">                _exit(<span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span>(write(copyConfig.outputFd, &amp;buff, <span class="number">1</span>) == <span class="number">-1</span>)&#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"写入文件失败！\n"</span>);</span><br><span class="line">            _exit(<span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    close(copyConfig.inputFd);</span><br><span class="line">    close(copyConfig.outputFd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;作为一个咸鱼废了好久,期中很多考试,复习有点无聊,开始之前准备看的linux/unix系统编程手册&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;另外去官网找源代码和头文件,make失败,尝试了一会儿就放弃了,毕竟影响不大&lt;/p&gt;
&lt;h3 id=&quot;4-
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
      <category term="unix系统编程手册" scheme="https://jackwener.github.io/tags/unix%E7%B3%BB%E7%BB%9F%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C/"/>
    
  </entry>
  
  <entry>
    <title>随想啦啦啦</title>
    <link href="https://jackwener.github.io/2018/04/20/Linux/"/>
    <id>https://jackwener.github.io/2018/04/20/Linux/</id>
    <published>2018-04-19T17:57:12.000Z</published>
    <updated>2018-05-07T09:29:16.326Z</updated>
    
    <content type="html"><![CDATA[<h1 id="开坑Linux啦"><a href="#开坑Linux啦" class="headerlink" title="开坑Linux啦"></a>开坑Linux啦</h1><blockquote><p>从开学进来已经相当久了，但是感觉学的东西很少，平时也是比较迷茫，不知道学什么，上次进行了联创的春招熬测后，确实是收获很多，有了很多想法，ps(挺感谢这个组织的，大概也是从想进联创开始入的计算机的坑吧，很想加入它，但是想来希望不大了，以后可能还会以学习的心态去看看考试题，没报什么希望)，后面很长时间可能一直待在Linux的坑里面。</p></blockquote><h2 id="书单计划"><a href="#书单计划" class="headerlink" title="书单计划"></a>书单计划</h2><ol><li>Linux/Unix系统编程手册</li><li>Linux/Unix编程实践教程</li><li>深入理解Linux内核</li><li>清华的操作系统的课</li><li>UNP卷一</li></ol><p>另外这次也去看看了冰岩的程序组，感觉后端似乎也挺好玩，或许会开新的坑。</p><p>ACM还是要继续(划水)，好玩的东西</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;开坑Linux啦&quot;&gt;&lt;a href=&quot;#开坑Linux啦&quot; class=&quot;headerlink&quot; title=&quot;开坑Linux啦&quot;&gt;&lt;/a&gt;开坑Linux啦&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;从开学进来已经相当久了，但是感觉学的东西很少，平时也是比较迷茫，不
      
    
    </summary>
    
    
      <category term="Linux" scheme="https://jackwener.github.io/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>CSAPP datelab（伪）报告</title>
    <link href="https://jackwener.github.io/2018/04/14/datelab/"/>
    <id>https://jackwener.github.io/2018/04/14/datelab/</id>
    <published>2018-04-14T10:43:19.000Z</published>
    <updated>2018-04-17T15:06:57.179Z</updated>
    
    <content type="html"><![CDATA[<p>CSAPP的第一个Lab<br><a id="more"></a></p><h1 id="CSAPP-datelab"><a href="#CSAPP-datelab" class="headerlink" title="CSAPP datelab"></a>CSAPP datelab</h1><blockquote><p>读CSAPP这本书的过程中出现了很多的困难，同时，我读这本书时间耗时很长但是<br>又完全没有弄懂很多东西，在迷迷糊糊的把书看完一遍后开始准备做配套的lab已以及准备南大的计算机系统配套的实验在这个过程中重新把书看一遍。</p></blockquote><blockquote><p>另外做这个Lab感觉难度不小，后面可能要补补离散</p></blockquote><p>datelab分为3个部分，位操作，整数操作，浮点操作</p><h2 id="位操作"><a href="#位操作" class="headerlink" title="位操作"></a>位操作</h2><h3 id="第一题"><a href="#第一题" class="headerlink" title="第一题"></a>第一题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 1 √</span></span><br><span class="line"><span class="comment"> * bitAnd - x&amp;y using only ~ and |</span></span><br><span class="line"><span class="comment"> *   Example: bitAnd(6, 5) = 4</span></span><br><span class="line"><span class="comment"> *   Legal ops: ~ |</span></span><br><span class="line"><span class="comment"> *   Max ops: 8</span></span><br><span class="line"><span class="comment"> *   Rating: 1</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><p>这个比较简单<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">bitAnd</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> ~((~x) | (~y));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h3 id="第二题"><a href="#第二题" class="headerlink" title="第二题"></a>第二题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 2 √</span></span><br><span class="line"><span class="comment"> * getByte - Extract byte n from word x</span></span><br><span class="line"><span class="comment"> *   Bytes numbered from 0 (LSB) to 3 (MSB)</span></span><br><span class="line"><span class="comment"> *   Examples: getByte(0x12345678,1) = 0x56</span></span><br><span class="line"><span class="comment"> *   Legal ops: ! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</span></span><br><span class="line"><span class="comment"> *   Max ops: 6</span></span><br><span class="line"><span class="comment"> *   Rating: 2</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><p>提取一个数字的n字节,这里使用掩码0xFF来取一个字节<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">getByte</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">return</span> (x&gt;&gt;(n&lt;&lt;<span class="number">3</span>)) &amp; <span class="number">0xFF</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h3 id="第三题"><a href="#第三题" class="headerlink" title="第三题"></a>第三题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 3 √</span></span><br><span class="line"><span class="comment"> * logicalShift - shift x to the right by n, using a logical shift</span></span><br><span class="line"><span class="comment"> *   Can assume that 0 &lt;= n &lt;= 31</span></span><br><span class="line"><span class="comment"> *   Examples: logicalShift(0x87654321,4) = 0x08765432</span></span><br><span class="line"><span class="comment"> *   Legal ops: ~ &amp; ^ | + &lt;&lt; &gt;&gt;</span></span><br><span class="line"><span class="comment"> *   Max ops: 20</span></span><br><span class="line"><span class="comment"> *   Rating: 3</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><p>取出高位，然后把高位变为0（使用掩码）<br>最后把取出的高位放回去<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">logicalShift</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">int</span> a=x&amp;(<span class="number">1</span>&lt;&lt;<span class="number">31</span>);</span><br><span class="line">  <span class="keyword">int</span> b=x&amp;(~(<span class="number">1</span>&lt;&lt;<span class="number">31</span>));</span><br><span class="line">  b&gt;&gt;=n;</span><br><span class="line">  b |= (a&gt;&gt;n)&amp;(<span class="number">1</span>&lt;&lt;<span class="number">32</span>+~n)<span class="comment">/*大坑.....注意a也是逻辑右移所以要用掩码取位*/</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h3 id="第四题"><a href="#第四题" class="headerlink" title="第四题"></a>第四题</h3><blockquote><p>/* 4 √</p><ul><li>bitCount - returns count of number of 1’s in word</li><li>Examples: bitCount(5) = 2, bitCount(7) = 3</li><li>Legal ops: ! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li><li>Max ops: 40</li><li>Rating: 4</li></ul></blockquote><p>ACM做题的时候分治法的时候讲过，把32位的数分为16组，每组的两个数相加，得到16个数，然后重复即可。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">bitCount</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> bits = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> mask = <span class="number">0x1</span> | (<span class="number">0x1</span> &lt;&lt; <span class="number">8</span>) | (<span class="number">0x1</span> &lt;&lt; <span class="number">16</span>) | (<span class="number">0x1</span> &lt;&lt; <span class="number">24</span>);</span><br><span class="line">    bits += (x &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">1</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">2</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">3</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">4</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">5</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">6</span>) &amp; mask);</span><br><span class="line">    bits += ((x &gt;&gt; <span class="number">7</span>) &amp; mask);</span><br><span class="line">    <span class="keyword">return</span> (bits &amp; <span class="number">0xFF</span>) + ((bits &gt;&gt; <span class="number">8</span>) &amp; <span class="number">0xFF</span>) + ((bits &gt;&gt; <span class="number">16</span>) &amp; <span class="number">0xFF</span>) + ((bits &gt;&gt; <span class="number">24</span>) &amp; <span class="number">0xFF</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="第五题"><a href="#第五题" class="headerlink" title="第五题"></a>第五题</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">/* 5 √</span><br><span class="line"> * bang - Compute !x without using !</span><br><span class="line"> *   Examples: bang(3) = 0, bang(0) = 1</span><br><span class="line"> *   Legal ops: ~ &amp; ^ | + &lt;&lt; &gt;&gt;</span><br><span class="line"> *   Max ops: 12</span><br><span class="line"> *   Rating: 4</span><br><span class="line"> */</span><br></pre></td></tr></table></figure><p>计算数字的逆（！）<br>很巧妙，0的特征，0和0的相反数首位按位或为0<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">bang</span><span class="params">(<span class="keyword">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">return</span> ((x|(~x+<span class="number">1</span>))&gt;&gt;<span class="number">31</span>)&amp;<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h2 id="补码运算"><a href="#补码运算" class="headerlink" title="补码运算"></a>补码运算</h2><h3 id="第六题"><a href="#第六题" class="headerlink" title="第六题"></a>第六题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">tmin</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">return</span>(<span class="number">1</span>&lt;&lt;<span class="number">31</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="第七题"><a href="#第七题" class="headerlink" title="第七题"></a>第七题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">思路：</span><br><span class="line">分正负数，分别前面为<span class="number">0</span>或<span class="number">1</span>，只需判断<span class="number">32</span>-n是否全<span class="number">0</span>或<span class="number">1</span>，通过掩码取这些位即可</span><br><span class="line">```c</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fitsBits</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> !((x &lt;&lt; (<span class="number">33</span> + ~n) &gt;&gt; (<span class="number">33</span> + ~n))^x);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="第八题"><a href="#第八题" class="headerlink" title="第八题"></a>第八题</h3><p>题意：数除以2^n<br>对于正数直接算术右移即可，对于负数</p><h3 id="第九题"><a href="#第九题" class="headerlink" title="第九题"></a>第九题</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">negate</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> ~x + <span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="第十题"><a href="#第十题" class="headerlink" title="第十题"></a>第十题</h3><p>判断正数，高位为0避开0；<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">isPositive</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> (!(x &gt;&gt; <span class="number">31</span>)) ^ (!(x ^ <span class="number">0</span>));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;CSAPP的第一个Lab&lt;br&gt;
    
    </summary>
    
    
      <category term="CSAPP" scheme="https://jackwener.github.io/tags/CSAPP/"/>
    
  </entry>
  
  <entry>
    <title>读csapp中的感悟</title>
    <link href="https://jackwener.github.io/2018/03/19/%E8%AF%BBcsapp%E4%B8%AD%E7%9A%84%E6%84%9F%E6%82%9F/"/>
    <id>https://jackwener.github.io/2018/03/19/读csapp中的感悟/</id>
    <published>2018-03-19T02:16:58.000Z</published>
    <updated>2018-05-10T12:20:45.456Z</updated>
    
    <summary type="html">
    
    </summary>
    
    
      <category term="CSAPP" scheme="https://jackwener.github.io/tags/CSAPP/"/>
    
      <category term="随想" scheme="https://jackwener.github.io/tags/%E9%9A%8F%E6%83%B3/"/>
    
  </entry>
  
</feed>
