﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-快乐生活，感受人生</title><link>http://www.cnitblog.com/yuhensong/</link><description>New Life, Old Face
&lt;bgsound src=http://www.ht.com.cn/bbu/attachments/month_0510/kh0n_10.wma loop="-1"&gt;</description><language>zh-cn</language><lastBuildDate>Mon, 22 Mar 2010 14:12:10 GMT</lastBuildDate><pubDate>Mon, 22 Mar 2010 14:12:10 GMT</pubDate><ttl>60</ttl><item><title>Blocked IO resource from AML in Win XP</title><link>http://www.cnitblog.com/yuhensong/archive/2009/12/31/63509.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Thu, 31 Dec 2009 06:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2009/12/31/63509.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/63509.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2009/12/31/63509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/63509.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/63509.html</trackback:ping><description><![CDATA[<p>ACPI BIOS implementations that directly access certain system hardware resources from AML code cannot be synchronized with operating system access to the same resources, which can cause the operating system to become unstable or to stop responding. This article describes issues related to BIOS AML firmware accessing system board resources, and the changes implemented to address these issues in the Windows XP, Windows Server 2003, and future versions of the operating system.</p>
		<h5 style="PADDING-TOP: 2px"> </h5>
		<a name="EX">
		</a>
		<h2>Introduction </h2>
		<p>
		</p>
		<p>During the development of the Windows XP operating system, Microsoft discovered many ACPI BIOS implementations that directly access and attempt to manipulate system hardware resources from BIOS ASL code. At run time, system board resources must not be simultaneously accessed or modified by both the BIOS and the operating system, because these accesses cannot be synchronized with operating system access to the same system resources. As a result, BIOS read or write access to these resources can cause adverse effects, ranging from general instability to causing the system to stop responding.</p>
		<p>Historically, error conditions of this nature might have been construed by the operating system as an unrecoverable error, resulting in a stop error (blue screen) and system shutdown. In an effort to improve the end user experience and increase system reliability, Windows XP has been re-designed as described in this article.</p>
		<a name="E3">
		</a>
		<h2>Changes in Windows XP </h2>
		<p>
		</p>
		<p>While developing and testing Windows XP a list of system board resources was identified that, when accessed from BIOS AML code, proved to be the most problematic. This article refers to the list of addresses associated with these resources as the "blocked ports list." Table 1 lists affected system resources and their associated I/O addresses.</p>
		<p>The ACPI AML interpreter in the Windows XP kernel monitors all attempts by BIOS AML code to read from or write to the specific addresses on the blocked ports list. When a read or write access is detected at any of these addresses, the following actions will occur: </p>
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>An error will be added to the system event log stating that the ACPI AML interpreter has detected an illegal read or write, and that this read or write has been blocked.</p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>For BIOS AML code that indicates compatibility with the Windows XP ACPI implementation, the operating system will block all read and write accesses to these addresses. This compatibility is determined by the AML code calling the _OSI method, as described later in this article.</p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>For BIOS AML code that is compatible with versions of Windows released before Windows XP, the operating system will allow the read or write access to succeed in most cases, but will still add an error to the system event log. </p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>Accesses to the Programmable Interrupt Controller (PIC) and cascaded PIC, and to PIC Edge/Level Control Registers, are always blocked because BIOS access to these ports is potentially catastrophic and might prevent the system from running. These I/O addresses are noted in Table 1.</p>
								</td>
						</tr>
				</tbody>
		</table>
		<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"> </div>
		<a name="EKB">
		</a>
		<h2>Windows XP BIOS Compatibility Determined Using _OSI </h2>
		<p>
		</p>
		<p>The specific actions taken by the operating system when read or write accesses to these resources are detected depends on the version of ACPI interface that the BIOS indicates it supports. This is determined through the BIOS use of the _OSI method as described in this article. </p>
		<p>For complete details about the _OSI method, see <a href="http://www.microsoft.com/taiwan/whdc/system/pnppwr/powermgmt/_OSI-method.mspx">How to Identify Windows Versions in ACPI Using _OSI</a>.</p>
		<p>The _OSI method is being introduced with the Windows XP operating system. BIOS ASL code can test for the level of features supported in the current Windows operating system by passing a string to the _OSI method. The operating system returns TRUE for any string that represents a feature set that it can support. Windows XP, for example, returns TRUE for the string "Windows 2001".</p>
		<p>By passing the string "Windows 2001" into the _OSI method, the BIOS indicates to the operating system that the BIOS is aware of and compatible with the ACPI implementation and feature set of Windows XP. Windows XP will then reject all I/O reads or writes from BIOS ASL code to addresses on the blocked ports list and generate an error in the system event log.</p>
		<a name="EVB">
		</a>
		<h2>Windows XP and Legacy BIOS ASL Implementations </h2>
		<p>
		</p>
		<p>For those BIOS implementations that are compatible with versions of Windows released before Windows XP, the operating system will allow the read or write access to succeed in most cases. Accesses to the PIC and cascaded PIC, and to the PIC Edge/Level Control Registers, are always blocked. In all cases an error will be written to the system event log. </p>
		<p>To help ensure system stability on systems with legacy BIOS ASL implementations, Windows XP attempts to synchronize accesses to resources whenever possible. For example: </p>
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>When a read or write access is detected to the CMOS/RTC index and data pair registers at I/O addresses 0x70 and 0x71, the operating system does the following: </p>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td class="listBullet" valign="top">•</td>
																<td class="listItem">
																		<p>Disables interrupts</p>
																</td>
														</tr>
														<tr>
																<td class="listBullet" valign="top">•</td>
																<td class="listItem">
																		<p>Preserves the contents of the index (address) register</p>
																</td>
														</tr>
														<tr>
																<td class="listBullet" valign="top">•</td>
																<td class="listItem">
																		<p>Allows the ASL code access to proceed</p>
																</td>
														</tr>
														<tr>
																<td class="listBullet" valign="top">•</td>
																<td class="listItem">
																		<p>Restores the value of the index register</p>
																</td>
														</tr>
												</tbody>
										</table>
										<p>This process helps prevent a race condition in which the operating system writes the desired address to the index register and a BIOS method changes the address in the index register before the operating system can access the intended data register, causing the operating system to use the wrong index value. </p>
										<p>
												<b>Note: </b>This approach cannot guarantee that the CMOS address register (0x70) will not be corrupted on multi-processor systems. </p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>ASL code that attempts to access the PCI Configuration Space registers at 0xCF8 0xD00 is re-routed by the kernel AML interpreter to call HalGetBusDataByOffset, which allows access to system resources to be properly synchronized.<br /></p>
								</td>
						</tr>
				</tbody>
		</table>
		<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"> </div>
		<a name="EPC">
		</a>
		<h2>Accessing BIOS Non-volatile Memory (CMOS NVRAM) </h2>
		<p>
		</p>
		<p>With these changes in Windows XP, BIOS developers may be looking for alternative methods to access CMOS NVRAM. The following examples present some possible solutions.</p>
		<h3>Reading from CMOS NVRAM</h3>
		<p>This example ASL code defines an operation region in the system memory address space. During POST, BIOS code copies the data from CMOS to this memory area. ASL code can then use fields to read the CMOS data. </p>
		<p>Each CM<i>nn</i> field in the example corresponds to 8 bits of CMOS. The BIOS engineer is responsible for defining these fields appropriately. Each field of this memory can be any combination of bits. </p>
		<p>During system boot, BIOS POST code should update this memory area with the value written in the CMOS before handing off to the operating system. Once the operating system has switched to ACPI mode, any attempt to read CMOS from ASL code should be done by reading from these memory locations and not from CMOS NVRAM I/O ports. </p>
		<pre class="codeSample">// Declare a memory operation region for 255 bytes of CMOS. 
