﻿
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[程序之美]]></title> 
<link>http://narmy.cn/linux/index.php</link> 
<description><![CDATA[__________高万龙的博客  博客已转移至http://narmy.cn/blog]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[程序之美]]></copyright>

<item>
<link>http://narmy.cn/linux/read.php/130.htm</link>
<title><![CDATA[《程序员的自我修养——链接、装载与库》勘误]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Wed, 19 May 2010 23:32:56 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/130.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: courier new;"><br/>《程序员的自我修养——链接、装载与库》<br/>2010年3月第5次印刷<br/>电子工业出版社<br/><br/>这本书确实不错，刚看完一遍，有很多收获。有一些自己觉得是错误的地方指出来，望对他人有用。<br/><br/><br/>1.&nbsp;&nbsp;P51.图2-8链接过程：<br/>原：Propressing 。<br/>应改为：Preprocessing<br/><br/>2．P60.第二段第二行：<br/>&nbsp;&nbsp;原：保存一份改程序的指令部分。<br/>应改为：保存一份该程序的指令部分。<br/><br/>3．P85.第六行：<br/>&nbsp;&nbsp;原：它被定义在.bss段，即下标为3。<br/>&nbsp;&nbsp;应改为：它被定义在.data段，即下标为3。<br/><br/>4．P104.第三段第三行：<br/>&nbsp;&nbsp;原：如第偏移为0x18的mov指令，<br/>&nbsp;&nbsp;应改为：如偏移为0x18的mov指令，<br/><br/>5．P134:第一段第一行：<br/>&nbsp;&nbsp;原：微软引入了一种叫PE(Protable Executable)的可执行格<br/>&nbsp;&nbsp;应改为：微软引入了一种叫PE(Portable Executable)的可执行格<br/><br/>6．P151:第四段第一行：<br/>&nbsp;&nbsp;原：从地址0xC00000000到<br/>&nbsp;&nbsp;应改为：从地址0xC0000000到<br/><br/>7．P154:第二段第一行：<br/>&nbsp;&nbsp;原：由于模块A和模块B之间相互调用依赖关系，<br/>&nbsp;&nbsp;应改为：由于模块A和模块B之间没有相互调用依赖关系，<br/><br/>8．P255:第二段第四行：<br/>&nbsp;&nbsp;原：我们在本书的第4章还会<br/>&nbsp;&nbsp;应改为：我们在本书的第4部分还会<br/><br/>9．P286:第三段第三行：<br/>&nbsp;&nbsp;原：先入栈的数据后出栈（First In Last Out, FIFO）,<br/>&nbsp;&nbsp;应改为：先入栈的数据后出栈（First In Last Out, FILO）,<br/><br/>10．P339:【小实验】第四段第一行：<br/>&nbsp;&nbsp;原：va_start将va_list定义的指针指向函数的最后一个参数后面的位置，<br/>&nbsp;&nbsp;应改为：va_start将va_list定义的指针指向函数的最后一个具名参数后面的位置，<br/><br/>11．P368:第三段代码最后大括号后面应该加分号。<br/><br/>12．P400:第三段命令行：<br/>&nbsp;&nbsp;原：$objdump –d –start-address=0xffffe400 –stop-address=0xffffe414&nbsp;&nbsp;linux-gate.dso<br/>&nbsp;&nbsp;应改为：$objdump –d –start-address=0xffffe400 –stop-address=0xffffe408&nbsp;&nbsp;linux-gate.dso<br/><br/><br/> 高万龙<br/>lengyuex@gmail.com<br/>2010/5/19<br/></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/125.htm</link>
<title><![CDATA[vim自己的IDE]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Sat, 01 May 2010 02:26:39 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/125.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: courier new;"><br/><br/><br/>生成tags文件、配置vi<br/>-------------------------------------------<br/>（1）进入源码所在目录：<br/># cd /usr/src/linux<br/>（2）生成针对源码的tags，因为ctags确省不把函数声明作为tag所以要加--c-types=+px（见注1）<br/># ctags -R --c-types=+px<br/>（3）在vi配置文件中加入生成的tags<br/># vi /etc/vim/vimrc<br/>set tags=/usr/src/linux/tags<br/><br/><br/><br/><br/>使用tag查找对象：<br/>-------------------------------------------<br/>ctags -R<br/>"-R"表示递归创建，也就包括源代码根目录下的所有子目录下的源程序。"tags"文件中包括这些对象的列表：<br/>(1)用#define定义的宏<br/>(2)枚举型变量的值<br/>(3)函数的定义、原型和声明<br/>(4)名字空间（namespace）<br/>(5)类型定义（typedefs）<br/>(6)变量（包括定义和声明）<br/>(7)类（class）、结构（struct）、枚举类型（enum）和联合（union）<br/>(8)类、结构和联合中成员变量或函数<br/><br/>vim用这个"tags"文件来定位上面这些做了标记的对象（见注1），下面介绍一下定位这些对象的方法：<br/><br/>1) 用命令行。在运行vim的时候加上"-t"参数，例如：<br/># vim -t foo_bar<br/>这个命令将打开定义"foo_bar"（变量或函数或其它）的文件，并把光标定位到这一行。<br/><br/>2) 在vim编辑器内用":ta"命令，例如：<br/>:ta foo_bar<br/><br/><br/>3) 最方便的方法是把光标移到变量名或函数名上，然后按下" Ctrl-]";用"Ctrl-o"退回原来的地方。用 Ctrl-]延着调用树向前跳转, 用Ctrl-t向回跳转<br/><br/>4) 分割窗口<br/>":tag"命令会将当前窗口的文件替换为包含新函数的文件。怎样才能同时查看两个文件呢？你可以使用 ":split"命令将窗口分开然后再用":tag"命令。vim 有个缩写命令可以做到这些：<br/>:stag tagname<br/>使用下面的命令可以分割当前窗口并跳转到光标下的标签:<br/>Ctrl-w-]<br/>如果指定了计数参数，新窗口将包含指定的那么多行。<br/><br/>5) 多个匹配<br/>当一个函数（或类中的方法）被定义多次， ":tags" 命令会跳转到第一处。如果在当前文件中存在匹配，那它将会被首先使用。 你现在可以跳转到同一个标签的其它匹配处：<br/>:tnext<br/>重复执行这个命令可以找到更多的匹配。如果存在很多匹配，你可以选择要跳转到哪一个：<br/>:tselect tagname<br/>vim 会为你展示一个选择列表：<br/># pri kind tag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file<br/>1 F&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;mch_init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os_amiga.c<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mch_init()<br/>2 F&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;mch_init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os_mac.c<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mch_init()<br/>3 F&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;mch_init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os_msdos.c<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mch_init(void)<br/>4 F&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;mch_init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os_riscos.c<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mch_init()<br/>Enter nr of choice (<CR> to abort):<br/>你现在可以输入要跳转到的匹配代号（在第一列）。其它列的信息可以让你知道匹配在何处被定义。<br/>以用这些命令在各匹配的标签间移动：<br/>:tfirst&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 到第一个匹配<br/>:[count]tprevious&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 向前 [count] 个匹配<br/>:[count]tnext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 向后 [count] 个匹配<br/>:tlast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;到最后一个匹配<br/>如果没有指定，[count] 省缺为一。<br/><br/>6) 猜测标签名<br/>命令行补全是避免输入长标签名的好办法。只需输入开始的一部分然后按 <Tab>：<br/>:tag write_<Tab><br/>你会得到第一个匹配。如果这不是你想要的，重复输入 <Tab> 直到你找到正确的匹配。<br/><br/>有时你只知道一个函数名的一部分，或是你有很多以相同字符串开头而结尾不同的标记。这时你可以告诉vim使用一个模式来查找标签。<br/>假设你要跳转到一个包含 "block" 的标签。首先输入：<br/>:tag /block<br/>现在再利用命令行补全功能：输入 <Tab>。vim 会找到所有包含 "block" 的标签并使用第一个匹配。<br/>标签名前面的 "/" 告诉vim这不是一个确定的标签名而是一个模式。你可以利用有关查找模式的所有特性。举个列子，假设你要选择所有以 "write_" 开头的标签：<br/>:tselect /^write_<br/>"^" 指定标签以 "write_" 开头，否则在中间含有 "write_" 的标签名也会被找到。类似地，"$" 指定标签名结尾处的匹配。<br/><br/>7) 预览窗口<br/>当编辑含有函数调用的代码时，你需要使用正确的调用参数。要获知所要传递的值，你可以查看这个函数是如何定义的。标签机制对此十分适用。如果定义可在另一个窗口内显示那就更好了。对此我们可以利用预览窗口。<br/>打开一个预览窗口来显示函数 "write_char"：<br/>:ptag write_char<br/>vim 会打开一个窗口，跳转到 "write_char" 标签。然后它会回到原来的位置。这样你可以继续输入而不必使用 CTRL-w w命令在两个分割窗口移动光标。<br/>如果函数名出现在文本中，你可以用下面的命令在预览窗口中得到其定义：<br/>Ctrl-w-]<br/>用下面的命令关闭预览窗口：<br/>:pclose<br/><br/>要在预览窗口中编辑一个指定的文件，用 ":pedit" 。这在编辑头文件时很有用，比如：<br/>:pedit defs.h<br/>最后， "psearch" 可用来查找当前文件和任何包含文件中的单词并在预览窗口中显示匹配。这在使用没有标签文件的库函数时十分有用。例如：<br/>:psearch popen<br/>这会在预览窗口中显示含有 popen() 原型的 "stdio.h" 文件：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;&nbsp;&nbsp;&nbsp;*popen __P((const char *, const char *));<br/>你可以用 'previewheight' 选项指定预览窗口打开时的高度。<br/><br/><br/><br/><br/><br/>注：<br/>-------------------------------------------<br/>（1）<br/>--<LANG>-kinds=[+&#124;-]kinds 或者<br/>--<LANG>-types=[+&#124;-]kinds<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;<LANG> is case-insensitive and is one of the built-in language names (see the --list-languages option for a complete list).<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;The specific sets of flags recognized for each language, their meanings and defaults may be list using the --list-kinds option.<br/><br/># ctags --list-kinds<br/>C<br/>&nbsp;&nbsp;&nbsp;&nbsp;c classes<br/>&nbsp;&nbsp;&nbsp;&nbsp;d macro definitions<br/>&nbsp;&nbsp;&nbsp;&nbsp;e enumerators (values inside an enumeration)<br/>&nbsp;&nbsp;&nbsp;&nbsp;f function definitions<br/>&nbsp;&nbsp;&nbsp;&nbsp;g enumeration names<br/>&nbsp;&nbsp;&nbsp;&nbsp;l local variables [off]<br/>&nbsp;&nbsp;&nbsp;&nbsp;m class, struct, and union members<br/>&nbsp;&nbsp;&nbsp;&nbsp;n namespaces<br/>&nbsp;&nbsp;&nbsp;&nbsp;p function prototypes [off]<br/>&nbsp;&nbsp;&nbsp;&nbsp;s structure names<br/>&nbsp;&nbsp;&nbsp;&nbsp;t typedefs<br/>&nbsp;&nbsp;&nbsp;&nbsp;u union names<br/>&nbsp;&nbsp;&nbsp;&nbsp;v variable definitions<br/>&nbsp;&nbsp;&nbsp;&nbsp;x external variable declarations [off]<br/>（2）<br/>--- 对 c++<br/>--- ctags -R --language-force=c++ --c++-types=+px --verbose --extra=+q<br/>--- extra=+q 用来增加生成 Class::member 的形式, 默认没有这样就可以用 :ts CView::OnDraw 这种形式看<br/>--- 因为c++一些头文件不用.h所以要用--language-force<br/><br/>--- 对 java<br/>--- ctags -R --languages=java c:/jdk131/src<br/>--- 要把src.jar展开<br/><br/><br/>2.整好了ctags，一切都好办了。<br/><br/>再加上根据建立的tags的自动补全，一切都很完美。<br/>OmniCppComplete : C/C++ omni-completion with ctags database <br/><br/><a href="http://www.vim.org/scripts/script.php?script_id=1520" target="_blank">http://www.vim.org/scripts/script.php?script_id=1520</a><br/><br/>SuperTab : Do all your insert-mode completion with Tab!<br/><a href="http://www.vim.org/scripts/script.php?script_id=182" target="_blank">http://www.vim.org/scripts/script.php?script_id=182</a><br/><br/>再加一个taglist:<br/><br/>taglist.vim : Source code browser (supports C/C++, java, perl, python, tcl, sql, php, etc) <br/><a href="http://www.vim.org/scripts/script.php?script_id=273" target="_blank">http://www.vim.org/scripts/script.php?script_id=273</a><br/><a href="http://narmy.cn/linux/attachment.php?fid=33" target="_blank"><img src="http://narmy.cn/linux/attachment.php?fid=33" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><div class="code"><br/>let c_hi_identifiers = &#039;all&#039;<br/>let c_hi_libs = &#91;&#039;*&#039;&#93;<br/>let g:ctags_statusline = 1<br/><br/>syntax enable<br/>syntax on<br/>set nocp<br/>filetype plugin on<br/>set tags+=/path/to/tags<br/><br/>let generate_tags = 1<br/><br/>set noai&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;习惯关闭自动缩进<br/></div><br/></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/124.htm</link>
<title><![CDATA[makefile 手册摘要]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Tue, 27 Apr 2010 01:52:46 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/124.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: courier new;"><br/><br/><br/><span style="font-size: 24px;"><span style="color: red;">GUN make的执行过程分为两个阶段。</span></span><br/>第一阶段：读取所有的makefile文件（包括“MAKIFILES”变量指定的、指示符“include”指定的、以及命令行选项“-f(--file)”指定的makefile文件），内建所有的变量、明确规则和隐含规则，并建立所有目标和依赖之间的依赖关系结构链表。<br/>在第二阶段：根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新，并使用对应的规则来重建这些目标。<br/><br/><span style="font-size: 24px;"><span style="color: red;">make的执行过程如下：</span></span><br/>1. 依次读取变量“MAKEFILES”定义的makefile文件列表<br/>2. 读取工作目录下的makefile文件（根据命名的查找顺序“GNUmakefile”，“makefile”，“Makefile”，首先找到那个就读取那个）<br/>3. 依次读取工作目录makefile文件中使用指示符“include”包含的文件<br/>4. 查找重建所有已读取的makefile文件的规则（如果存在一个目标是当前读取的某一个makefile文件，则执行此规则重建此makefile文件，完成以后从第一步开始重新执行）<br/>5. 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支<br/>6. 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表<br/>7. 执行除“终极目标”以外的所有的目标的规则（规则中如果依赖文件中任一个文件的时间戳比目标文件新，则使用规则所定义的命令重建目标文件）<br/>8. 执行“终极目标”所在的规则<br/><br/><span style="font-size: 24px;"><span style="color: red;">变量取值</span></span><br/>变量定义解析的规则如下：<br/>IMMEDIATE = DEFERRED<br/>IMMEDIATE ?= DEFERRED<br/>IMMEDIATE := IMMEDIATE<br/>IMMEDIATE += DEFERRED or IMMEDIATE<br/>define IMMEDIATE<br/>DEFERRED<br/>Endef<br/>当变量使用追加符（+=）时，如果此前这个变量是一个简单变量（使用 :=定义的）则认为它是立即展开的，其它情况时都被认为是“延后”展开的变量。<br/><br/><span style="font-size: 24px;"><span style="color: red;">书写规则是我们需要注意的几点：</span></span><br/>1. 规则的命令部分有两种书写方式：a. 命令可以和目标：依赖描述放在同一行。命令在依赖文件列表后并使用分号（；）和依赖文件列表分开。b. 命令在目标：依赖的描述的下一行，作为独立的命令行。当作为独立的命令行时此行必须以[Tab]字符开始。在Makefile中，在第一个规则之后出现的所有以[Tab]字符开始的行都会被当作命令来处理。<br/>2. Makefile中符号“$”有特殊的含义（表示变量或者函数的引用），在规则中需要使用符号“$”的地方，需要书写两个连续的（“$$”）。<br/>3. 前边已提到过，对于Makefile中一个较长的行，我们可以使用反斜线“&#92;”将其书写到几个独立的物理行上。虽然make对Makefile文本行的最大长度是没有限制的，但还是建议这样做。不仅书写方便而且更有利于别人的阅读（这也是一个程序员修养的体现）。<br/><br/><br/><span style="font-size: 24px;"><span style="color: red;">wildcard使用：通配PATH下.o文件</span></span><br/>一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。复杂一些用法；可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”，首先使用“wildcard”函数获取工作目录下的.c文件列表；之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。因此在一个目录下可以使用如下内容的Makefile来将工作目录下的所有的.c文件进行编译并最后连接成为一个可执行文件：<br/>#sample Makefile<br/>objects := $(patsubst %.c,%.o,$(wildcard *.c))<br/>foo : $(objects)<br/>cc -o foo $(objects)<br/><br/><span style="font-size: 24px;"><span style="color: red;">@禁止命令回显</span></span><br/>如果规则的命令行以字符“@”开始，则make在执行这个命令时就不会回显这个将要被执行的命令。典型的用法是在使用“echo”命令输出一些信息时。如：<br/>@echo 开始编译XXX模块......<br/>执行时，将会得到“开始编译XXX模块......”这条输出信息。如果在命令行之前没有字符“@”，那么，make的输出将是：<br/>echo编译XXX模块......<br/>编译XXX模块......<br/><br/><span style="font-size: 24px;"><span style="color: red;">Makefile中命令行书写规则</span></span><br/>Makefile中书写在同一行中的多个命令属于一个完整的shell命令行，书写在独立行的一条命令是一个独立的shell命令行。因此：在一个规则的命令中，命令行“cd”改变目录不会对其后的命令的执行产生影响。就是说其后的命令执行的工作目录不会是之前使用“cd”进入的那个目录。如果要实现这个目的，就不能把“cd”和其后的命令放在两行来书写。而应该把这两条命令写在一行上，用分号分隔。这样它们才是一个完整的shell命令行。如：<br/>foo : bar/lose<br/>cd bar; gobble lose > ../foo<br/>如果希望把一个完整的shell命令行书写在多行上，需要使用反斜杠（&#92;）来对处于多行的命令进行连接，表示他们是一个完整的shell命令行。例如上例我们以也可以这样书写：<br/>foo : bar/lose<br/>cd bar; &#92;<br/>gobble lose > ../foo<br/><br/><span style="font-size: 24px;"><span style="color: red;">部分标准的伪目标和空目标命名：</span></span><br/><br/>all<br/>作为Makefile的顶层目标，一般此目标作为默认的终极目标。<br/><br/>clean<br/>这个伪目标定义了一组命令，这些命令的功能是删除所有由make创建的文件。<br/><br/>mostlyclean<br/>和“clean”伪目标功能相似。区别在于它所定义的删除命令不会全部删除由make生成的文件。比如说不需要删除某些库文件。<br/><br/>&#56256;distclean<br/>realclean<br/>clobber<br/><br/>同样类似于伪目标“clean”，但它们所定义的删除命令所删除的文件更多。可以包含非make创建的文件。例如：编译之前系统的配置文件、链接文件等。<br/><br/>install<br/>将make成功创建的可执行文件拷贝到shell 环境变量“PATH”指定的某个目录。典型的，应用可执行文件被拷贝到目录“/usr/local/bin”，库文件拷贝到目录“/usr/local/lib”目录下。<br/><br/>print<br/>打印出所有被更改的源文件列表。<br/><br/>tar<br/>创建一个tar文件（归档文件包）。<br/><br/>shar<br/>创建一个源代码的shell文档（shar文件）。<br/><br/>dist<br/>为源文件创建发布的压缩包，可以使各种压缩方式的发布包。<br/>&#56256;<br/>TAGS<br/>创建当前目录下所有源文件的符号信息（“tags”）文件，这个文件可被vim使用。<br/>&#56256; check<br/>&#56256; test<br/>对Makefile最后生成的文件进行检查。<br/>这些功能和目标的对照关系并不是GNU make规定的。你可以在Makefile中定义任何命名的伪目标。但是以上这些都被作约定，所有开源的工程中这些特殊的目标的命名都是按照这种约定来的。既然绝大多数程序员都遵循这种约定，自然我们也应该按照这种约定来做。否则在别人看来这样Makefile只能算一个样例，不能作为正式版本。<br/><br/></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/123.htm</link>
<title><![CDATA[SVNgoogle code]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Mon, 12 Apr 2010 14:32:45 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/123.htm</guid> 
<description>
<![CDATA[ 
	前两天看到别的googlecode project ，突然想到自己的项目，于是马上把它放到了code上，每修改一次svn 一个新version。<br/><br/>太好了，以前一直没有发现，真是惭愧啊。<br/><br/><br/>subversion Ubuntu 下安装<br/><br/><a href="http://wiki.ubuntu.org.cn/SubVersion" target="_blank">http://wiki.ubuntu.org.cn/SubVersion</a><br/><br/>subversion Manual <br/><br/><a href="http://svnbook.red-bean.com/" target="_blank">http://svnbook.red-bean.com/</a>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/118.htm</link>
<title><![CDATA[bochs gdb 联合调试]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Mon, 29 Mar 2010 09:50:23 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/118.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: courier new;">系统终于还是出现了我无法短时间直接从代码看出来的错误，早就知道这是不可免去的。<br/><br/>我是ubuntu的系统，bochs必须自己编译方可支持与gdb的联合调试。<br/><br/>1.下载bochs.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://bochs.sourceforge.net/" target="_blank">http://bochs.sourceforge.net/</a> 下载最新版本。<br/>2.安装依赖。<br/><div class="code"><br/>&nbsp;&nbsp;&nbsp;&nbsp; $apt-get install build-essential&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //编译工具链，这是必须的<br/>&nbsp;&nbsp;&nbsp;&nbsp; $apt-get install xorg-dev&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//图形</div><br/>3.<div class="code"><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tar xvf bochs-2.4.2.tar.gz<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cd bochs-2.4.2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$./configure --prefix=/opt/bochs/gdbstub --with-x11 --enable-gdb-stub&nbsp;&nbsp;--enable-disasm --enable-pci --enable-pcidev --enable-plugins --enable-ne2000 --enable-pnic --disable-docbook&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//prefix指定目录，自己随意指定即可,docbook在编译的时候会出错，我们把它去掉就是了<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><br/><br/><br/>4.&nbsp;&nbsp; $sudo make<br/>5.&nbsp;&nbsp; $sudo make install <br/><br/><br/>OK,完成了。试试。<br/><div class="code"><br/>//bochsrc<br/><br/>&nbsp;&nbsp;1.megs:32<br/>&nbsp;&nbsp;2 romimage: file=/opt/bochs/gdbstub/share/bochs/BIOS-bochs-latest<br/>&nbsp;&nbsp;3 vgaromimage:file=/opt/bochs/gdbstub/share/bochs/VGABIOS-lgpl-latest<br/>&nbsp;&nbsp;4 floppya:1_44=a.img,status=inserted<br/>&nbsp;&nbsp;5 ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14<br/>&nbsp;&nbsp;6 ata0-master: type=disk, path=&quot;80m.img&quot;, mode=flat, cylinders=162, heads=16,&nbsp;&nbsp;&nbsp;&nbsp; spt=63<br/>&nbsp;&nbsp;7 boot:a<br/>&nbsp;&nbsp;8 log:out.txt<br/>&nbsp;&nbsp;9 mouse:enabled=0<br/> 10 keyboard_mapping:enabled=1,map=/opt/bochs/gdbstub/share/bochs/keymaps/x11-pc-us.map<br/> 11 gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0<br/><br/></div><br/><br/>其中11行是打开gdb联合调试。<br/><br/>把bochs做链接到/bin下就可以了<br/>$bochs -q -f bochsrc<br/><br/>打开另一终端运行gdb<br/>>target remote localhost:1234<br/><br/>OK.<br/><br/><br/>在调试内核的时候遇到了一个问题，就是gdb找不到symbol.最后才发现是自己一时疏忽，竟然在ld中用-s选项将symbol给清除了。<br/><br/>当然，在生成可执行内核时这是必须的，要不然内核会大好几倍。所以我的做法是在Makefile中修改，将ld的-s选项去掉，并在<br/><br/>生成内核的时候<br/><div class="code"><br/>cp -fv kernel.bin kernel.bin.tmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //复制一个带符号的副本<br/>strip kernel.bin.tmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将副本去掉符号<br/>cp -fv kernel.bin.tmp /mnt/floppy/kernel.bin&nbsp;&nbsp;&nbsp;&nbsp; //将副本当做可执行文件放入盘区<br/>rm -rf kernel.bin.tmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //删掉副本，只留下原来带符号的内核，以便gdb时用<br/></div><br/></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/116.htm</link>
<title><![CDATA[Hard disk  partition(collection)]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Sat, 20 Mar 2010 05:40:39 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/116.htm</guid> 
<description>
<![CDATA[ 
	What is a hard disk partition?<br/>A hard disk partition is a defined storage space on a hard drive.<br/>Most operating systems allow users to divide a hard disk into multiple partitions, making one physical hard disk into several smaller logical hard disks.<br/>Reasons to Use Hard Disk Partitions<br/>A user may decide to split a hard disk into multiple partitions in order to organize his data more effectively. On Microsoft Windows machines, it is common to store the OS and applications on one hard disk partition and user data on another hard disk partition. When a problem occurs with Microsoft Windows, the OS partition can be completely formatted and reinstalled without affecting the data partition.<br/>A user may decide to split a hard disk into multiple partitions because smaller partitions often have smaller cluster sizes. A cluster size is the smallest chunk of data which a partition can store. A large partition might have a cluster size of 16KB. This mens that a file with one character in it will occupy 16KB of space on the disk. In a smaller partition, that file might only require 4KB to store. This is a useful strategy if you are storing a large number of small files.<br/>A user may have to split a large hard disk into multiple partitions if the hard disk is larger than the partition size supported by the operating system.<br/>Creating Hard Disk Partitions<br/>Most operating system use the 'fdisk' command to create hard disk partitions. Many operating systems also have graphical tools which accomplish the same task, such as EASEUS Partition Master.<br/>Hard Disk Partitions and File Systems<br/>You don't actually store data in hard disk partitions.<br/>You store file systems in hard disk partitions and then you store data in these file systems.<br/>Some operating systems blur the lines between partitions and file systems.<br/>The Partition Table<br/>Partition information is stored in the partition table, a reserved area at the beginning of a hard disk.<br/>Extended Partitions<br/>A standard partition table is only able to store information about four partitions. At one time this meant that a hard disk could have a maximum of four partitions.<br/>To work around this limitation, extended partitions were created.<br/>An extended partition stores information about other partitions. By using an extended partition, you can create many more than four partitions on your hard disk.<br/>The four standard partitions are often called the primary partitions.<br/>Partitions configured into an extended partition are often referred to as logical partitions.<br/>Partition Types<br/>When a partition is created, a special byte of data is written to record what type of partition it is.<br/>Because one hard disk may be shared by multiple operating systems, operating systems tend to agree on the meaning of these values.<br/>The table below lists some of the partition types in use.<br/>Partition Number&nbsp;&nbsp;Partition Type<br/>00&nbsp;&nbsp;Empty<br/>01&nbsp;&nbsp;DOS 12-bit FAT<br/>02&nbsp;&nbsp;XENIX root<br/>03&nbsp;&nbsp;XENIX usr<br/>04&nbsp;&nbsp;DOS 16-bit FAT <=32M<br/>05&nbsp;&nbsp;DOS Extended Partition<br/>06&nbsp;&nbsp;DOS 16-bit FAT >=32<br/>07&nbsp;&nbsp;OS/2 HPFS, WinNT NTFS<br/>08&nbsp;&nbsp;AIX<br/>09&nbsp;&nbsp;AIX bootable<br/>0a&nbsp;&nbsp;OS/2 Boot Manager<br/>0b&nbsp;&nbsp;Win95 FAT32<br/>0c&nbsp;&nbsp;Win95 FAT32 (LBA)<br/>0e&nbsp;&nbsp;Win95 FAT16 (LBA)<br/>0f&nbsp;&nbsp;Win95 Extended (LBA)<br/>35&nbsp;&nbsp;OS/2 JFS<br/>39&nbsp;&nbsp;Plan 9<br/>40&nbsp;&nbsp;Venix 80286<br/>51&nbsp;&nbsp;Novell<br/>52&nbsp;&nbsp;Microport<br/>63&nbsp;&nbsp;Unix System V, Mach, GNU HURD<br/>64&nbsp;&nbsp;Novell Netware 286<br/>65&nbsp;&nbsp;Novell Netware 386<br/>75&nbsp;&nbsp;PIC/IX<br/>80&nbsp;&nbsp;MINIX until 1.4a<br/>81&nbsp;&nbsp;MINUX, Linux<br/>82&nbsp;&nbsp;Solaris X86, Linux swap<br/>83&nbsp;&nbsp;Linux native<br/>85&nbsp;&nbsp;Linux extended<br/>93&nbsp;&nbsp;Amoeba<br/>94&nbsp;&nbsp;Amoeba BBT<br/>a5&nbsp;&nbsp;FreeBSD, NetBSD, BSD/386, 386BSD<br/>a6&nbsp;&nbsp;OpenBSD<br/>a7&nbsp;&nbsp;NEXTSTEP<br/>b7&nbsp;&nbsp;BSDI BSD/386 filesystem<br/>b8&nbsp;&nbsp;BSDI BSD/386 swap<br/>be&nbsp;&nbsp;Solaris 8 bootable<br/>bf&nbsp;&nbsp;Solaris x86<br/>c7&nbsp;&nbsp;Syrinx<br/>db&nbsp;&nbsp;CP/M<br/>e1&nbsp;&nbsp;DOS access<br/>e3&nbsp;&nbsp;DOS R/O<br/>eb&nbsp;&nbsp;BeOS BFS<br/>fb&nbsp;&nbsp;VMWare filesystem<br/>fc&nbsp;&nbsp;VMWare swap<br/>f2&nbsp;&nbsp;DOS secondary<br/>ff&nbsp;&nbsp;Xenix Bad Block Table<br/><br/><br/>What is MBR?<br/>Short for Master Boot Record, a small program that is executed when a computer boots up. Typically, the MBR resides on the first sector of the hard disk. The program begins the boot process by looking up the partition table to determine which partition to use for booting. It then transfers program control to the boot sector of that partition, which continues the boot process. In DOS and Windows systems, you can create the MBR with the FDISK /MBR command.<br/>An MBR virus is a common type of virus that replaces the MBR with its own code. Since the MBR executes every time a computer is started, this type of virus is extremely dangerous. MBR viruses normally enter a system through a floppy disk that is installed in the floppy drive when the computer is started up. Even if the floppy disk is not bootable, it can infect the MBR.<br/>At the completion of your system's Power On Self Test (POST), INT 19 is called. Usually INT 19 tries to read a boot sector from the first floppy drive. If a boot sector is found on the floppy disk, the that boot sector is read into memory at location 0000:7C00 and INT 19 jumps to memory location 0000:7C00. However, if no boot sector is found on the first floppy drive, INT 19 tries to read the MBR from the first hard drive. If an MBR is found it is read into memory at location 0000:7c00 and INT 19 jumps to memory location 0000:7c00. The small program in the MBR will attempt to locate an active (bootable) partition in its partition table. If such a partition is found, the boot sector of that partition is read into memory at location 0000:7C00 and the MBR program jumps to memory location 0000:7C00. Each operating system has its own boot sector format. The small program in the boot sector must locate the first part of the operating system's kernel loader program (or perhaps the kernel itself or perhaps a "boot manager program") and read that into memory.<br/>INT 19 is also called when the CTRL-ALT-DEL keys are used. On most systems, CTRL-ALT-DEL causes an short version of the POST to be executed before INT 19 is called.<br/>If an active partition is found, that partition's boot record is read into 0000:7c00 and the MBR code jumps to 0000:7c00 with SI pointing to the partition table entry that describes the partition being booted. The boot record program uses this data to determine the drive being booted from and the location of the partition on the disk.<br/>If no active partition table entry is found, ROM BASIC is entered via INT 18. All other errors cause a system hang.<br/>OFFSET 0 1 2 3&nbsp;&nbsp;4 5 6 7&nbsp;&nbsp;8 9 A B&nbsp;&nbsp;C D E F&nbsp;&nbsp;*0123456789ABCDEF*<br/>000000 fa33c08e d0bc007c 8bf45007 501ffbfc *.3.....&#124;..P.P...*<br/>000010 bf0006b9 0001f2a5 ea1d0600 00bebe07 *................*<br/>000020 b304803c 80740e80 3c00751c 83c610fe *.....t....u.....*<br/>000030 cb75efcd 188b148b 4c028bee 83c610fe *.u......L.......*<br/>000040 cb741a80 3c0074f4 be8b06ac 3c00740b *.t....t.......t.*<br/>000050 56bb0700 b40ecd10 5eebf0eb febf0500 *V.......^.......*<br/>000060 bb007cb8 010257cd 135f730c 33c0cd13 *..&#124;...W.._s.3...*<br/>000070 4f75edbe a306ebd3 bec206bf fe7d813d *Ou...........&#125;.=*<br/>000080 55aa75c7 8bf5ea00 7c000049 6e76616c *U.u.....&#124;..Inval*<br/>000090 69642070 61727469 74696f6e 20746162 *id partition tab*<br/>0000a0 6c650045 72726f72 206c6f61 64696e67 *le.Error loading*<br/>0000b0 206f7065 72617469 6e672073 79737465 * operating syste*<br/>0000c0 6d004d69 7373696e 67206f70 65726174 *m.Missing operat*<br/>0000d0 696e6720 73797374 656d0000 00000000 *ing system......*<br/>0000e0 00000000 00000000 00000000 00000000 *................*<br/>0000f0 0O000000 00000000 00000000 00000000<br/>0001b0 00000000 00000000 00000000 00008001 *................*<br/>0001c0 0100060d fef83e00 00000678 0d000000 *...........x....*<br/>0001d0 00000000 00000000 00000000 00000000 *................*<br/>0001e0 00000000 00000000 00000000 00000000 *................*<br/>0001f0 00000000 00000000 00000000 000055aa *..............U.*<br/><br/><br/>What is Partition Table?<br/>Partition can be considered as a piece of disk space, which is marked thereby runs on some operating system. Partition table is located at the first sector (cylinder 0, head 0 and sector 1, MBR) of each hard disk. It memorizes information about sizes and locations of partitions on hard disk. The partition information is started on offset 1BEH of master boot sector. Each partition entry is 16 bytes long. The total partition table is 64 bytes long. Then partition table is limited to a maximum of 4 entries. That is, there is a maximum of 4 partitions, which is called primary partition and can be created on hard disk.<br/>But there are problems: many people want to create more than 4 partitions. So the extended partition is designed for this demand. Master extended partition is the primary partition. Differing from other partitions, the first sector of extended partition is not a boot sector, but another partition table, which is called logical partition table.<br/>Commonly, there are only two partition entries in logical partition table. One points to a partition, called logical partition, whose boundary must be limited to the extended partition. The other entry, if needed, of the extended partition table points to the next logical partition table. Similarly, its boundary is limited to its parents extended partition. And the next logical partition table may also have two partition entries: one points to a logical partition; the other points to another logical partition table and the rest may be deduced by analogy. Therefore, many partitions could be created in extended partition.<br/>Now let's have a look at the layout of one partition entry.<br/>The 16 bytes of one entry are as follows:<br/>OFFSET&nbsp;&nbsp;BYTE&nbsp;&nbsp;DESCRIPTION<br/>0&nbsp;&nbsp;1&nbsp;&nbsp;Boot label. Tell computer toboot from this partition<br/>1&nbsp;&nbsp;1&nbsp;&nbsp;Starting head<br/>2&nbsp;&nbsp;1&nbsp;&nbsp;Lower 6 bits (bit 0 to bit 5) isstarting sector.<br/>Higher 2 bits (bit 6 to bit 7) is the higher bits of starting cylinder<br/>3&nbsp;&nbsp;1&nbsp;&nbsp;The lower 8 bits of starting cylinder<br/>4&nbsp;&nbsp;1&nbsp;&nbsp;Partition type<br/>5&nbsp;&nbsp;1&nbsp;&nbsp;Ending head<br/>6&nbsp;&nbsp;1&nbsp;&nbsp;Lower 6 bits (bit 0 to bit 5) isending sector.<br/>Higher 2 bits (bit 6 to bit 7) is the higher bits of ending cylinder<br/>7&nbsp;&nbsp;1&nbsp;&nbsp;The lower 8 bits of ending cylinder<br/>8&nbsp;&nbsp;4&nbsp;&nbsp;Leading sectors of this partition<br/>12&nbsp;&nbsp;4&nbsp;&nbsp;Number of sectors of this partition<br/>(a) Boot label (offset 0): <br/>Most of the disks have one primary partition. Some people want to have more operating systems on their computers, so they have to create some other primary partitions. To tell the computer from which operating system to boot, one "Active" partition is in need. That's why partition table always keeps an indicator of the currently "Active" partition - the one from which the computer boots. In Partition Table Doctor or Super Fdisk, the active partition is figured out by "Active" with "Yes".<br/>(b) Starting position (offset 1-3):<br/>Describes the partition's starting position, the cylinder, the head and the sector. Also called starting CHS.<br/>starting head = (OFFSET 1)<br/>starting sector = (OFFSET 2) & 0x3f<br/>starting cylinder = (((OFFSET 2) & 0xc0)<<2)&#124;(OFFSET 3)<br/>(c) Partition type (offset 4): <br/>Indicates what file system is in the partition. For example, 06 or 0E indicates a FAT file system. 0B or 0C indicates a FAT32 file system. 07 indicates NTFS or OS/2 HPFS file system.<br/>(d) Ending position (offset 5-7):<br/>Describes the partition's ending position, the cylinder, the head and the sector. Also called ending CHS.<br/>(e) Leading sectors (offset 8-11):<br/>The number of sectors before this partition. If we count all sectors on hard disk in sequence from zero, this field will exactly point to the first sector of this partition.<br/>(f) Number of sectors (offset 12-15):<br/>The total number of sectors on this partition. So the size of this partition will be (Number of sectors)*512/1048576 MB.<br/>Master boot record<br/>From Wikipedia, the free encyclopedia<br/>&nbsp;&nbsp; This article is in need of attention from an expert on the subject. Please help recruit one or improve this article yourself. See thetalk page for details. Please consider using &#123;&#123;Expert-subject&#125;&#125; to associate this request with a WikiProject.<br/><br/>Structure of a Master Boot Record<br/>Address&nbsp;&nbsp;Description&nbsp;&nbsp;Size<br/>in<br/>bytes<br/><br/>Hex<br/>Oct<br/>Dec<br/>&nbsp;&nbsp;<br/>0000&nbsp;&nbsp;0000&nbsp;&nbsp;0&nbsp;&nbsp;Code Area&nbsp;&nbsp;440<br/>(max. 446)<br/>01B8&nbsp;&nbsp;0670&nbsp;&nbsp;440&nbsp;&nbsp;Optional Disk signature&nbsp;&nbsp;4<br/>01BC&nbsp;&nbsp;0674&nbsp;&nbsp;444&nbsp;&nbsp;Usually Nulls; 0x0000&nbsp;&nbsp;2<br/>01BE&nbsp;&nbsp;0676&nbsp;&nbsp;446&nbsp;&nbsp;Table of primary partitions<br/>(Four 16-byte entries, IBM Partition Table scheme)&nbsp;&nbsp;64<br/>01FE&nbsp;&nbsp;0776&nbsp;&nbsp;510&nbsp;&nbsp;55h&nbsp;&nbsp;MBR signature;<br/>0xAA55[1]<br/>2<br/>01FF&nbsp;&nbsp;0777&nbsp;&nbsp;511&nbsp;&nbsp;AAh&nbsp;&nbsp;&nbsp;&nbsp;<br/>MBR, total size: 446 + 64 + 2 =&nbsp;&nbsp;512<br/>A master boot record (MBR), or partition sector, is the 512-byte boot sector that is the first sector ("LBA Sector 0") of a partitioned data storage device such as a hard disk. (The boot sector of a non-partitioned device is a Volume Boot Record. These are usually different, although it is possible to create a record that acts as both; it is called a multi boot record.) The MBR may be used for one or more of the following:<br/>&nbsp;&nbsp;Holding a disk's primary partition table.[2]<br/>&nbsp;&nbsp;Bootstrapping operating systems, after the computer's BIOS passes execution to machine code instructions contained within the MBR.<br/>&nbsp;&nbsp;Uniquely identifying individual disk media, with a 32-bit disk signature; even though it may never be used by the machine the disk is running on.[3][4][5][6]<br/>Due to the broad popularity of IBM PC-compatible computers, this type of MBR is widely used, to the extent of being supported by and incorporated into other computer types including newer cross-platform standards for bootstrapping and partitioning.[citation needed]<br/>Contents<br/> [hide]<br/>•&nbsp;&nbsp;1 MBRs and disk partitioning<br/>•&nbsp;&nbsp;2 MBRs and system bootstrapping<br/>•&nbsp;&nbsp;3 MBRs and disk identity<br/>•&nbsp;&nbsp;4 Programming Considerations<br/>•&nbsp;&nbsp;5 Editing/replacing MBR contents<br/>•&nbsp;&nbsp;6 References<br/>•&nbsp;&nbsp;7 Further reading<br/>•&nbsp;&nbsp;8 See also<br/>•&nbsp;&nbsp;9 External links<br/><br/>[edit]MBRs and disk partitioning<br/>Layout of one 16-byte partition record<br/>Offset&nbsp;&nbsp;Field<br/>length<br/>(bytes)&nbsp;&nbsp;Description<br/>0x00&nbsp;&nbsp;1&nbsp;&nbsp;status[7] (0x80 = bootable (active), 0x00 = non-bootable,<br/>other = invalid[8])<br/><br/>0x01&nbsp;&nbsp;3&nbsp;&nbsp;CHS address of first block in partition.[9]<br/>The format is described in the next 3 bytes.<br/>0x01&nbsp;&nbsp;1&nbsp;&nbsp;head[10]<br/><br/>0x02&nbsp;&nbsp;1&nbsp;&nbsp;sector is in bits 5–0[11]; bits 9–8 of cylinder are in bits 7–6<br/><br/>0x03&nbsp;&nbsp;1&nbsp;&nbsp;bits 7–0 of cylinder[12]<br/><br/>0x04&nbsp;&nbsp;1&nbsp;&nbsp;partition type[13][14]<br/><br/>0x05&nbsp;&nbsp;3&nbsp;&nbsp;CHS address of last block in partition.[15]<br/>The format is described in the next 3 bytes.<br/>0x05&nbsp;&nbsp;1&nbsp;&nbsp;head<br/>0x06&nbsp;&nbsp;1&nbsp;&nbsp;sector is in bits 5–0; bits 9–8 of cylinder are in bits 7–6<br/>0x07&nbsp;&nbsp;1&nbsp;&nbsp;bits 7–0 of cylinder<br/>0x08&nbsp;&nbsp;4&nbsp;&nbsp;LBA of first sector in the partition[16]<br/><br/>0x0C&nbsp;&nbsp;4&nbsp;&nbsp;number of blocks in partition, in little-endian format[16]<br/><br/>The MBR is not located in a partition, it is located at a Main Boot Record area in front of the first partition.<br/>When a data storage device has been partitioned with the MBR Partition Table scheme (i.e., the conventionalIBM PC partitioning scheme), the master boot record contains the primary partition entries in its partition table. The partition table may also contain entries for other, secondary partitions which are stored in extended boot records (EBRs), BSD disklabels, and Logical Disk Manager metadata partitions that are described by those primary entries.[17]<br/>By convention, there are exactly four primary partition table entries in the MBR Partition Table scheme, although some DOS operating systems did extend this to five (PTS-DOS)[18] or even eight (AST or NEC DOS)[19][20]entries. Both the partition length and partition start address are stored as 32-bit quantities. Because the block size is 512 bytes, this implies that neither the maximum size of a partition nor the maximum start address (both in bytes) can exceed 232 × 512 bytes, or 2 TiB. Alleviating this capacity limitation is one of the prime motivations for the development of the GUID Partition Table (GPT).<br/>Where a data storage device has been partitioned with the GPT scheme, the Master Boot Record will still contain a partition table, but its only purpose is to indicate the existence of the GUID Table and to prevent utility programs that understand only the MBR Partition Table scheme from creating any partitions in what they would see as free space on the disk, thereby accidentally erasing the GUID table.<br/>[edit]MBRs and system bootstrapping<br/>On IA-32 IBM PC compatible machines using the MBR Partition Table scheme, the bootstrapping firmwarecontained within the ROM BIOS loads and executes the master boot record. Because the i386 family of processors boot up in real mode, the code in the MBR uses real mode machine language instructions. This code normally passes control by chain loading the volume boot record (VBR) of the active (primary) partition, although some boot managers replace that conventional code with their own.<br/>The conventional MBR code expects the MBR Partition Table scheme to have been used, and scans the list of (primary) partition entries in its embedded partition table to find the only one that is marked with the active flag. It then loads and runs the Volume Boot Record for that partition. (Thus the master boot record, like other boot sectors, is a target for boot-sector infectingcomputer viruses. See boot sector.)<br/>The MBR replacement code in some boot managers can perform a variety of tasks, and what those tasks are varies from boot manager to boot manager. In some, for example, it loads the remainder of the boot manager code from the first track of the disk, which it assumes to be "free" space that is not allocated to any disk partition, and executes it. In others, it uses a table of embedded disk locations to locate the remainder of the boot manager code to load and to execute. (Both approaches have problems. The first relies on behavior that is not universal across all disk partitioning utilities. The second requires that the embedded list of disk locations be updated when changes are made that would relocate the remainder of the code.)<br/>On machines that do not use IA-32 processors, and on machines that use Extensible Firmware Interface (EFI) firmware, this design is unsuitable, and the MBR is not used as part of the system bootstrap. On the latter, the firmware is instead capable of directly understanding the GPT partitioning scheme and the FAT filesystem format, and loads and runs programs held as files in the EFI System partition. The MBR will be involved only insofar as it might contain the partition table if the MBR Partition Table scheme has been used.<br/>There is some MBR replacement code that emulates EFI firmware's bootstrap, which makes non-EFI machines capable of booting from disks using the GPT partitioning scheme. (A typical example is a Multi Boot Record, which can be used as MBR and as a Volume Boot Record in the bootstrap process and hence the name. It detects a GPT and loads the EFI compatible code from disk to complete this task.)<br/>[edit]MBRs and disk identity<br/> <br/> <br/>Information contained in the Partition Table of an external hard drive as it appears in the utility program, QtParted, running under Linux.<br/>In addition to the bootstrap code and a partition table, master boot records may contain a Windows NT disk signature. This is a 32-bit value that is intended to uniquely identify the disk medium (as opposed to the disk unit — the two not necessarily being the same for removable hard disks).<br/>The disk signature was introduced by Windows NT version 3.5, but is now used by several operating systems, including the Linux kernel version 2.6 and later. Linux uses the NT disk signature at boot time to determine the location of the boot volume.[21]<br/>Windows NT (and later Microsoft operating systems) uses the disk signature as an index to all the partitions on any disk ever connected to the computer under that OS; these signatures are kept in Registry keys, primarily for storing the persistent mappings between disk partitions and drive letters. It may also be used in boot.ini files (though most do not), to describe the location of bootable Windows NT (or later) partitions.[22] One key (among many) where NT disk signatures appear in a Windows 2000/XP Registry is:<br/>HKEY_LOCAL_MACHINE&#92;SYSTEM&#92;MountedDevices<br/>If a disk's signature stored in the MBR was A8 E1 B9 D2 (in that order) and its first partition corresponded with logical drive C: under Windows, then the REG_BINARY data under the key value, &#92;DosDevices&#92;C:, would be:<br/>A8 E1 B9 D2 00 7E 00 00 00 00 00 00<br/>The first four bytes are said disk signature. (Note: In other keys, these bytes may appear in reverse order from that found in the MBR sector.) These are followed by eight more bytes, forming a 64-bit Integer, in little endian notation, which are used to locate the byte offset of this partition. In this case, 00 7E corresponds to the hexadecimal value 0x7E00 (32,256dec). Dividing this byte offset by 512 (the size of a hard disk's physical sector in bytes) results in 63, which is the physical sector number (or LBA) containing the first block of the partition ([23]).<br/>If this disk had another partition with the values 00 F8 93 71 02 following the disk signature (under, e.g., the key value &#92;DosDevices&#92;D:), it would begin at byte offset 0x27193f800(10,495,457,280dec), which is also the first byte of physical sector 20,498,940.<br/>[edit]Programming Considerations<br/>Assume that the system being programmed uses the BIOS MBR scheme, as stated above, and the system BIOS locates a valid MBR on a partitioned drive in its boot sequence. As stated above, conventional MBR code loads and runs the operating-system-dependent Volume Boot Record (or bootloader) code that is located at the beginning of the disk's "active" partition. The MBR can simply assume that the one active partition on the current drive is supposed to boot, or alternately, it can be programmed as a Dual boot MBR. A dual boot MBR must interact with the user to determine which partition on which drive should boot, and may transfer control to the MBR of a different drive.<br/>The BIOS will load the first valid MBR that it finds into hexadecimal physical address 0x7c00, and jump to that address. Part of the end of the 512 byte sector is pre-allocated for the partition table and other information (see above), so the MBR program must be tiny enough to fit within 440 bytes of memory. The MBR program may communicate with the user, examine the partition table, or perform some housekeeping tasks such as enabling the A20 line, or changing to Unreal mode from Real mode. Eventually, the MBR will need to perform its main task, and load the program that will perform the next stage of the boot process, usually by making use of the INT 13 BIOS call.<br/>Typical boot sector code also expects to be loaded at physical address 0x7c00, even though all the memory from physical address 0x501 (address 0x500 is the last one used by the BIOS)[citation needed] to somewhere short of 0x9ffff is typically available in Real mode (a total of up to 640 KB minus the first 1281 bytes of memory)[24] Since 0x7c00 is the location where the MBR is already running, one of the first tasks of an MBR is usually to relocate itself somewhere else in memory—most often at 0x600 (for Microsoft code). A conventional Volume Boot Record is only one sector long; but it does no harm and is trivial to allow the MBR to load significantly more than just one sector. Some bootloaders are longer than one sector, so loading more than one sector can speed up the boot process.<br/>[edit]Editing/replacing MBR contents<br/>Though it is possible to directly manipulate the bytes in the MBR sector using various Disk Editors, there are tools to write fixed sets of functioning code to the MBR . Since MS-DOS 5.0, the DOS-mode program FDISK has included the (undocumented, but widely used) switch /mbr, which will rewrite the MBR code. Under Windows 2000 or later, the Recovery Console can be used to write new MBR code to a hard disk using its fixmbr command. Under Windows Vista and Windows 7, the Recovery Environment can be used to write new MBR code to a hard disk by clicking on Command Prompt and typing bootrec /FixMbr.<br/>Some third-party utilities may also be used for directly editing the contents of partition tables (without requiring any knowledge of hexadecimal or disk/sector editors).[25]<br/>In Linux, ms-sys may be used to install a standard MBR. The GRUB and LILO projects have tools for writing code to the MBR sector, namely grub-install and lilo -mbr. The grubinteractive console also has commands to write to the MBR. dd is also a commonly used Unix command to copy or overwrite any sector, MBR included.<br/>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/113.htm</link>
<title><![CDATA[source insight ATT语法高亮]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Fri, 01 Jan 2010 10:18:10 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/113.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: Courier New;">读内核的时候虽然汇编的语法量不大，但是没有高亮总是觉得很不爽。<br/><br/>今天找到了一篇文章，写得很详细，自己配置了一个AT&T的语法高亮。<br/><br/>我试了一下，觉得还行吧，做得很粗糙，但是有点颜色已经很不错了，自己看起来足够了，文章讲得很详细，我就不缀述了。<br/><br/>给链接：<a href="http://knol.google.com/k/at-t-asm-syntax-highlight-in-source-insight#" target="_blank">http://knol.google.com/k/at-t-asm-syntax-highlight-in-source-insight#</a></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/111.htm</link>
<title><![CDATA[asmlinkage and GCCs Function attribute]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Wed, 30 Dec 2009 07:41:18 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/111.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: Courier New;"><br/><div class="code"><br/>&lt;asm-i386/linkage.h&gt;<br/><br/>#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))<br/></div><br/><br/><span style="color: red;"><span style="font-size: 24px;">Function Attribute</span></span><br/><a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#Function-Attributes" target="_blank">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#Function-Attributes</a><br/><br/><span style="color: red;"><span style="font-size: 24px;">Variable Attribute</span></span><br/><a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes" target="_blank">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes</a><br/><br/><span style="color: red;"><span style="font-size: 24px;">Attribute Syntax</span></span><br/><a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Attribute-Syntax.html#Attribute-Syntax" target="_blank">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Attribute-Syntax.html#Attribute-Syntax</a><br/><br/>In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.<br/><br/>在GNU C中，为了帮助你完善函数调用和更仔细地检查你的代码，你会为程序中的函数声明一些确定的东西。<br/><br/><br/>The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: noreturn, noinline, always_inline, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, warn_unused_result and nonnull. Several other attributes are defined for functions on particular target systems.<br/><br/>在声明的时候可以使用__attribute__关键字来指出特殊的属性。在关键字的后面跟上详细规则并用双括号括起来。下面的属性是为<br/>一般的函数定义的。noreturn, noinline, always_inline, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, warn_unused_result and nonnull. 还有几个其它的则是为特殊的函数机制定义的。<br/><br/><span style="color: red;">regparm (number)</span><br/>&nbsp;&nbsp;&nbsp;&nbsp;On the Intel 386, the regparm attribute causes the compiler to pass up to number integer arguments in registers EAX, EDX, and ECX instead of on the stack. Functions that take a variable number of arguments will continue to be passed all of their arguments on the stack.<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在Intel 386架构上，regparm属性使编译器从eax,edx,ecx这些寄存器而不是堆栈来传递整型参数。<br/>&nbsp;&nbsp;&nbsp;&nbsp;Beware that on some ELF systems this attribute is unsuitable for global functions in shared libraries with lazy binding (which is the default). Lazy binding will send the first call via resolving code in the loader, which might assume EAX, EDX and ECX can be clobbered, as per the standard calling conventions. Solaris 8 is affected by this. GNU systems with GLIBC 2.1 or higher, and FreeBSD, are believed to be safe since the loaders there save all registers. (Lazy binding can be disabled with the linker or the loader if desired, to avoid the problem.) <br/><br/><br/><br/><span style="color: red;">section (&quot;section-name&quot;)</span><br/>&nbsp;&nbsp;&nbsp;&nbsp;Normally, the compiler places the code it generates in the text section. Sometimes, however, you need additional sections, or you need certain particular functions to appear in special sections. The section attribute specifies that a function lives in a particular section. For example, the declaration:<br/><div class="code"><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;extern void foobar (void) __attribute__ ((section (&quot;bar&quot;)));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/></div><br/>&nbsp;&nbsp;&nbsp;&nbsp;puts the function foobar in the bar section.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Some file formats do not support arbitrary sections so the section attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead.<br/><br/><span style="color: red;">unused</span><br/>This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function. <br/><br/><span style="color: red;">used</span><br/>This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly. <br/><br/><span style="color: red;">noreturn</span><br/>A few standard library functions, such as abort and exit, cannot return. GCC knows this automatically. Some programs define their own functions that never return. You can declare them noreturn to tell the compiler this fact. For example, <br/>&nbsp;&nbsp;&nbsp;&nbsp;<div class="code">&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fatal () __attribute__ ((noreturn));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatal (/* ... */)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* ... */ /* Print error message. */ /* ... */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp; </div><br/>The noreturn keyword tells the compiler to assume that fatal cannot return. It can then optimize without regard to what would happen if fatal ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables. <br/><br/>The noreturn keyword does not affect the exceptional path when that applies: a noreturn-marked function may still return to the caller by throwing an exception or calling longjmp. <br/><br/>Do not assume that registers saved by the calling function are restored before calling the noreturn function. <br/><br/>It does not make sense for a noreturn function to have a return type other than void. <br/><br/>The attribute noreturn is not implemented in GCC versions earlier than 2.5. An alternative way to declare that a function does not return, which works in the current version and in some older versions, is as follows: <br/><div class="code"><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef void voidfn ();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volatile voidfn fatal;<br/>&nbsp;&nbsp;&nbsp;&nbsp; </div><br/>This approach does not work in GNU C++. <br/><br/><span style="color: red;">weak</span><br/>The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker. <br/><br/><br/><br/><span style="color: red;"><span style="font-size: 18px;">设计__attribute__的原因</span></span><br/><br/>Some people object to the __attribute__ feature, suggesting that ISO C&#039;s #pragma should be used instead. At the time __attribute__ was designed, there were two reasons for not doing this. <br/><br/>1.It is impossible to generate #pragma commands from a macro. <br/>2.There is no telling what the same #pragma might mean in another compiler. <br/><br/>These two reasons applied to almost any application that might have been proposed for #pragma. It was basically a mistake to use #pragma for anything. <br/><br/>The ISO C99 standard includes _Pragma, which now allows pragmas to be generated from macros. In addition, a #pragma GCC namespace is now in use for GCC-specific pragmas. However, it has been found convenient to use __attribute__ to achieve a natural attachment of attributes to their corresponding declarations, whereas #pragma GCC is of use for constructs that do not naturally form part of the grammar. <br/><br/><br/><br/> </span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/110.htm</link>
<title><![CDATA[ubuntu 9.10 eclipse for c/c++ development]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Mon, 21 Dec 2009 04:38:48 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/110.htm</guid> 
<description>
<![CDATA[ 
	<span style="font-family: Courier New;">自带的eclipse 没有cdt.于是下了Eclipse IDE for C/C++ Developers (79 MB)<a href="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-linux-gtk.tar.gz" target="_blank">http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-linux-gtk.tar.gz</a>.<br/><br/>解压到/home/name/bin/eclipse<br/><br/>下载jre.安装，把jre-version放到eclipse目录下并改名为jre.<br/><br/>这时执行<br/><div class="code"><br/>#export GDK_NATIVE_WINDOWS=1 /*这个很关键，要不然eclipse按钮不好使*/<br/>#/home/name/eclipse/eclipse<br/></div><br/>方便一点也可以再加个快键方式<br/><div class="code"><br/>#vi /usr/share/applications/eclipse.desktop<br/>&nbsp;&nbsp;&nbsp;&nbsp; &#91;Desktop Entry&#93;<br/>&nbsp;&nbsp;&nbsp;&nbsp; Encoding=UTF-8<br/>&nbsp;&nbsp;&nbsp;&nbsp; Name=Eclise 3.5.1<br/>&nbsp;&nbsp;&nbsp;&nbsp; Exec=/bin/bash -c &quot;export GDK_NATIVE_WINDOWS=1 ;&#039;/home/name/bin/eclipse/eclipse&#039;&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Icon=/home/name/bin/eclipse/icon.xpm<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Categories=Development;Java;IDE<br/>&nbsp;&nbsp;&nbsp;&nbsp; Version=1.0<br/>&nbsp;&nbsp;&nbsp;&nbsp; StartupNotify=true<br/>&nbsp;&nbsp;&nbsp;&nbsp;Type=Application<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Terminal=0<br/></div><br/>帮助开发，再装上manpage<br/><div class="code"><br/>#apt-get install manpages-posix manpages-posix-dev<br/></div><br/>再加点色彩<br/><div class="code"><br/>#apt-get install most<br/>#vi /etc/manpath.config<br/>&nbsp;&nbsp;&nbsp;&nbsp;DEFINE&nbsp;&nbsp;pager&nbsp;&nbsp;most<br/></div><br/>OK。<br/><br/><br/></span>
]]>
</description>
</item>
<item>
<link>http://narmy.cn/linux/read.php/92.htm</link>
<title><![CDATA[探索struct ＆ union 存储方式]]></title> 
<author>lengyuex &lt;lengyuex@gmail.com&gt;</author>
<category><![CDATA[C &#124;&#124; OS]]></category>
<pubDate>Sat, 03 Oct 2009 08:06:11 +0000</pubDate> 
<guid>http://narmy.cn/linux/read.php/92.htm</guid> 
<description>
<![CDATA[ 
	<div class="code"><br/>/*<br/> * test_struct.c<br/> *<br/> *&nbsp;&nbsp;Created on: 2009-10-3<br/> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author: lengyuex<br/> */<br/><br/>#include &lt;stdio.h&gt;<br/>#include &lt;stdlib.h&gt;<br/>int main(void)<br/>&#123;<br/>&nbsp;&nbsp;struct str_1&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int b;<br/>&nbsp;&nbsp;&#125;good1;<br/>&nbsp;&nbsp;struct str_2&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&#125;good2;<br/>&nbsp;&nbsp;struct str_3&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char d ;<br/><br/>&nbsp;&nbsp;&#125;good3;<br/>&nbsp;&nbsp;struct str_4&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int b;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char c;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char d;<br/><br/>&nbsp;&nbsp;&#125;good4;<br/>&nbsp;&nbsp;struct str_5&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int d ;<br/>&nbsp;&nbsp;&#125;good5;<br/>&nbsp;&nbsp;struct str_6&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int d;<br/>&nbsp;&nbsp;&nbsp;&nbsp;double e;<br/>&nbsp;&nbsp;&nbsp;&nbsp;double f ;<br/>&nbsp;&nbsp;&#125;good6;<br/>&nbsp;&nbsp;union uni_1&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int b;<br/>&nbsp;&nbsp;&#125;good11;<br/>&nbsp;&nbsp;union uni_2&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&#125;good22;<br/>&nbsp;&nbsp;union uni_3&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char d ;<br/><br/>&nbsp;&nbsp;&#125;good33;<br/>&nbsp;&nbsp;union uni_4&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int b;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char c;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char d;<br/><br/>&nbsp;&nbsp;&#125;good44;<br/>&nbsp;&nbsp;union uni_5&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int d ;<br/>&nbsp;&nbsp;&#125;good55;<br/>&nbsp;&nbsp;union uni_6&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char a ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char b ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int c ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int d;<br/>&nbsp;&nbsp;&nbsp;&nbsp;double e;<br/>&nbsp;&nbsp;&nbsp;&nbsp;double f ;<br/>&nbsp;&nbsp;&#125;good66;<br/>&nbsp;&nbsp;printf (&quot;good1:%d&#92;ngood2:%d&#92;ngood3:%d&#92;ngood4:%d&#92;ngood5:%d&#92;ngood6:%d&#92;ngood11:%d&#92;ngood22:%d&#92;ngood33:%d&#92;ngood44:%d&#92;ngood55:%d&#92;ngood66:%d&#92;n&quot;,sizeof(good1),sizeof(good2),sizeof(good3),sizeof(good4),sizeof(good5),sizeof(good6),sizeof(good11),sizeof(good22),sizeof(good33),sizeof(good44),sizeof(good55),sizeof(good66));<br/>&nbsp;&nbsp;printf (&quot;char : %d&#92;n&quot;,sizeof (char));<br/>&nbsp;&nbsp;printf (&quot;int : %d&#92;n&quot;,sizeof (int));<br/>&nbsp;&nbsp;printf (&quot;short :%d&#92;n&quot;,sizeof (short));<br/>&nbsp;&nbsp;printf (&quot;long : %d &#92;n&quot;,sizeof (long));<br/>&nbsp;&nbsp;printf (&quot;float :%d &#92;n&quot;,sizeof (float));<br/>&nbsp;&nbsp;printf (&quot;double :%d &#92;n&quot;,sizeof (double));<br/>&nbsp;&nbsp;printf (&quot;a:0x%x,b:0x%x,c:0x%x,d:0x%x,e:0x%x,f:0x%x&#92;n&quot;,(unsigned int)&amp;good6.a,(unsigned int)&amp;good6.b,(unsigned int)&amp;good6.c,(unsigned int)&amp;good6.d,(unsigned int)&amp;good6.e,(unsigned int)&amp;good6.f);<br/>&nbsp;&nbsp;exit (0);<br/>&#125;<br/><br/></div><br/><br/>打印出结果为：<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>[lengyuex@Tux algorithm]$ ./a.out <br/>good1:8<br/>good2:8<br/>good3:16<br/>good4:12<br/>good5:12<br/>good6:28<br/>good11:4<br/>good22:4<br/>good33:4<br/>good44:4<br/>good55:4<br/>good66:8<br/>char : 1<br/>int : 4<br/>short :2<br/>long : 4 <br/>float :4 <br/>double :8 <br/>a:0xbff7cc9c,b:0xbff7cc9d,c:0xbff7cca0,d:0xbff7cca4,e:0xbff7cca8,f:0xbff7ccb0<br/><br/></div></div><br/><br/><br/>主要在第6个的情况下，感觉有些不对，所以后面用地址来验证一下，发现即使有double的情况下，也是4字节对齐的。
]]>
</description>
</item>
</channel>
</rss>