⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib0016.html

📁 Memory Management—Algorithms and implementation in C/C++ Introduction Chapter 1 - Memory Manag
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<li class="listitem">
<p class="first-para">System management mode (SMM)</p>
</li>
<li class="listitem">
<p class="first-para">Virtual 8086 mode</p>
</li>
</ul>
<p class="para">System management mode and virtual 8086 mode are both special-purpose modes of operation that are only used under special circumstances. I will focus primarily on the first two modes of operation: real mode and protected mode. In addition, I will investigate how each of these modes support segmentation and paging.</p>
<p class="para">Having the processor operate in different modes is not a feature limited to the Intel platform. The MIPS64 processor, for example, also operates in four modes:</p>
<ul class="itemizedlist">
<li class="first-listitem">
<p class="first-para">Kernel mode</p>
</li>
<li class="listitem">
<p class="first-para">User mode</p>
</li>
<li class="listitem">
<p class="first-para">Debug mode</p>
</li>
<li class="listitem">
<p class="first-para">Supervisor mode</p>
</li>
</ul>
<div class="section">
<h3 class="sect3-title">
<a name="78"></a><a name="ch01lev2sec1"></a>Real Mode Operation</h3>
<p class="first-para">The first IBM PC ran strictly in real mode. Furthermore, all 32-bit Intel computers also start in real mode when they are booted. This sort of provides a least common denominator behavior that backward compatibility depends upon.</p>
<p class="para">Real mode operating systems tend to be very small (i.e., less than 128KB) because they rely on the BIOS to provide an interface to the hardware. This allows them to easily fit on a 1.44MB floppy diskette. Virus protection rescue disks rely on this fact, as do system repair disks. I have also bought drive partitioning software that can be run from a boot disk.</p>
<p class="para">In real mode, the general-purpose registers we saw earlier in <a href="LiB0014.html#61" target="_parent" class="chapterjump">Figure 1.2</a> are truncated into 16-bit registers, as are the error flag <a name="79"></a><a name="IDX-15"></a>and instruction pointer registers. The real mode register setup is displayed in <a class="internaljump" href="#ch01fig07">Figure 1.7</a>.</p>
<div class="figure">
<a name="80"></a><a name="ch01fig07"></a><span class="figuremediaobject"><img src="images/fig43_01.jpg" height="360" width="319" alt="" border="0"></span>
<br style="line-height: 1">
<span class="figure-title"><span class="figure-titlelabel">Figure 1.7</span></span>
</div>
<p class="para">As you can see, the "E" prefix has been removed from the register names. In addition, each of the 16-bit general registers, AX, CX, DX, and EX, can be manipulated in terms of two 8-bit registers. For example, the AX register can be seen as the combination of the AH and AL registers. The AH register refers to the high byte in AX, and the AL register refers to the low byte in AX.</p>
<table border="0" cellspacing="0" cellpadding="0" class="note">
<tr>
<td valign="top" class="admon-check"></td><td valign="top" class="admon-title">Note&nbsp;</td><td valign="top" class="admon-body">
<p class="first-para">The memory and mode registers shown in <a href="LiB0014.html#61" target="_parent" class="chapterjump">Figure 1.2</a> are still visible in real mode. They still exist if the processor is a 32-bit class CPU but they have no significance or use in real mode. The only exception to this rule is if you are trying to switch to protected mode.</p>
</td>
</tr>
</table>
<p class="para">A machine in real mode can address 1MB of DRAM. This implies that only 20 address lines are used in real mode. The address of a byte in memory, for a processor real mode, is formed by adding an offset address to a segment address. The result of the sum is always a 20-bit value (remember this fact; it is important), which confirms our suspicion that there are 20 address lines.</p>
<p class="para">The address formed by the sum of the segment and offset addresses corresponds directly to the value that is placed on the processor's address lines. Now you can get a better idea of why they call it "real" mode. The address of a byte in real mode maps directly to a "real" byte in physical memory.</p>
<a name="81"></a><a name="IDX-16"></a>
<p class="para">An address is denoted, in Intel assembly language, by a <span class="fixed">segment:offset</span> pair. For example, if a byte is located in segment <span class="fixed">0x8200</span> and is situated at an offset of <span class="fixed">0x0100</span>, the address of this byte is specified as:</p>
<div class="informalexample">
<pre class="literallayout">
    0x8200:0x0100