// First 0 to 127 bytes reflects CMOS access from IO ports 0x70 
// and 0x71 and the subsequent bytes reflect CMOS access from IO 
// ports 0x72 to 0x73.  BIOS code should properly set up the base 
// address of the beginning of this memory range at offset during 
// BIOS POST.

OperationRegion (CMRM, SystemMemory, offset, 255)  //Operation Region 

Field (CMRM, AnyAcc, NoLock, Preserve) {   //Field
    //  Memory corresponding to addresses 0x70, 0x71
    CM00,    8,
    CM01,    8,
    CM02,    8,
    .
    .
    CM7f,     8,     

    // Memory corresponding to addresses 0x72, 0x73
    CM80,    8,
    .
    .
    CMFF
    }   // End of CMOS field
</pre>
		<p>The following is an example of ASL code which reads from CMOS offset 52 bits 4 to 7 and returns the value read. </p>
		<pre class="codeSample">// This example returns bits 4 to 7 of CMOS offset 52

Method (RDCM) {
    ShiftRight (CM52, 4, Local0)
    Return (Local0) 
    }
</pre>
		<h3>Writing to CMOS NVRAM</h3>
		<p>BIOS code should write to CMOS NVRAM by generating a system management interrupt (SMI). AML code can generate a SMI by writing a specific value to the SMI command port. AML code can pass the CMOS offset and value to be written through the NVRAM memory operation region. The BIOS SMI handles the writes to CMOS, and also updates the memory area pointed by the CMRM operation region to reflect the correct CMOS contents.</p>
		<a name="ECD">
		</a>
		<h2>Affected System Resources and Addresses </h2>
		<p>
		</p>
		<p>Table 1 lists the system resources and associated I/O addresses that should not be directly accessed by BIOS AML code (the "blocked ports" list).</p>
		<p>
				<b>Table 1 Blocked I/O Port Addresses and System Board Resources </b>
		</p>
		<table class="dataTable" id="EJD" cellspacing="0" cellpadding="0">
				<thead>
						<tr class="stdHeader" valign="top">
								<td id="colELD">Address</td>
								<td id="colEOD">Function</td>
								<td id="colERD" style="BORDER-RIGHT: #cccccc 1px solid">Comments</td>
						</tr>
				</thead>
				<tbody>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x000 0x00F</p>
								</td>
								<td>
										<p class="lastInCell">DMA Controller 1</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x020 0x021</p>
								</td>
								<td>
										<p class="lastInCell">Programmable Interrupt Controller</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell">Access is never allowed*</p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x040 0x043</p>
								</td>
								<td>
										<p class="lastInCell">System Timer 1</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x048 0x04B</p>
								</td>
								<td>
										<p class="lastInCell">Timer 2 Failsafe</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x070 0x071</p>
								</td>
								<td>
										<p class="lastInCell">System CMOS, RTC</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x074 0x076</p>
								</td>
								<td>
										<p class="lastInCell">Extended CMOS</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x081 0x083</p>
								</td>
								<td>
										<p class="lastInCell">DMA1 Page Registers</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x087</p>
								</td>
								<td>
										<p class="lastInCell">DMA1 CH0 Low Page</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x089</p>
								</td>
								<td>
										<p class="lastInCell">DMA2 CH2 Low Page</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x08A 0x08B</p>
								</td>
								<td>
										<p class="lastInCell">DMA2 CH3 Low Page,</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x08F</p>
								</td>
								<td>
										<p class="lastInCell">DMA2 Low Page Refresh</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x090 0x091</p>
								</td>
								<td>
										<p class="lastInCell">Arbitration Control Port Card Select Feedback</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x093 0x094</p>
								</td>
								<td>
										<p class="lastInCell">Reserved System Board Setup</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x096 0x097</p>
								</td>
								<td>
										<p class="lastInCell">POS Channel Select</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x0A0 0x0A1</p>
								</td>
								<td>
										<p class="lastInCell">Cascaded Programmable Interrupt Controller</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell">Access is never allowed*</p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0x0C0 0x0DF</p>
								</td>
								<td>
										<p class="lastInCell">ISA DMA</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
						<tr class="record" valign="top">
								<td>
										<p class="lastInCell">0x4D0 0x4D1</p>
								</td>
								<td>
										<p class="lastInCell">PIC Edge/Level Control Registers</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell">Access is never allowed*</p>
								</td>
						</tr>
						<tr class="evenRecord" valign="top">
								<td>
										<p class="lastInCell">0xCF8 0xD00</p>
								</td>
								<td>
										<p class="lastInCell">PCI Configuration Space Access</p>
								</td>
								<td style="BORDER-RIGHT: #cccccc 1px solid">
										<p class="lastInCell"> </p>
								</td>
						</tr>
				</tbody>
		</table>
		<div class="dataTableBottomMargin">
		</div>
		<p>*Read or write accesses to these ports are always blocked, regardless of the BIOS use of the _OSI method.</p>
		<a name="EUH">
		</a>
		<h2>Call to Action </h2>
		<p>
		</p>
		<p>BIOS developers should design their BIOS code according to the guidelines in this article: </p>
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>BIOS code that is compatible with Windows XP should access system resources as described in this article; they should not directly read from or write to any of the I/O port addresses listed in Table 1.</p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>BIOS code that is compatible with earlier versions of Windows released before Windows XP should not directly access the PIC and cascaded PIC, or PIC Edge/Level Control Registers.</p>
								</td>
						</tr>
						<tr>
								<td class="listBullet" valign="top">•</td>
								<td class="listItem">
										<p>BIOS code should report compatibility with Windows XP as described in <a href="http://www.microsoft.com/taiwan/whdc/system/pnppwr/powermgmt/_OSI-method.mspx">How to Identify Windows Versions in ACPI Using _OSI</a>.</p>
								</td>
						</tr>
				</tbody>
		</table><img src ="http://www.cnitblog.com/yuhensong/aggbug/63509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2009-12-31 14:54 <a href="http://www.cnitblog.com/yuhensong/archive/2009/12/31/63509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>64-bit EFI和SMM</title><link>http://www.cnitblog.com/yuhensong/archive/2009/11/09/62491.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Mon, 09 Nov 2009 10:26:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2009/11/09/62491.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/62491.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2009/11/09/62491.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/62491.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/62491.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果EFI支持64-bit的话，那么就可以启动Windows 7, 还不是因为MS不好好支持32-bit，这样就不需要CSM module了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么如果EFI支持64-bit的话，SMM driver也就变成64-bit了，这个时候SMM就必须从Real mode 转成64-bit protect mode，其实主要的问题就是CPU的mode是IA-32e mode，这是由CPU的一个寄存器来决定的，具体的就是MSR（C0000080h）的bit8，所以在SMI handler中就需要load 64-bit的GDT，然后切成保护模式之前，设置CPU的这个寄存器，使之变成64-bit，其他的和32-bit的一模一样，就可以去执行64-bit的C程序了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 需要强调的是，64-bit汇编code中，eax就用rax了，等等。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 贴一张图吧，说明一下CPU的不同模式：<br><img style="WIDTH: 911px; HEIGHT: 616px" height=616 src="http://www.cnitblog.com/images/cnitblog_com/yuhensong/mode.JPG" width=911 border=0></p><img src ="http://www.cnitblog.com/yuhensong/aggbug/62491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2009-11-09 18:26 <a href="http://www.cnitblog.com/yuhensong/archive/2009/11/09/62491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于ACPI table的基本概念和图示</title><link>http://www.cnitblog.com/yuhensong/archive/2009/10/21/62042.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Wed, 21 Oct 2009 08:04:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2009/10/21/62042.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/62042.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2009/10/21/62042.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/62042.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/62042.html</trackback:ping><description><![CDATA[&nbsp;
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ACPI Table</span><span>是</span><span>BIOS</span><span>提供给</span><span>OSPM</span><span>的硬件配置数据，包括系统硬件的电源管理和配置管理，</span><span>ACPI Table</span><span>有很多表，根据存储的位置，可以分为：</span></p>
<p><span><span>1）&nbsp;</span></span><span>RSDP</span><span>位于</span><span>F</span><span>段，用于</span><span>OSPM</span><span>搜索</span><span>ACPI Table</span><span>，</span><span>RSDP</span><span>可以定位其他所有</span><span>ACPI Table</span></p>
<p><span><span>2）&nbsp;</span></span><span>FACS</span><span>位于</span><span>ACPI NVS</span><span>内存，用于系统进行</span><span>S3</span><span>保存的恢复指针，内存为</span><span>NV Store</span></p>
<p><span><span>3）&nbsp;</span></span><span>剩下所有</span><span>ACPI Table</span><span>都位于</span><span>ACPI Reclaim</span><span>内存，进入</span><span>OS</span><span>后，内存可以释放</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ACPI Table</span><span>根据版本又分为</span><span>1.0B</span><span>，</span><span>2.0</span><span>，</span><span>3.0，4.0</span><span>。</span><span>2.0</span><span>以后，支持了</span><span>64-bit</span><span>的地址空间，因此几个重要的</span><span>Table</span><span>会不大一样，比如：</span><span>RSDP</span><span>，</span><span>RSDT</span><span>，</span><span>FADT</span><span>，</span><span>FACS</span><span>。简单的列举一下不同版本的</span><span>ACPI Table</span><span>：</span></p>
<p><span><span>1）&nbsp;</span></span><span>ACPI 1.0B</span><span>：</span><span>RSDP1</span><span>，</span><span>RSDT</span><span>，</span><span>FADT1</span><span>，</span><span>FACS1</span><span>，</span><span>DSDT</span><span>，</span><span>MADT</span><span>，</span><span>SSDT</span><span>，</span><span>HPET</span><span>，</span><span>MCFG</span><span>等</span></p>
<p><span><span>2）&nbsp;</span></span><span>ACPI 3.0 </span><span>：</span><span>RSDP3</span><span>，</span><span>RSDT</span><span>，</span><span>XSDT</span><span>，</span><span>FADT3</span><span>，</span><span>FACS3</span><span>，</span><span>DSDT</span><span>，</span><span>MADT</span><span>，</span><span>HPET</span><span>，</span><span>MCFG</span><span>，</span><span>SSDT</span><span>等</span></p>
<p><span>以系统支持</span><span>ACPI3.0</span><span>为例子，说明系统中</span><span>ACPI table</span><span>之间的关系如图：<br></span></p>
<p>&nbsp;</p>
<p><img style="WIDTH: 556px; HEIGHT: 363px" height=363 src="http://www.cnitblog.com/images/cnitblog_com/yuhensong/acpitable.JPG" width=556 border=0>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;<span>其中绿色代表在内存</span><span>F</span><span>段，蓝色是</span><span>ACPI Reclaim</span><span>内存，红色是</span><span>NV store</span><span>内存</span></p>
<span><br clear=all></span>
<p>&nbsp;</p><img src ="http://www.cnitblog.com/yuhensong/aggbug/62042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2009-10-21 16:04 <a href="http://www.cnitblog.com/yuhensong/archive/2009/10/21/62042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C语言中+和|的区别 （原创）</title><link>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58700.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Fri, 22 May 2009 05:18:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58700.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/58700.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58700.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/58700.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/58700.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 当我们在coding的时候，使用两个变量相加的情况，或者用 +，或者用 | ，都是没有问题，比如：<br>&nbsp;&nbsp;&nbsp; 0x1000 + 0x55 = 0x1055<br>&nbsp;&nbsp;&nbsp; 0x1000 | 0x55&nbsp;&nbsp;= 0x1055<br>&nbsp;&nbsp;&nbsp; 介于以前这种固有的思维，因此没有把其中不同仔细考虑，直到这几天的bug，才恍然大悟，还是因为基础知识的不扎实和习惯性的思维导致这个bug，不过也给我了一个机会，彻底的搞清楚这两个运算符在变量相加的时候的区别。<br>&nbsp;&nbsp;&nbsp; 因为code是这么定义的：<br>#define PCI_ADDR(bus,device,func,reg)&nbsp; (UINT64)(bus&lt;&lt;24 + device&lt;&lt;16 + func&lt;&lt;8 + reg ) &amp; 0x00000000FFFFFFFF<br>#define DRAM_PCI&nbsp;&nbsp;&nbsp; PCI_ADDR(0,0,3,0)<br>&nbsp;&nbsp;&nbsp;&nbsp;UINT64 Addr；<br>&nbsp;&nbsp;&nbsp;&nbsp;假如我要访问寄存器0x55<br>&nbsp;&nbsp;&nbsp; （1） Addr = DRAM_PCI + 0x55;<br>&nbsp;&nbsp;&nbsp;&nbsp;（2） Addr = DRAM_PCI&nbsp; | 0x55;<br>&nbsp;&nbsp;&nbsp;&nbsp; 那么请问（1）和（2）相等吗？ <br>&nbsp;&nbsp;&nbsp;&nbsp; 答案是： （1） Addr = 0；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（2） Addr = RealValue;<br><br>&nbsp;&nbsp;&nbsp;&nbsp; 那么为什么在（1）中，Addr = 0呢，问题还是出在PCI_ADDR这个宏定义上：<br>&nbsp;&nbsp;&nbsp;&nbsp; 因为宏定义最后做了一个与运算，所以在之后的运算中就需要和 + 或者 | 进行优先级的比较，由于+&nbsp; 》 &amp;&nbsp; 》 | ，因此当使用 | 的时候，就不会出现问题，能够和我们想要的运算一致；当使用 + 的时候，由于 + 比 &amp; 优先级高，因此就率先计算了 0x00000000FFFFFFFF + 0x55，导致得到了新值 0x0000000100000054，然后和之前的数值进行 &amp;， 不就得到了 0 嘛<br>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">所以得到的经验教训：<br></span>&nbsp;&nbsp;&nbsp;&nbsp; 1）在复杂的定义面前不能想当然的去使用自己认为没有问题的运算符，因为检查这个问题可不是这么容易找到根源的。<br>&nbsp;&nbsp;&nbsp;&nbsp; 2）在进行宏定义的时候最好给整个宏加上括号，那么就可以避免很多优先级的问题，因为调用这个宏的人可能多种多样。<br>&nbsp;&nbsp;&nbsp;&nbsp; 3）尽可能的使用最简单的运算符进行coding，可以避免一些问题，当然如果反复调用的情况下，还是需要定义宏，当然定义要慎重，参考2）<br>&nbsp;&nbsp;&nbsp;&nbsp; 4）基础很重要啊，要能快速的找到问题的根源还是需要熟悉各种运算符的优先级，这次又好好的复习了一下。<br><br><span style="COLOR: red">顺便附上C语言中常用运算符的优先级：</span><br>1 () [] -&gt; .&nbsp;&nbsp; ::&nbsp; ! ~ ++ -- <br>2 - (unary) * (dereference)&nbsp; &amp; (address of) sizeof <br>3 -&gt;* .* <br>4 * (multiply) / % <br>5 + - <br>6 &lt;&lt; &gt;&gt; <br>7 &lt; &lt;= &gt; &gt;= <br>8 == != <br>9 &amp; (bitwise AND) <br>10 ^ <br>11 | <br>12 &amp;&amp; <br>13 || <br>14 ? : <br>15 = += -= etc. <br>16 , <br></p><img src ="http://www.cnitblog.com/yuhensong/aggbug/58700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2009-05-22 13:18 <a href="http://www.cnitblog.com/yuhensong/archive/2009/05/22/58700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让我很是惭愧啊</title><link>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58690.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Fri, 22 May 2009 01:56:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58690.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/58690.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2009/05/22/58690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/58690.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/58690.html</trackback:ping><description><![CDATA[一些网上朋友看到了我的这个blog，说是做的不错，汗！<br>不过已经很久不更新进来的心得了<br>看来需要努力了，不能辜负来看这个blog的希望啊<br>近期跟新之<img src ="http://www.cnitblog.com/yuhensong/aggbug/58690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2009-05-22 09:56 <a href="http://www.cnitblog.com/yuhensong/archive/2009/05/22/58690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Standby Suspend Sleep and Hibernate</title><link>http://www.cnitblog.com/yuhensong/archive/2008/06/18/45849.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Wed, 18 Jun 2008 06:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2008/06/18/45849.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/45849.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2008/06/18/45849.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/45849.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/45849.html</trackback:ping><description><![CDATA[<div>USER ISSUE<br>What is the difference between sleep, standby, suspend, and hibernate?</div>
<div>GENERAL INFORMATION<br>&nbsp; Computers typically offer various power saving modes. The names for these modes will be something like standby, suspend, sleep, and hibernate. Typically the standby, suspend and sleep modes require that the computer be left on to some degree, and that it <font color=#ff0000>stay connected to power</font> (battery or AC). While in these modes, the hard drive usually stops running, the display turns off, and the fans might even turn off. However, the computer is still keeping in <font color=#ff0000>active memory </font>everything that was running and open just prior to being put in a low power mode. The hibernate mode allows you to turn off the computer completely and even unplug it from power. When it turns back on, the screen should show you exactly what you were were working on just prior to putting it in hibernate mode.</div>
<div>&nbsp;&nbsp; Because standby, suspend and sleep modes keep all the information <font color=#ff0000>in memory</font>, it is typically <font color=#ff0000>quicker</font> to start working again after being in these modes. Resuming work from the hibernate mode typically takes more time because it requires starting up the computer and loading everything <font color=#ff0000>into memory from the hard drive </font>again (although you don't need to manually start the programs and load the files because the computer will restore everything to the state it was in previously).</div>
<div>&nbsp;&nbsp; Depending on the computer and configuration, some cleanup tasks may be performed at system startup and shut down. So, some people prefer to simply shut down a computer when the are done using it. Some people suggest that it is best to leave computers on. However, if we consider the computer to be like any other appliance, then it makes sense to simply turn it off when it is not in use just as we would with a television set, dish washer, microwave, coffee pot, or any other appliance.</div>
<div><font color=#333399>休眠功能的特点 </font></div>
<div>与普通开机过程比较，休眠状态有以下的特点： <br>　　1.可以随时进入休眠状态，无须将所有工作储存起来，并关闭一个又一个的应用软件。因为休眠所保存的是当前的&#8220;状态&#8221;，所有打开的程序、设置及窗口排列等都不会改变。 <br>　　2.开机和关机的过程很快，相对正常关机和开机，休眠到硬盘（STD）至唤醒所需的时间可以快20%以上，而休眠到内存（STR）的关机和开机过程只需5秒钟。 <br>　　3.对笔记本电脑来说，当电池即将耗尽而又不能得到外接电源补给的时候，迅速进入休眠状态是保证当前工作不会丢失的唯一自保方法。 </div>
<div><font color=#333399>休眠功能的分类</font> </div>
<div>&nbsp;　　台式电脑和笔记本电脑的休眠模式也各有特色，一般而言后者的休眠方式比较全面和复杂。但总体来说都可分为STD和STR方式，而后者又细分成S1、S3及S1&amp;&amp;S3模式。 <br>（一）ＳＴＤ模式（Ｓｕｓｐｅｎｄ ｔｏ Ｄｉｓｋ，休眠到磁盘） <br>　　STD的特点是将电脑内存中的状态复制到硬盘，因为内存中的资料就是电脑当前状态的写照，所以保存这些资料就完整保留了电脑中的状态。STD在Windows中称为&#8220;Hibernate&#8221;（休眠），要在控制面板的电源管理中进行设置（开始&#8594;设置&#8594;控制面板&#8594;电源管理&#8594;休眠&#8594;启用休眠功能）。其特点是会在硬盘中永久占用空间作为保存内存资料之用。很明显，内存容量有多大，需要占用的硬盘空间就有多大。 <br>　　看到这里，大家一定会联想到，在STD状态下，电脑内存容量越大，进入休眠和唤醒的过程也就越慢。当然，对于内存中没有资料的部分，硬盘也不会全部读写，所以时间比完全读写要快一些，但总的来说速度仍然较慢。 <br>　　不过STD也有优点，就是当资料复制到硬盘后，即使电源完全中断，资料也不会丢失。因此对笔记本电脑来说，STD是最好的选择。 <br>（二）ＳＴＲ模式：（Ｓｕｓｐｅｎｄ ｔｏ ＲＡＭ，休眠到内存） <br>　　STR是在进入休眠状态时，只保留内存和主板芯片组的供电，而关闭其他部分。由于所有资料本来就在内存中，因此速度之快超乎想像。无论是台式电脑或笔记本电脑都可以利用此方式作休眠，它在Windows中被称为&#8220;Suspend&#8221;。 <br>　　其中Suspend状态又可分为S1与S3。S1模式的休眠程度较浅，当休眠时，硬盘、处理器和其他设备都会停止工作，但处理器和显示卡的风扇仍然会运转，机箱电源也仍然在工作。因此S1的省电程度较低，但进入和唤醒速度最快，兼容性也比较好(我的机器就是这个，suspend以后机箱里还有风扇的声音并且洞口有风进入说明电源风扇还在转)。而S3就仿佛彻底关机一样，除了电源指示灯会闪烁之外，所有风扇全部停转。此模式的耗电最少，速度也够快。笔记本电脑通常都以此模式运作，达到最省电和无噪音的效果。而台式电脑采用此模式后，基本上无须关机，不用电脑的时候直接在关机菜单中选择&#8220;Standby&#8221;就行了。 <br>　　STR的缺点就是很容易因为第三方驱动程序的兼容性问题使得系统无法正常进入Suspend状态。此外，如果主板BIOS对ACPI的支持不完善，也会使STR功能无法使用。其中S3模式出现问题的几率比S1模式多，因此很多主板都具备S1&amp;&amp;S3模式，并可让操作系统自动选择。但另外一个重要的前提就是机箱电源的+5V Standby插头必须能输出750mA以上电流，否则计算机将&#8220;长眠不醒&#8221;。</div>
<div>　　绝大多数笔记本电脑同时支持多种电源管理模式，通常当用户在Windows中选择&#8220;Standby&#8221;或者按下电源开关，就会进入Suspend状态。而当用户合上屏幕，则会进入Hibernate状态。当然，不管使用哪种模式，即使电脑不进入休眠或待机状态，我们都可以设置当某种设备闲置一定时间后就自动关闭，以便省电。 <br>　　只要大家充分了解和应用电脑的休眠功能，既能达到省电的目的，又可以让电脑在开机和关机时更加迅速，不是有一举两得的功效吗？ <br><br>缩写：<br>S1 or S3&nbsp;&nbsp;= standby&nbsp;&nbsp;&nbsp; = 待机&nbsp; = STR<br>S4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Hibernate&nbsp; = 休眠 = STD<br></div><img src ="http://www.cnitblog.com/yuhensong/aggbug/45849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2008-06-18 14:54 <a href="http://www.cnitblog.com/yuhensong/archive/2008/06/18/45849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>函数指针和指针函数的基本概念（ZZ）</title><link>http://www.cnitblog.com/yuhensong/archive/2008/06/13/45663.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Fri, 13 Jun 2008 07:12:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2008/06/13/45663.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/45663.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2008/06/13/45663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/45663.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/45663.html</trackback:ping><description><![CDATA[<p><font size=2><font color=#0000ff>【函数指针】</font><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在程序运行中，函数代码是程序的算法指令部分，它们和数组一样也占用存储空间，都有相应的地址。可以使用指针变量指向数组的首地址，也可以使用指针变量指向函数代码的首地址，指向函数代码首地址的指针变量称为函数指针。</font></p>
<p><font size=2>1．函数指针定义</font></p>
<p><font size=2>函数类型 （*指针变量名）(形参列表)；</font></p>
<p><font size=2>&#8220;函数类型&#8221;说明函数的返回类型，由于&#8220;()&#8221;的优先级高于&#8220;*&#8221;,所以指针变量名外的括号必不可少，后面的&#8220;形参列表&#8221;表示指针变量指向的函数所带的参数列表。</font></p>
<p><font size=2>例如：</font></p>
<p><font size=2>int (*f)(int x);</font></p>
<p><font size=2>double (*ptr)(double x);</font></p>
<p><font size=2>在定义函数指针时请注意：<br>&nbsp;&nbsp;&nbsp; <br>函数指针和它指向的函数的参数个数和类型都应该是—致的；</font></p>
<p><font size=2>函数指针的类型和函数的返回值类型也必须是一致的。</font></p>
<p><font size=2>2．函数指针的赋值</font></p>
<p><font size=2>函数名和数组名一样代表了函数代码的首地址，因此在赋值时，直接将函数指针指向函数名就行了。</font></p>
<p><font size=2>例如，</font></p>
<p><font size=2>int func(int x);&nbsp;&nbsp; /* 声明一个函数 */</font></p>
<p><font size=2>int (*f) (int x);&nbsp;&nbsp;&nbsp; /* 声明一个函数指针 */</font></p>
<p><font size=2>f=func;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 将func函数的首地址赋给指针f */</font></p>
<p><font size=2>赋值时函数func不带括号，也不带参数，由于func代表函数的首地址，因此经过赋值以后，指针f就指向函数func(x)的代码的首地址。</font></p>
<p><font size=2>3．通过函数指针调用函数</font></p>
<p><font size=2>函数指针是通过函数名及有关参数进行调用的。</font></p>
<p><font size=2>与其他指针变量相类似，如果指针变量pi是指向某整型变量i的指针，则*p等于它所指的变量i；如果pf是指向某浮点型变量f的指针，则*pf就等价于它所指的变量f。同样地，*f是指向函数func(x)的指针，则*f就代表它所指向的函数func。所以在执行了f=func;之后，(*f)和func代表同一函数。</font></p>
<p><font size=2>由于函数指针指向存储区中的某个函数，因此可以通过函数指针调用相应的函数。现在我们就讨论如何用函数指针调用函数，它应执行下面三步：</font></p>
<p><font size=2>首先，要说明函数指针变量。</font></p>
<p><font size=2>例如：int (*f)(int x);</font></p>
<p><font size=2>其次，要对函数指针变量赋值。</font></p>
<p><font size=2>例如： f=func;&nbsp;&nbsp;&nbsp; (func(x)必须先要有定义)</font></p>
<p><font size=2>最后，要用 (*指针变量)(参数表);调用函数。</font></p>
<p><font size=2>例如：&nbsp;&nbsp;&nbsp; (*f)(x);(x必须先赋值)</font></p>
<p><br><font size=2>【例】任意输入n个数，找出其中最大数，并且输出最大数值。</font></p>
<p><font size=2>main()</font></p>
<p><font size=2>{</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int f();</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i，a，b;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*p)();&nbsp;&nbsp;&nbsp; /* 定义函数指针 */</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d"，&amp;a);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p=f;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 给函数指针p赋值，使它指向函数f */</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i＝1;i&lt;9;i++)</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d"，&amp;b);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a＝(*p)(a，b);&nbsp;&nbsp;&nbsp; /* 通过指针p调用函数f */</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("The Max Number is:%d"，a)</font></p>
<p><font size=2>}</font></p>
<p><br><font size=2>f(int x，int y)</font></p>
<p><font size=2>{</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; int z;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; z＝(x&gt;y)?x:y;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; return(z);</font></p>
<p><font size=2>}</font></p>
<p><font size=2>运行结果为：</font></p>
<p><font size=2>343 -45 4389 4235 1 -534 988 555 789↙</font></p>
<p><font size=2>The Max Number is：4389</font></p>
<p><br><font color=#0000ff size=2>【指针函数】</font></p>
<p><font size=2>一个函数不仅可以带回一个整型数据的值，字符类型值和实型类型的值，还可以带回指针类型的数据，使其指向某个地址单元。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回指针的函数，一般定义格式为：</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类型标识符&nbsp;&nbsp;&nbsp; *函数名(参数表)</font></p>
<p><font size=2>int *f(x，y);</font></p>
<p><font size=2>其中x，y是形式参数，f是函数名，调用后返回一个指向整型数据的地址指针。f(x，y)是函数，其值是指针。</font></p>
<p><font size=2>如：char *ch();表示的就是一个返回字符型指针的函数，请看下面的例题：</font></p>
<p><font size=2>【例】将字符串1(str1)复制到字符串2(str2)，并输出字符串2.</font></p>
<p><font size=2>#include "stdio.h"</font></p>
<p><font size=2>main()</font></p>
<p><font size=2>{</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; char *ch(char *，char *);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; char str1[]="I am glad to meet you!";</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; char str2[]="Welcom to study C!";</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; printf("%s"，ch(str1，str2));</font></p>
<p><font size=2>}</font></p>
<p><font size=2>char *ch(char *str1，char *str2)</font></p>
<p><font size=2>{</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; int i;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; char *p;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; p=str2<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(*str2==NULL) exit(-1);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; do</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; { </font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *str2=*str1;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str1++;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str2++;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; }while(*str1!=NULL);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; return(p);</font></p>
<p><font size=2>}</font></p>
<p><br><font size=2>通过分析可得</font></p>
<p><font size=2>函数指针是一个指向函数的指针，而指针函数只是说明他是一个返回值为指针的函数，</font></p>
<p><font size=2>函数指针可以用来指向一个函数。<br></font></p><img src ="http://www.cnitblog.com/yuhensong/aggbug/45663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2008-06-13 15:12 <a href="http://www.cnitblog.com/yuhensong/archive/2008/06/13/45663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>好久没来这里了</title><link>http://www.cnitblog.com/yuhensong/archive/2008/04/22/42616.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Tue, 22 Apr 2008 08:06:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2008/04/22/42616.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/42616.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2008/04/22/42616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/42616.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/42616.html</trackback:ping><description><![CDATA[最近杂事比较多，没有时间更新<br><br>现在手头主要做ACPI了，不过SMM也没有丢<br><br>希望两手都要抓，两手都要硬，呵呵<br><img src ="http://www.cnitblog.com/yuhensong/aggbug/42616.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2008-04-22 16:06 <a href="http://www.cnitblog.com/yuhensong/archive/2008/04/22/42616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>准备安装无数操作系统</title><link>http://www.cnitblog.com/yuhensong/archive/2007/11/12/36175.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Mon, 12 Nov 2007 07:24:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2007/11/12/36175.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/36175.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2007/11/12/36175.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/36175.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/36175.html</trackback:ping><description><![CDATA[有个160G的工作盘，因为工作可能需要很多OS，今天决定重装OS，具体的要安装下面的OS：<br>100M&nbsp;&nbsp; DOS<br>10G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XP1<br>10G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Redflag<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XP2<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XP3<br>20G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VISTA<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fedora<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ubuntu<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandriva<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Linux later<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Linux later<br>5G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Linux later<br>2G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Swap<br>10G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Work<br>20G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Others<br>20G&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bak<br>100M&nbsp;&nbsp; EFI<br><br>如此可以我的无敌OS盘硬盘就诞生了！<br><img src ="http://www.cnitblog.com/yuhensong/aggbug/36175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2007-11-12 15:24 <a href="http://www.cnitblog.com/yuhensong/archive/2007/11/12/36175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BDA - BIOS Data Area - PC Memory Map[ZZ]</title><link>http://www.cnitblog.com/yuhensong/archive/2007/10/25/35322.html</link><dc:creator>yuhen</dc:creator><author>yuhen</author><pubDate>Thu, 25 Oct 2007 07:38:00 GMT</pubDate><guid>http://www.cnitblog.com/yuhensong/archive/2007/10/25/35322.html</guid><wfw:comment>http://www.cnitblog.com/yuhensong/comments/35322.html</wfw:comment><comments>http://www.cnitblog.com/yuhensong/archive/2007/10/25/35322.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnitblog.com/yuhensong/comments/commentRss/35322.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yuhensong/services/trackbacks/35322.html</trackback:ping><description><![CDATA[<pre>	Address Size	   Description
00:00 256dwords Interrupt vector table
30:00 256bytes	Stack area used during post and bootstrap
40:00	word	COM1 port address
40:02	word	COM2 port address
40:04	word	COM3 port address
40:06	word	COM4 port address
40:08	word	LPT1 port address
40:0A	word	LPT2 port address
40:0C	word	LPT3 port address
40:0E	word	LPT4 port address (except PS/2)
Extended BIOS Data Area segment (PS/2, see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/ebda.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/ebda.html"><font color=#a70002>EBDA</font></a>)
40:10  2 bytes	Equipment list flags (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int11.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int11.html"><font color=#a70002>INT 11</font></a>)
|7|6|5|4|3|2|1|0| 40:10 (value in INT 11 register AL)
| | | | | | | `- IPL diskette installed
| | | | | | `-- math coprocessor
| | | | |-+-- old PC system board RAM &lt; 256K
| | | | | `-- pointing device installed (PS/2)
| | | | `--- not used on PS/2
| | `------ initial video mode
`--------- # of diskette drives, less 1
|7|6|5|4|3|2|1|0| 40:11  (value in INT 11 register AH)
| | | | | | | `- 0 if DMA installed
| | | | `------ number of serial ports
| | | `------- game adapter
| | `-------- not used, internal modem (PS/2)
`----------- number of printer ports
40:12	byte	PCjr: infrared keyboard link error count
40:13	word	Memory size in Kbytes  (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int12.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int12.html"><font color=#a70002>INT 12</font></a>)
40:15	byte	Reserved
40:16	byte	PS/2 BIOS control flags
40:17	byte	Keyboard flag byte 0 (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/kbflags.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/kbflags.html"><font color=#a70002>KB FLAGS</font></a>)
|7|6|5|4|3|2|1|0| keyboard flag byte 0
| | | | | | | `--- right shift key depressed
| | | | | | `---- left shift key depressed
| | | | | `----- CTRL key depressed
| | | | `------ ALT key depressed
| | | `------- scroll-lock is active
| | `-------- num-lock is active
| `--------- caps-lock is active
`---------- insert is active
40:18	byte	Keyboard flag byte 1 (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/kbflags.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/kbflags.html"><font color=#a70002>KB FLAGS</font></a>)
|7|6|5|4|3|2|1|0| keyboard flag byte
| | | | | | | `--- left CTRL key depressed
| | | | | | `---- left ALT key depressed
| | | | | `----- system key depressed and held
| | | | `------ suspend key has been toggled
| | | `------- scroll lock key is depressed
| | `-------- num-lock key is depressed
| `--------- caps-lock key is depressed
`---------- insert key is depressed
40:19	byte	Storage for alternate keypad entry
40:1A	word	Offset from 40:00 to keyboard buffer head
40:1C	word	Offset from 40:00 to keyboard buffer tail
40:1E  32bytes	Keyboard buffer (circular queue buffer)
40:3E	byte	Drive recalibration status
|7|6|5|4|3|2|1|0| drive recalibration status
| | | | | | | `-- 1=recalibrate drive 0
| | | | | | `--- 1=recalibrate drive 1
| | | | | `---- 1=recalibrate drive 2
| | | | `----- 1=recalibrate drive 3
| `---------- unused
`----------- 1=working interrupt flag
40:3F	byte	Diskette motor status
|7|6|5|4|3|2|1|0| diskette motor status
| | | | | | | `-- 1=drive 0 motor on
| | | | | | `--- 1=drive 1 motor on
| | | | | `---- 1=drive 2 motor on
| | | | `----- 1=drive 3 motor on
| `---------- unused
`----------- 1=write operation
40:40	byte	Motor shutoff counter (decremented by <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int8.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int8.html"><font color=#a70002>INT 8</font></a>)
40:41	byte	Status of last diskette operation (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int13-1.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int13-1.html"><font color=#a70002>INT 13,1</font></a>)
|7|6|5|4|3|2|1|0| status of last diskette operation
| | | | | | | `--- invalid diskette command
| | | | | | `---- diskette address mark not found
| | | | | `----- sector not found
| | | | `------ diskette DMA error
| | | `------- CRC check / data error
| | `-------- diskette controller failure
| `--------- seek to track failed
`---------- diskette time-out
40:42  7 bytes	NEC diskette controller status (see <a href="http://quby.bokee.com/java%20script:if(confirm('http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/765.html%20%20/n/nThis%20file%20was%20not%20retrieved%20by%20Teleport%20Pro,%20because%20the%20server%20reports%20that%20this%20file%20cannot%20be%20found.%20%20/n/nDo%20you%20want%20to%20open%20it%20from%20the%20server?'))window.location='http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/765.html'" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/765.html"><font color=#a70002>FDC</font></a>)
40:49	byte	Current video mode  (see VIDEO MODE)
40:4A	word	Number of screen columns
40:4C	word	Size of current video regen buffer in bytes
40:4E	word	Offset of current video page in video regen buffer
40:50  8 words	Cursor position of pages 1-8, high order byte=row
low order byte=column; changing this data isn't
reflected immediately on the display
40:60	byte	Cursor ending (bottom) scan line (don't modify)
40:61	byte	Cursor starting (top) scan line (don't modify)
40:62	byte	Active display page number
40:63	word	Base port address for active <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/6845.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/6845.html"><font color=#a70002>6845</font></a> CRT controller
3B4h = mono, 3D4h = color
40:65	byte	6845 CRT mode control register value (port 3x8h)
EGA/VGA values emulate those of the MDA/CGA
40:66	byte	CGA current color palette mask setting (port 3d9h)
EGA and VGA values emulate the CGA
40:67	dword	CS:IP for 286 return from protected mode
dword	Temp storage for SS:SP during shutdown
dword	Day counter on all products after AT
dword	PS/2 Pointer to reset code with memory preserved
5 bytes	Cassette tape control (before AT)
40:6C	dword	Daily timer counter, equal to zero at midnight;
incremented by INT 8; read/set by <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int1a.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int1a.html"><font color=#a70002>INT 1A</font></a>
40:70	byte	Clock rollover flag, set when 40:6C exceeds 24hrs
40:71	byte	BIOS break flag, bit 7 is set if <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int1b.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int1b.html"><font color=#a70002>Ctrl-Break</font></a> was
*ever* hit; set by <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int9.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int9.html"><font color=#a70002>INT 9</font></a>
40:72	word	Soft reset flag via Ctl-Alt-Del or JMP FFFF:0
1234h  Bypass memory tests &amp; CRT initialization
4321h  Preserve memory
5678h  System suspend
9ABCh  Manufacturer test
ABCDh  Convertible POST loop
????h  many other values are used during POST
40:74	byte	Status of last hard disk operation (see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int13-1.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int13-1.html"><font color=#a70002>INT 13,1</font></a>)
40:75	byte	Number of hard disks attached
40:76	byte	XT fixed disk drive control byte
40:77	byte	Port offset to current fixed disk adapter
40:78  4 bytes	Time-Out value for LPT1,LPT2,LPT3(,LPT4 except PS/2)
40:7C  4 bytes	Time-Out value for COM1,COM2,COM3,COM4
40:80	word	Keyboard buffer start offset (seg=40h,BIOS 10-27-82)
40:82	word	Keyboard buffer end offset (seg=40h,BIOS 10-27-82)
40:84	byte	Rows on the screen (less 1, EGA)
40:85	word	Point height of character matrix (EGA)
byte	PCjr: character to be repeated if the typematic
repeat key takes effect
40:86	byte	PCjr: initial delay before repeat key action begins
40:87	byte	PCjr: current Fn function key number
byte	Video mode options (EGA)
|7|6|5|4|3|2|1|0| Video mode options (EGA)
| | | | | | | `-- 1=alphanumeric cursor emulation enabled
| | | | | | `--- 1=video subsystem attached to monochrome
| | | | | `---- reserved
| | | | `----- 1=video subsystem is inactive
| | | `------ reserved
| `--------- video RAM  00-64K  10-192K  01-128K  11-256K
`---------- video mode number passed to <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int10.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int10.html"><font color=#a70002>INT 10</font></a>, function 0
40:88	byte	PCjr: third keyboard status byte
EGA feature bit switches, emulated on VGA
|7|6|5|4|3|2|1|0| EGA feature bit switches (EGA)
| | | | | | | `-- EGA SW1 config (1=off)
| | | | | | `--- EGA SW2 config (1=off)
| | | | | `---- EGA SW3 config (1=off)
| | | | `----- EGA SW4 config (1=off)
| | | `------ Input FEAT0 (ISR0 bit 5) after output on FCR0
| | `------- Input FEAT0 (ISR0 bit 6) after output on FCR0
| `-------- Input FEAT1 (ISR0 bit 5) after output on FCR1
`--------- Input FEAT1 (ISR0 bit 6) after output on FCR1
40:89	byte	Video display data area (MCGA and VGA)
|7|6|5|4|3|2|1|0| Video display data area (MCGA and VGA)
| | | | | | | `-- 1=VGA is active
| | | | | | `--- 1=gray scale is enabled
| | | | | `---- 1=using monochrome monitor
| | | | `----- 1=default palette loading is disabled
| | | `------ see table below
| | `------- reserved
| `--------  1=display switching enabled
`--------- alphanumeric scan lines (see table below)
Bit7    Bit4	Scan Lines
0	0	350 line mode
0	1	400 line mode
1	0	200 line mode
1	1	reserved
40:8A	byte	Display Combination Code (DCC) table index (EGA)
40:8B	byte	Last diskette data rate selected
|7|6|5|4|3|2|1|0| last diskette data rate selected
| | | | `--------- reserved
| | `------------ last floppy drive step rate selected
`-------------- last floppy data rate selected
Data Rate 			Step Rate
00  500K bps		00  step rate time of 0C
01  300K bps		01  step rate time of 0D
10  250K bps		10  step rate time of 0A
11  reserved		11  reserved
40:8C	byte	Hard disk status returned by controller
40:8D	byte	Hard disk error returned by controller
40:8E	byte	Hard disk interrupt control flag(bit 7=working int)
40:8F	byte	Combination hard/floppy disk card when bit 0 set
40:90  4 bytes	Drive 0,1,2,3 media state
|7|6|5|4|3|2|1|0| drive media state (4 copies)
| | | | | `------- drive/media state (see below)
| | | | `------- reserved
| | | `------- 1=media/drive established
| | `------- double stepping required
`--------- data rate:	00=500K bps    01=300K bps
10=250K bps    11=reserved
Bits
210  Drive Media State
000  360Kb diskette/360Kb drive not established
001  360Kb diskette/1.2Mb drive not established
010  1.2Mb diskette/1.2Mb drive not established
011  360Kb diskette/360Kb drive established
100  360Kb diskette/1.2Mb drive established
101  1.2Mb diskette/1.2Mb drive established
110  Reserved
111  None of the above
40:94	byte	Track currently seeked to on drive 0
40:95	byte	Track currently seeked to on drive 1
40:96	byte	Keyboard mode/type
|7|6|5|4|3|2|1|0| Keyboard mode/type
| | | | | | | `--- last code was the E1 hidden code
| | | | | | `---- last code was the E0 hidden code
| | | | | `----- right CTRL key depressed
| | | | `------ right ALT key depressed
| | | `------- 101/102 enhanced keyboard installed
| | `-------- force num-lock if Rd ID &amp; KBX
| `--------- last char was first ID char
`---------- read ID in process
40:97	byte	Keyboard LED flags
|7|6|5|4|3|2|1|0| Keyboard LED flags
| | | | | | | `--- scroll lock indicator
| | | | | | `---- num-lock indicator
| | | | | `----- caps-lock indicator
| | | | `------ circus system indicator
| | | `------- ACK received
| | `-------- re-send received flag
| `--------- mode indicator update
`---------- keyboard transmit error flag
40:98	dword	Pointer to user wait complete flag
40:9C	dword	User wait Time-Out value in microseconds
40:A0	byte	RTC wait function flag
|7|6|5|4|3|2|1|0| <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int15-86.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int15-86.html"><font color=#a70002>INT 15,86</font></a> RTC wait function flag
| | | | | | | `--- 1= wait pending
| `-------------- not used
`--------------- 1=INT 15,86 wait time elapsed
40:A1	byte	LANA DMA channel flags
40:A2  2 bytes	Status of LANA 0,1
40:A4	dword	Saved hard disk interrupt vector
40:A8	dword	BIOS Video Save/Override Pointer Table address
(see <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/videoinformation.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/videoinformation.html"><font color=#a70002>VIDEO TABLES</font></a>)
40:AC  8 bytes	Reserved
40:B4	byte	Keyboard NMI control flags (convertible)
40:B5	dword	Keyboard break pending flags (convertible)
40:B9	byte	Port 60 single byte queue (convertible)
40:BA	byte	Scan code of last key (convertible)
40:BB	byte	NMI buffer head pointer (convertible)
40:BC	byte	NMI buffer tail pointer (convertible)
40:BD  16bytes	NMI scan code buffer (convertible)
40:CE	word	Day counter (convertible and after)
40:F0  16bytes	Intra-Applications Communications Area (IBM Technical
Reference incorrectly locates this at 50:F0-50:FF)
Address Size	   Description	 (BIOS/DOS Data Area)
50:00	byte	Print screen status byte
00 = PrtSc not active,
01 = PrtSc in progress
FF = error
50:01  3 bytes	Used by BASIC
50:04	byte	DOS single diskette mode flag, 0=A:, 1=B:
50:05  10bytes	POST work area
50:0F	byte	BASIC shell flag; set to 2 if current shell
50:10	word	BASICs default DS value (DEF SEG)
50:12	dword	Pointer to BASIC <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int1c.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int1c.html"><font color=#a70002>INT 1C</font></a> interrupt handler
50:16	dword	Pointer to BASIC <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int23.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int23.html"><font color=#a70002>INT 23</font></a> interrupt handler
50:1A	dword	Pointer to BASIC <a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int24.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int24.html"><font color=#a70002>INT 24</font></a> disk error handler
50:20	word	DOS dynamic storage
50:22  14bytes	DOS diskette initialization table (<a href="http://cs.uns.edu.ar/~jechaiz/organizacion/assembly/int1e.html" tppabs="http://www.iro.umontreal.ca/~feeley/cours/ift2240/doc/assembly/int1e.html"><font color=#a70002>INT 1E</font></a>)
50:30	4bytes	MODE command
70:00		I/O drivers from IO.SYS/IBMBIO.COM
</pre>
<h1 align=center>The following map varies in size and locus</h1>
<pre>	07C0:0		Boot code is loaded here at startup (31k mark)
A000:0		EGA/VGA RAM for graphics display mode 0Dh &amp; above
B000:0		MDA RAM, Hercules graphics display RAM
B800:0		CGA display RAM
C000:0		EGA/VGA BIOS ROM (thru C7FF)
C400:0		Video adapter ROM space
C600:0 256bytes PGA communication area
C800:0	 16K	Hard disk adapter BIOS ROM
C800:5		XT Hard disk ROM format, AH=Drive, AL=Interleave
D000:0	 32K	Cluster adapter BIOS ROM
D800:0		PCjr conventionalsoftware cartridge address
E000:0	 64K	Expansion ROM space (hardwired on AT)
128K	PS/2 System ROM (thru F000)
F000:0		System monitor ROM
PCjr: software cartridge override address
F400:0		System expansion ROMs
F600:0		IBM ROM BASIC (AT)
F800:0		PCjr software cartridge override address
FC00:0		BIOS ROM
FF00:0		System ROM
FFA6:E		ROM graphics character table
FFFF:0		ROM bootstrap code
FFFF:5 8 bytes	ROM date (not applicable for all clones)
FFFF:E	byte	ROM machine id	(see MACHINE ID)
</pre><img src ="http://www.cnitblog.com/yuhensong/aggbug/35322.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yuhensong/" target="_blank">yuhen</a> 2007-10-25 15:38 <a href="http://www.cnitblog.com/yuhensong/archive/2007/10/25/35322.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>