</pre>
</div>
<p class="para">Sometimes, for reasons that I will explain later, this is also written as:</p>
<div class="informalexample">
<pre class="literallayout">
    0x8200[0]:0x0100
</pre>
</div>
<p class="para">The real mode address resolution process is displayed in <a class="internaljump" href="#ch01fig08">Figure 1.8</a>.</p>
<div class="figure">
<a name="82"></a><a name="ch01fig08"></a><span class="figuremediaobject"><a href="images/fig44%5F01%5F0%2Ejpg" NAME="IMG_8" target="_parent"><img src="images/fig44_01.jpg" height="152" width="325" alt="Click To expand" border="0"></a></span>
<br style="line-height: 1">
<span class="figure-title"><span class="figure-titlelabel">Figure 1.8</span></span>
</div>
<p class="para">Segment addresses denote a particular memory segment and are always stored in one of the 16-bit segment registers. Specifically, a segment address specifies the <i class="emphasis">base address,</i> the lowest address, of a memory segment. Each segment register has a particular use:</p>
<div class="informaltable">
<table border="0">
<thead>
<tr valign="top">
<th class="th" scope="col" align="left">
<p class="table-para">Register</p>
</th><th class="th" scope="col" align="left">
<p class="table-para">Use</p>
</th>
</tr>
<tr>
<td colspan="2">
<hr>
</td>
</tr>
</thead>
<tbody>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">CS</p>
</td><td class="td" align="left">
<p class="table-para">Segment address of code currently being executed</p>
</td>
</tr>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">SS</p>
</td><td class="td" align="left">
<p class="table-para">Segment address of stack</p>
</td>
</tr>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">DS</p>
</td><td class="td" align="left">
<p class="table-para">Data segment address</p>
</td>
</tr>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">ES</p>
</td><td class="td" align="left">
<p class="table-para">Extra segment address (usually data)</p>
</td>
</tr>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">FS</p>
</td><td class="td" align="left">
<p class="table-para">Extra segment address (usually data)</p>
</td>
</tr>
<tr valign="top">
<td class="td" align="left">
<p class="table-para">GS</p>
</td><td class="td" align="left">
<p class="table-para">Extra segment address (usually data)</p>
</td>
</tr>
</tbody>
</table>
</div>
<table border="0" cellspacing="0" cellpadding="0" class="note">
<tr>
<td valign="top" class="admon-check"></td><td valign="top" class="admon-title">Note&nbsp;</td><td valign="top" class="admon-body">
<p class="first-para">The fact that there are six segment registers means that at any time, only six segments of memory can be manipulated. A program can have more than six segments, but only six can be accessible at any one point in time.</p>
</td>
</tr>
</table>
<a name="83"></a><a name="IDX-17"></a>
<p class="para">Offset addresses can be stored in the general registers and are 16 bits in size. Given that an offset address is 16 bits, this limits each segment to 64KB in size.</p>
<div class="qandaset">
<table border="0" cellpadding="0">
<tr class="qandaentry">
<td class="td" valign="top" width="2%">
<p class="first-para">
<a name="LiB2"><b>1.&nbsp;</b></a>
</p>
</td><td class="td" valign="top" width="90%">
<p class="first-para">If the segment address and offset address are both stored in 16-bit registers, how can the sum of two 16-bit values form a 20-bit value?</p>
</td><td class="td" valign="top" width="8%">
<p class="first-para">
<a href="#LiB1"><img src="images/question.gif" height="24" width="24" alt="The trick is that the segment address has an implicit zero added to the end. For example, a segment address of 0x0C00 is treated as 0x0C000 by the processor. This is denoted, in practice, by placing the implied zero in brackets (i.e., 0x0C00[0]). This is where the processor comes up with a 20-bit value. " border="0"></a>
</p>
</td>
</tr>
</table>
<p class="bold">Answers</p>
<table border="0" cellpadding="0">
<tr class="qandaentry-answer">
<td class="td" valign="top" width="2%">
<p class="first-para">
<a class="internaljump" name="answer.nr-qandaentry.66763D62-F11E-458F-9967-D3C0273B9A9D" href="#LiB2"><b>1.</b></a>&nbsp;</p>
</td><td class="td" valign="top" width="90%">
<p class="first-para">The trick is that the segment address has an implicit zero added to the end. For example, a segment address of 0x0C00 is treated as 0x0C000 by the processor. This is denoted, in practice, by placing the implied zero in brackets (i.e., 0x0C00[0]). This is where the processor comes up with a 20-bit value.</p>
</td>
</tr>
</table>
</div>
<p class="para">As you can see, the real mode segment/offset approach does provide a crude sort of segmentation. However, at no point did I mention that the boundaries between segments are protected. The ugly truth is that there is no memory protection in real mode. When you run a program in real mode, it owns everything and can run amok if it wants.</p>
<p class="para">Running an application in real mode is like letting a den of Cub Scouts into your home. They're young, spirited, and all hopped-up on sugar. If you're not careful, they will start tearing the house down. Crashing a real mode machine is simple, and there is little you can do to prevent it (other than back up your work constantly).</p>
<p class="para">In case you are wondering, and I'm sure some of you are, here is an example of a C program that can crash a computer running in real mode:</p>
<div class="informalexample">
<pre class="literallayout">
<span style="background-color:d9d9d9">/* --crashdos.c-- */</span>

<span style="background-color:d9d9d9">void main()</span>
<span style="background-color:d9d9d9">{</span>
    <span style="background-color:d9d9d9">unsigned char *ptr;</span>
    <span style="background-color:d9d9d9">int i;</span>

    <span style="background-color:d9d9d9">ptr = (unsigned char *)0x0;</span>
    <span style="background-color:d9d9d9">for(i=0;i&lt;1024;i++)</span>
    <span style="background-color:d9d9d9">{</span>
        <span style="background-color:d9d9d9">ptr[i]=0x0;</span>
    <span style="background-color:d9d9d9">}</span>
    <span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span>
</pre>
</div>
<p class="para">See how little effort it takes? There is nothing special or secret about this attack. I just overwrite the interrupt vector table that is <a name="84"></a><a name="IDX-18"></a>located at the bottom of memory. If you wanted to hide this type of code in a large executable, you could probably cut down the program to less than five lines of assembly code.</p>
<p class="para">If you really wanted to be malicious, you could disable the keyboard and then start reformatting the hard drive. The only defense a person would have is to yank the power cord, and even then, by the time they realize what is going on, it would probably be too late. My point, however, is not to tell you how to immobilize a DOS machine. Nobody uses them anymore, anyway. My motive is to demonstrate that real mode is anything but a secure environment.</p>
<p class="para">To make matters worse, real mode does not support paging. All you have to play with is 1MB of DRAM. In reality, you actually have less than 1MB because the BIOS and video hardware consume sizeable portions of memory. Remember the Bill Gates quote?</p>
<table border="0" cellspacing="0" cellpadding="0" class="note">
<tr>
<td valign="top" class="admon-check"></td><td valign="top" class="admon-title">Note&nbsp;</td><td valign="top" class="admon-body">
<p class="first-para">No memory protection? No paging? Now you understand how the first version of PC-DOS was less than 5,000 lines of assembler. Perhaps "real" mode is called such because it is really minimal.</p>
</td>
</tr>
</table>
<p class="last-para">Intel's processors would never have made inroads into the enterprise with this kind of Mickey Mouse memory management. In an attempt to support more robust operating systems and larger address spaces, Intel came out with the 80386. The 80386 had a physical address space of 4GB and supported a new mode of operation: protected mode.</p>
<a></a>
</div>
<div class="section">
<h3 class="sect3-title">
<a name="85"></a><a name="ch01lev2sec2"></a>Protected Mode Operation</h3>
<p class="first-para">Protected mode supplies all the bells and whistles that are missing in real mode. The Pentium processor was specifically designed to run in protected mode. Its internal plumbing executes 32-bit instructions more efficiently than it executes 16-bit instructions. Having the Pentium start in real mode during a machine's power-up was sort of a courtesy that the Intel engineers have extended to help operating systems bootstrap.</p>
<p class="para">An Intel processor running in protected mode supports protected segmentation, and it also can support paging. This means that address resolution will be much more complicated. In real mode, we just added an offset address to a segment address to produce a value that corresponded directly to physical memory address. In protected mode, the processor expects a whole load of special data structures to be in place. In addition, the segment and offset pair may no longer correspond directly to a physical address. So hang on, here we go...</p>
<a name="86"></a><a name="IDX-19"></a>
<div class="section">
<h4 class="sect4-title">Protected Mode Segmentation</h4>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -