??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲中文字幕久久精品无码APP,亚洲国产中文在线二区三区免,heyzo亚洲精品日韩http://www.tkk7.com/jjshcc/category/54125.html桑巴葡语译工作室是q州市最专业葡萄牙语译机构-www.puyufanyi.com-Ƣ迎LJava,As400,Mainframe的猎头eric_cc#qq.ccom(?换成@)zh-cnThu, 16 Jan 2014 08:49:56 GMTThu, 16 Jan 2014 08:49:56 GMT60Gdb 调试?/title><link>http://www.tkk7.com/jjshcc/archive/2014/01/15/408982.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 15 Jan 2014 07:59:00 GMT</pubDate><guid>http://www.tkk7.com/jjshcc/archive/2014/01/15/408982.html</guid><wfw:comment>http://www.tkk7.com/jjshcc/comments/408982.html</wfw:comment><comments>http://www.tkk7.com/jjshcc/archive/2014/01/15/408982.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/jjshcc/comments/commentRss/408982.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jjshcc/services/trackbacks/408982.html</trackback:ping><description><![CDATA[<div><div>Gdb 调试?/div><div>调试是所有程序员都会面的问题。如何提高程序员的调试效率,更好更快地定位程序中的问题从而加快程序开发的q度Q是大家共同面对的。就如读者熟知的Windows下的一些调试工P如VC自带的如讄断点、单步跟t等Q都受到了广大用L赞赏。那么,在Linux下有什么很好的调试工具呢?</div><div>本文所介绍的Gdb 调试器是一ƾGNU 开发组lƈ发布的UNIX/Linux 下的E序调试工具。虽Ӟ它没有图形化的友好界面,但是它强大的功能也以与微Y的VC 工具{媲?/div><div>下面p跟随W者一步步学习Gdb调试器?/div><div>3.5.1 Gdb使用程</div><div>q里l出了一个短的E序Q由此带领读者熟悉一下Gdb 的用流E。徏议读者能够实</div><div>际动手操作?/div><div>首先Q打开Linux 下的~辑器Vi或者EmacsQ编辑如下代码(׃Z更好地熟悉Gdb的操作,W者在此用Vi ~辑Q希望读者能够参?.3 节中对Vi 的介l,q熟l用ViQ?/div><div>/*test.c*/</div><div>#include <stdio.h></div><div>int sum(int m);</div><div>int main()</div><div>{</div><div>int i,n=0;</div><div>sum(50);</div><div>for(i=1; i<=50; i++)</div><div>{</div><div>n += i;</div><div>}</div><div>printf("The sum of 1-50 is %d \n", n );</div><div>}</div><div>int sum(int m)</div><div>{</div><div>int i,n=0;</div><div>for(i=1; i<=m;i++)</div><div>n += i;</div><div>printf("The sum of 1-m is %d\n", n);</div><div>}</div><div>在保存退出后首先使用Gcc对test.cq行~译Q注意一定要加上选项“-g”Q这L译出的可执行代码中才包含调试信息Q否则之后Gdb 无法载入该可执行文g?/div><div>[root@localhost Gdb]# gcc -g test.c -o test</div><div>虽然q段E序没有错误Q但调试完全正确的程序可以更加了解Gdb 的用流E。接下来启动Gdb q行调试。注意,Gdb q行调试的是可执行文Ӟ而不是如“.c”的源代码Q因此,需要先通过Gcc~译生成可执行文件才能用Gdbq行调试?/div><div>[root@localhost Gdb]# gdb test</div><div>GNU Gdb Red Hat Linux (6.3.0.0-1.21rh)</div><div>Copyright 2004 Free Software Foundation, Inc.</div><div>GDB is free software, covered by the GNU General Public License, and you are</div><div>welcome to change it and/or distribute copies of it under certain conditions.</div><div>Type "show copying" to see the conditions.</div><div>There is absolutely no warranty for GDB. Type "show warranty" for details.</div><div>This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db</div><div>library "/lib/libthread_db.so.1".</div><div>(gdb)</div><div>可以看出Q在Gdb 的启动画面中指出了Gdb 的版本号、用的库文件等信息Q接下来p入了?#8220;QgdbQ?#8221;开头的命o行界面了?/div><div>Q?Q查看文?/div><div>?Gdb 中键?#8220;l”QlistQ就可以查看所载入的文Ӟ如下所C:</div><div>注意</div><div>在Gdb的命令中都可使用~略形式的命令,?#8220;l”代便“list”Q?#8220;b”代表“breakpoint”Q?#8220;p”代表“print”{,读者也可?#8220;help”命o查看帮助信息?/div><div>(Gdb) l</div><div>1 #include <stdio.h></div><div>2 int sum(int m);</div><div>3 int main()</div><div>4 {</div><div>5 int i,n=0;</div><div>6 sum(50);</div><div>7 for(i=1; i<=50; i++)</div><div>8 {</div><div>9 n += i;</div><div>10 }</div><div>(Gdb) l</div><div>11 printf("The sum of 1?0 is %d \n", n );</div><div>12</div><div>13 }</div><div>14 int sum(int m)</div><div>15 {</div><div>16 int i,n=0;</div><div>17 for(i=1; i<=m;i++)</div><div>18 n += i;</div><div>19 printf("The sum of 1~m is = %d\n", n);</div><div>20 }</div><div>可以看出QGdb 列出的源代码中明地l出了对应的行号Q这样就可以大大地方便代码的定位?/div><div>Q?Q设|断?/div><div>讄断点是调试程序中是一个非帔R要的手段Q它可以使程序到一定位|暂停它的运行。因此,E序员在该位|处可以方便地查看变量的倹{堆栈情늭Q从而找Z码的症结所在?/div><div>?Gdb 中设|断炚w常简单,只需?#8220;b”后加入对应的行号卛_Q这是最常用的方式,另外q有其他方式讄断点Q。如下所C:</div><div>(Gdb) b 6</div><div>Breakpoint 1 at 0x804846d: file test.c, line 6.</div><div>要注意的是,在Gdb 中利用行可|断Ҏ指代码运行到对应行之前将其停止,如上例中Q代码运行到W?行之前暂停(q没有运行第5行)?/div><div>Q?Q查看断Ҏ?/div><div>在设|完断点之后Q用户可以键?#8220;info b”来查看设|断Ҏ况,在Gdb 中可以设|?/div><div>多个断点?/div><div>(Gdb) info b</div><div>Num Type Disp Enb Address What</div><div>1 breakpoint keep y 0x0804846d in main at test.c:6</div><div>Q?Q运行代?/div><div>接下来就可运行代码了QGdb默认从首行开始运行代码,可键?#8220;r”QrunQ即可(若想从程序中指定行开始运行,可在r 后面加上行号Q?/div><div>(Gdb) r</div><div>Starting program: /root/workplace/Gdb/test</div><div>Reading symbols from shared object read from target memory...done.</div><div>Loaded system supplied DSO at 0x5fb000</div><div>Breakpoint 1, main () at test.c:6</div><div>6 sum(50);</div><div>可以看到Q程序运行到断点处就停止了?/div><div>Q?Q查看变量?/div><div>在程序停止运行之后,E序员所要做的工作是查看断点处的相关变量倹{在Gdb 中只需</div><div>键入“p”Q变量值即可,如下所C:</div><div>(Gdb) p n</div><div>$1 = 0</div><div>(Gdb) p i</div><div>$2 = 134518440</div><div>在此处,Z么变?#8220;i”的gؓ如此奇怪的一个数字呢Q原因就在于E序是在断点讄的对应行之前停止的,那么在此Ӟq没有把“i”的数D为零Q而只是一个随机的数字。但变量“n”是在W四行赋值的Q故在此时已lؓ零?/div><div>技?/div><div>Gdb 在显C变量值时都会在对应g前加?#8220;$N”标记Q它是当前变量值的引用标记Q所以以后若惛_ơ引用此变量可以直接写?#8220;$N”Q而无需写冗长的变量名?/div><div>Q?Q单步运?/div><div>单步q行可以使用命o“n”QnextQ或“s”QstepQ,它们之间的区别在于:若有函数调用的时候,“s”会进入该函数?#8220;n”不会q入该函数。因此,“s”qgVC{工具中?/div><div>“step in”Q?#8220;n”cM与VC{工具中?#8220;step over”。它们的使用如下所C:</div><div>(Gdb) n</div><div>The sum of 1-m is 1275</div><div>7 for(i=1; i<=50; i++)</div><div>(Gdb) s</div><div>sum (m=50) at test.c:16</div><div>16 int i,n=0;</div><div>可见Q?#8220;n”后,E序昄函数sum的运行结果ƈ向下执行Q而?#8220;s”后则q入到sum函数之中单步q行?/div><div>Q?Q恢复程序运?/div><div>在查看完所需变量及堆栈情况后Q就可以使用命o“c”QcontinueQ恢复程序的正常q行了。这Ӟ它会把剩余还未执行的E序执行完,q显C剩余程序中的执行结果。以下是之前使用“n”命o恢复后的执行l果Q?/div><div>(Gdb) c</div><div>Continuing.</div><div>The sum of 1-50 is :1275</div><div>Program exited with code 031.</div><div>可以看出Q程序在q行完后退出,之后E序处于“停止状?#8221;?/div><div>知?/div><div>在Gdb中,E序的运行状态有“q行”?#8220;暂停”?#8220;停止”3U,其中“暂停”状态ؓE序遇到了断Ҏ观察点之cȝQ程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“?#8221;QStackQ中。故在这U状态下可以查看函数的变量值等各种属性。但在函数处?#8220;停止”状态之后,“?#8221;׃自动撤销Q它也就无法查看各种信息了?/div><div>3.5.2 Gdb基本命o</div><div>Gdb 的命令可以通过查看help q行查找Q由于Gdb 的命令很多,因此Gdb 的help 其分成了很多种c(classQ,用户可以通过q一步查看相关class扑ֈ相应命o。如下所C:</div><div>(gdb) help</div><div>List of classes of commands:</div><div>aliases -- Aliases of other commands</div><div>breakpoints -- Making program stop at certain points</div><div>data -- Examining data</div><div>files -- Specifying and examining files</div><div>internals -- Maintenance commands</div><div>…</div><div>Type "help" followed by a class name for a list of commands in that class.</div><div>Type "help" followed by command name for full documentation.</div><div>Command name abbreViations are allowed if unambiguous.</div><div>上述列出了Gdb 各个分类的命令,注意底部的加_部分说明其为分cd令。接下来可以</div><div>具体查找各分cȝ的命令。如下所C:</div><div>(gdb) help data</div><div>Examining data.</div><div>List of commands:</div><div>call -- Call a function in the program</div><div>delete display -- Cancel some expressions to be displayed when program stops</div><div>delete mem -- Delete memory region</div><div>disable display -- Disable some expressions to be displayed when program stops</div><div>…</div><div>Type "help" followed by command name for full documentation.</div><div>Command name abbreViations are allowed if unambiguous.</div><div>xQ若用户惌查找call命oQ就可键?#8220;help call”?/div><div>(gdb) help call</div><div>Call a function in the program.</div><div>The argument is the function name and arguments, in the notation of the</div><div>current working language. The result is printed and saved in the value</div><div>history, if it is not void.</div><div>当然Q若用户已知命o名,直接键入“help [command]”也是可以的?/div><div>Gdb 中的命o主要分ؓ以下几类Q工作环境相兛_令、设|断点与恢复命o、源代码查看命o、查看运行数据相兛_令及修改q行参数命o。以下就分别对这几类的命令进行讲解?/div><div>1Q工作环境相兛_?/div><div>Gdb中不仅可以调试所q行的程序,而且q可以对E序相关的工作环境进行相应的讑֮Q甚臌可以使用shell 中的命oq行相关的操作,其功能极其强大。表3.10 所CZؓGdb 常见工作环境相关命o?/div><div>?.10 Gdb 工作环境相关命o</div><div>命o格式 <span style="white-space:pre"> </span>含义</div><div>set args<span style="white-space:pre"> </span>q行时的参数指定q行时参敎ͼ如set args 2</div><div>show args <span style="white-space:pre"> </span>查看讄好的q行参数</div><div>path dir <span style="white-space:pre"> </span>讑֮E序的运行\?/div><div>show paths <span style="white-space:pre"> </span>查看E序的运行\?/div><div>set enVironment var [=value] 讄环境变量</div><div>show enVironment [var] <span style="white-space:pre"> </span> 查看环境变量</div><div>cd dir q入到dir目录Q相当于shell中的cd命o</div><div>pwd 昄当前工作目录</div><div>shell command q行shell的command命o</div><div>2Q设|断点与恢复命o</div><div>Gdb 中设|断点与恢复的常见命令如?.11 所C?/div><div>?3.11 Gdb 讄断点与恢复相兛_?/div><div>命o格式  含义</div><div>bnfo b <span style="white-space:pre"> </span>查看所设断?/div><div>break <span style="white-space:pre"> </span>行号或函数名 <条g表达?gt; 讄断点</div><div>tbreak <span style="white-space:pre"> </span>行号或函数名 <条g表达?gt; 讄临时断点Q到辑֐被自动删?/div><div>delete <span style="white-space:pre"> </span>[断点号] 删除指定断点Q其断点号ؓ“info b”中的W一栏。若~省断点号则删除所有断?/div><div>disable [断点号]] 停止指定断点Q?#8220;info b”仍能查看此断炏V同delete一P省断点号则停止所有断?/div><div>enable  [断点号] ȀzL定断点,xz被disable停止的断?/div><div>condition [断点号] <条g表达?gt; 修改对应断点的条?/div><div>ignore <span style="white-space:pre"> </span>[断点号]<num> 在程序执行中Q忽略对应断点num?/div><div>step <span style="white-space:pre"> </span>单步恢复E序q行Q且q入函数调用</div><div>next<span style="white-space:pre"> </span> 单步恢复E序q行Q但不进入函数调?/div><div>finish <span style="white-space:pre"> </span>q行E序Q直到当前函数完成返?/div><div>c l箋执行函数Q直到函数结束或遇到新的断点</div><div>׃讄断点在Gdb 的调试中非常重要Q所以在此再着重讲解一下Gdb中设|断点的Ҏ。Gdb 中设|断Ҏ多种方式Q其一是按行设|断点,讄Ҏ?.5.1节已l指出,在此׃重复了。另外还可以讄函数断点和条件断点,在此l合上一节的代码,具体介绍后两U设|断点的Ҏ?/div><div>① 函数断点</div><div>Gdb 中按函数讄断点只需把函数名列在命o“b”之后Q如下所C:</div><div>(gdb) b sum</div><div>Breakpoint 1 at 0x80484ba: file test.c, line 16.</div><div>(gdb) info b</div><div>Num Type Disp Enb Address What</div><div>1 breakpoint keep y 0x080484ba in sum at test.c:16</div><div>要注意的是,此时的断点实际是在函数的定义处,也就是在16 行处Q注意第16 行还?/div><div>执行Q?/div><div>② 条g断点</div><div>Gdb 中设|条件断点的格式为:b 行数或函数名if 表达式。具体实例如下所C:</div><div>(gdb) b 8 if i==10</div><div>Breakpoint 1 at 0x804848c: file test.c, line 8.</div><div>(gdb) info b</div><div>Num Type Disp Enb Address What</div><div>1 breakpoint keep y 0x0804848c in main at test.c:8</div><div>stop only if i == 10</div><div>(gdb) r</div><div>Starting program: /home/yul/test</div><div>The sum of 1-m is 1275</div><div>Breakpoint 1, main () at test.c:9</div><div>9 n += i;</div><div>(gdb) p i</div><div>$1 = 10</div><div>可以看到Q该例中在第8 行(也就是运行完W? 行的for 循环Q设|了一?#8220;i==0”的条件断点,在程序运行之后可以看出,E序实在i?0 时暂停运行?/div><div>3QGdb 中源码查看相兛_?/div><div>?Gdb 中可以查看源码以方便其他操作Q它的常见相兛_令如?.12 所C?/div><div>?.12 Gdb 源码查看相关相关命o</div><div>命o格式 <span style="white-space:pre"> </span>含义</div><div>list <span style="white-space:pre"> </span><行号>|<函数?gt; 查看指定位置代码</div><div>file <span style="white-space:pre"> </span>[文g名] 加蝲指定文g</div><div>forward-search  正则表达式源代码前向搜烦</div><div>reverse-search  正则表达式源代码后向搜烦</div><div>dir dir <span style="white-space:pre"> </span>停止路径?/div><div>show directories 昄定义了的源文件搜索\?/div><div>info line<span style="white-space:pre"> </span> 昄加蝲到Gdb内存中的代码</div><div>4QGdb 中查看运行数据相兛_?/div><div>Gdb 中查看运行数据是指当E序处于“q行”?#8220;暂停”状态时Q可以查看的变量及表</div><div>辑ּ的信息,其常见命令如?.13 所C:</div><div>?.13 Gdb 查看q行数据相关命o</div><div>命o格式 <span style="white-space:pre"> </span>含义</div><div>print <span style="white-space:pre"> </span>表达式|变量查看E序q行时对应表辑ּ和变量的?/div><div>x <n/f/u>   查看内存变量内容。其中n为整数表C显C内存的长度Qf表示昄的格式,u表示从当前地址往后请求显C的字节?/div><div>display <span style="white-space:pre"> </span>表达式设定在单步q行或其他情况中Q自动显C的对应表达式的内容</div><div>5QGdb 中修改运行参数相兛_?/div><div>Gdb q可以修改运行时的参敎ͼq该变量按照用户当前输入的值l运行。它的设|方法ؓQ在单步执行的过E中Q键入命?#8220;set 变量Q设定?#8221;。这P在此之后Q程序就会按照该讑֮的D行了。下面,W者结合上一节的代码n的初始D?Q其代码?/div><div>下所C:</div><div>(Gdb) b 7</div><div>Breakpoint 5 at 0x804847a: file test.c, line 7.</div><div>(Gdb) r</div><div>Starting program: /home/yul/test</div><div>The sum of 1-m is 1275</div><div>Breakpoint 5, main () at test.c:7</div><div>7 for(i=1; i<=50; i++)</div><div>(Gdb) set n=4</div><div>(Gdb) c</div><div>Continuing.</div><div>The sum of 1-50 is 1279</div><div>Program exited with code 031.</div><div>可以看到Q最后的q行l果实比之前的值大??/div><div>Gdb的用切记点Q?/div><div>· 在Gcc~译选项中一定要加入“-g”?/div><div>· 只有在代码处?#8220;q行”?#8220;暂停”状态时才能查看变量倹{?/div><div>· 讄断点后程序在指定行之前停</div></div><img src ="http://www.tkk7.com/jjshcc/aggbug/408982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-15 15:59 <a href="http://www.tkk7.com/jjshcc/archive/2014/01/15/408982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Gcc ~译?/title><link>http://www.tkk7.com/jjshcc/archive/2014/01/15/408978.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 15 Jan 2014 07:21:00 GMT</pubDate><guid>http://www.tkk7.com/jjshcc/archive/2014/01/15/408978.html</guid><wfw:comment>http://www.tkk7.com/jjshcc/comments/408978.html</wfw:comment><comments>http://www.tkk7.com/jjshcc/archive/2014/01/15/408978.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jjshcc/comments/commentRss/408978.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jjshcc/services/trackbacks/408978.html</trackback:ping><description><![CDATA[<div><div></div><div>3.4 Gcc ~译?/div><div>GNU CCQ简UCؓGccQ是GNU目中符合ANSI C 标准的编译系l,能够~译用C、C++和Object C{语a~写的程序。Gcc不仅功能强大Q而且可以~译如C、C++、Object C、Java、Fortran、Pascal、Modula-3 和Ada {多U语aQ而且Gcc 又是一个交叉^台编译器Q它能够在当前CPUq_上ؓ多种不同体系l构的硬件^台开发YӞ因此其适合在嵌入式领域的开发编译。本章中的示例,除非特别注明Q否则均采用Gcc版本?.0.0?/div><div>下表3.6 是Gcc支持~译源文件的后缀及其解释?/div><div>?.6 Gcc所支持后缀名解?/div><div>后缀?<span style="white-space:pre"> </span>所对应的语a             后缀?所对应的语a</div><div>.c <span style="white-space:pre"> </span>C原始E序                 .s/.S  汇编语言原始E序</div><div>.C/.cc/.cxx        C++原始E序             .h       预处理文Ӟ头文Ӟ</div><div>.m                    Objective-C原始E序  .o       目标文g</div><div>.i 已经q预处理的C原始E序              .a/.so     ~译后的库文?/div><div>.ii 已经q预处理的C++原始E序</div><div>3.4.1 Gcc~译程解析</div><div>如本章开头提到的Q?strong style="color: red; ">Gcc的编译流E分Z4个步?/strong>Q分别ؓQ?/div><div><span style="color: red; "><strong>· 预处理(Pre-ProcessingQ;</strong></span></div><div><span style="color: red; "><strong>· ~译QCompilingQ;</strong></span></div><div><span style="color: red; "><strong>· 汇编QAssemblingQ;</strong></span></div><div><span style="color: red; "><strong>· 链接QLinkingQ?/strong></span></div><div>下面具体来查看一下Gcc是如何完? 个步骤的?/div><div>首先Q有以下hello.c源代码:</div><div>#include<stdio.h></div><div>int main()</div><div>{</div><div>printf("Hello! This is our embedded world!\n");</div><div>return 0;</div><div>}</div><div><span style="color: red; "><strong>Q?Q预处理阶段</strong></span></div><div>在该阶段Q编译器上qC码中的stdio.h~译q来Qƈ且用户可以用Gcc的选项“-E”q行查看Q该选项的作用是让Gcc在预处理l束后停止编译过E?/div><div>注意</div><div>Gcc指o的一般格式ؓQGcc [选项] 要编译的文g [选项] [目标文g]</div><div>其中Q目标文件可~省QGcc默认生成可执行的文gQ命为:~译文g.out</div><div>[root@localhost Gcc]# <span style="color: red; "><strong>Gcc –E hello.c –o hello.i</strong></span></div><div>在此处,选项“-o”是指目标文gQ由?.6 可知Q?#8220;.i”文g为已l过预处理的C 原始E序。以下列Zhello.i文g的部分内容:</div><div>typedef int (*__gconv_trans_fct) (struct __gconv_step *,</div><div>struct __gconv_step_data *, void *,</div><div>__const unsigned char *,</div><div>__const unsigned char **,</div><div>__const unsigned char *, unsigned char **,</div><div>size_t *);</div><div>…</div><div># 2 "hello.c" 2</div><div>int main()</div><div>{</div><div>printf("Hello! This is our embedded world!\n");</div><div>return 0;</div><div>}</div><div>由此可见QGcc实q行了预处理Q它?#8220;stdio.h”的内Ҏ入到hello.i文g中?/div><div><span style="color: red; "><strong>Q?Q编译阶D?/strong></span></div><div>接下来进行的是编译阶D,在这个阶D中QGcc 首先要检查代码的规范性、是否有语法错误{,以确定代码的实际要做的工作,在检查无误后QGcc把代码翻译成汇编语言。用户可以?#8220;-S”选项来进行查看,该选项只进行编译而不q行汇编Q生成汇~代码?/div><div>[root@localhost Gcc]# <span style="color: red; "><strong>Gcc –S hello.i –o hello.s</strong></span></div><div>以下列出了hello.s的内容,可见Gcc已经其转化为汇~了Q感兴趣的读者可以分析一下这一行简单的C语言程序是如何用汇~代码实现的?/div><div>.file "hello.c"</div><div>.section .rodata</div><div>.align 4</div><div>.LC0:</div><div>.string "Hello! This is our embedded world!"</div><div>.text</div><div>.globl main</div><div>.type main, @function</div><div>main:</div><div>pushl %ebp</div><div>movl %esp, %ebp</div><div>subl $8, %esp</div><div>andl $-16, %esp</div><div>movl $0, %eax</div><div>addl $15, %eax</div><div>addl $15, %eax</div><div>shrl $4, %eax</div><div>sall $4, %eax</div><div>subl %eax, %esp</div><div>subl $12, %esp</div><div>pushl $.LC0</div><div>call puts</div><div>addl $16, %esp</div><div>movl $0, %eax</div><div>leave</div><div>ret</div><div>.size main, .-main</div><div>.ident "GCC: (GNU) 4.0.0 20050519 (Red Hat 4.0.0-8)"</div><div>.section .note.GNU-stack,"",@progbits</div><div><span style="color: red; "><strong>Q?Q汇~阶D?/strong></span></div><div>汇编阶段是把~译阶段生成?#8220;.s”文g转成目标文gQ读者在此可使用选项“-c”可看到汇编代码已{化ؓ“.o”的二q制目标代码了。如下所C:</div><div>[root@localhost Gcc]# <span style="color: red; "><strong>Gcc –c hello.s –o hello.o</strong></span></div><div><span style="color: red; "><strong>Q?Q链接阶D?/strong></span></div><div>在成功编译之后,p入了链接阶段。在q里涉及C个重要的概念Q函数库。读者可以重新查看这个小E序Q在q个E序中ƈ没有定义“printf”的函数实玎ͼ且在预编译中包含q的“stdio.h”中也只有该函数的声明Q而没有定义函数的实现Q那么,是在哪里实现“printf”函数的呢Q最后的{案是:pȝ把这些函数实现都被做到名为libc.so.6的库文g中去了,在没有特别指定时QGcc会到pȝ默认的搜索\?#8220;/usr/lib”下进行查找,也就是链接到libc.so.6库函C去,q样p实现函数“printf”了,而这也就是链接的作用。函数库一般分为静态库和动态库两种。静态库是指~译链接Ӟ把库文g的代码全部加入到可执行文件中Q因此生成的文g比较大,但在q行时也׃再需要库文g了。其后缀名一般ؓ“.a”。动态库与之相反Q在~译链接时ƈ没有把库文g的代码加入到可执行文件中Q而是在程序执行时p行时链接文g加蝲库,q样可以节省pȝ的开销。动态库一般后~名ؓ“.so”Q如前面所q的libc.so.6是动态库。Gcc在编译时默认使用动态库。完成了链接之后QGcc可以生成可执行文gQ如下所C?/div><div>[root@localhost Gcc]# <span style="color: red; "><strong>Gcc hello.o –o hello</strong></span></div><div>q行该可执行文gQ出现正的l果如下?/div><div>[root@localhost Gcc]# ./hello</div><div>Hello! This is our embedded world!</div><div>3.4.2 Gcc~译选项分析</div><div>Gcc 有超q?00 个的可用选项Q主要包括M选项、告警和出错选项、优化选项和体p?/div><div>l构相关选项。以下对每一cM最常用的选项q行讲解?/div><div>Q?QM选项</div><div>Gcc的ȝ选项如表3.7 所C,很多在前面的CZ中已l有所涉及?/div><div><span style="color: red; "><strong>?.7 GccM选项列表</strong></span></div><div><span style="color: red; "><strong>-c 只是~译不链接,生成目标文g“.o”</strong></span></div><div><span style="color: red; "><strong>-S 只是~译不汇~,生成汇编代码</strong></span></div><div><span style="color: red; "><strong>-E 只进行预~译Q不做其他处?/strong></span></div><div><span style="color: red; "><strong>-g 在可执行E序中包含标准调试信?/strong></span></div><div><span style="color: red; "><strong>-o file 把输出文件输出到file?/strong></span></div><div><span style="color: red; "><strong>-v 打印出编译器内部~译各过E的命o行信息和~译器的版本</strong></span></div><div><span style="color: red; "><strong>-I dir 在头文g的搜索\径列表中ddir目录</strong></span></div><div><span style="color: red; "><strong>-L dir 在库文g的搜索\径列表中ddir目录</strong></span></div><div><span style="color: red; "><strong>-static 链接静态库</strong></span></div><div><span style="color: red; "><strong>-llibrary q接名ؓlibrary的库文g</strong></span></div><div>对于“-c”?#8220;-E”?#8220;-o”?#8220;-S”选项在前一节中已l讲解了其用方法,在此主要讲解另外两个非常常用的库依赖选项“-I dir”?#8220;-L dir”?/div><div>· “-I dir”</div><div>正如上表中所qͼ“-I dir”选项可以在头文g的搜索\径列表中ddir 目录。由于Linux中头文g都默认放C“/usr/include/”目录下,因此Q当用户希望d攄在其他位|的头文件时Q就可以通过“-I dir”选项来指定,q样QGcc׃到相应的位置查找对应的目录。比如在“/root/workplace/Gcc”下有两个文gQ?/div><div>/*hello1.c*/</div><div>#include<my.h></div><div>int main()</div><div>{</div><div>printf("Hello!!\n");</div><div>return 0;</div><div>}</div><div>/*my.h*/</div><div>#include<stdio.h></div><div>q样Q就可在Gcc命o行中加入“-I”选项Q?/div><div>[root@localhost Gcc] Gcc hello1.c –I /root/workplace/Gcc/ -o hello1</div><div>q样QGccp够执行出正确l果?/div><div>知?/div><div>在include语句中,“<>”表示在标准\径中搜烦头文Ӟ““””表示在本目录中搜索。故在上例中Q可把hello1.c?#8220;#include<my.h>”改ؓ“#include “my.h””Q就不需要加?#8220;-I”选项了?/div><div>·<span style="color: red; "><strong> “-L dir”选项“-L dir”的功能与“-I dir”cMQ能够在库文件的搜烦路径列表中添加dir 目录?/strong></span></div><div><span style="color: red; "><strong>例如有程序hello_sq.c需要用到目?#8220;/root/workplace/Gcc/lib”下的一个动态库libsunq.soQ则</strong></span></div><div>只需键入如下命o卛_Q?/div><div>[root@localhost Gcc] Gcc hello_sq.c –L /root/workplace/Gcc/lib –lsunq –o hello_sq</div><div>需要注意的是,“-I dir”?#8220;-L dir”都只是指定了路径Q而没有指定文Ӟ因此不能在\径中包含文g名?/div><div>另外值得详细解释一下的?#8220;-l”选项Q它指示Gcc去连接库文glibsunq.so。由于在Linux下的库文件命名时有一个规定:必须以l、i、b 3 个字母开头。因此在?l选项指定链接的库文g名时可以省去l、i、b 3个字母。也是说Gcc在对“-lsunq”q行处理Ӟ会自动去链接名ؓlibsunq.so的文件?/div><div>Q?Q告警和出错选项</div><div>Gcc的告警和出错选项如表3.8 所C?/div><div>?.8 GccM选项列表</div><div>????/div><div>-ansi 支持W合ANSI标准的CE序</div><div>-pedantic 允许发出ANSI C标准所列的全部警告信息</div><div>l表</div><div>????/div><div>-pedantic-error 允许发出ANSI C标准所列的全部错误信息</div><div>-w 关闭所有告?/div><div>-Wall 允许发出Gcc提供的所有有用的报警信息</div><div>-werror 把所有的告警信息转化为错误信息,q在告警发生时终止编译过E?/div><div>下面l合实例对这几个告警和出错选项q行单的讲解?/div><div>如有以下E序D:</div><div>#include<stdio.h></div><div>void main()</div><div>{</div><div>long long tmp = 1;</div><div>printf("This is a bad code!\n");</div><div>return 0;</div><div>}</div><div>q是一个很p糕的程序,读者可以考虑一下有哪些问题Q?/div><div>· “-ansi”</div><div>该选项强制Gcc生成标准语法所要求的告警信息,管q还q不能保证所有没有警告的E序都是W合ANSI C标准的。运行结果如下所C:</div><div>[root@localhost Gcc]# Gcc –ansi warning.c –o warning</div><div>warning.c: 在函?#8220;main”中:</div><div>warning.c:7 警告Q在无返回值的函数中,“return”带返回?/div><div>warning.c:4 警告Q?#8220;main”的返回类型不?#8220;int”</div><div>可以看出Q该选项q没有发?#8220;long long”q个无效数据cd的错误?/div><div>· “-pedantic”</div><div>允许发出ANSI C标准所列的全部警告信息Q同样也保证所有没有警告的E序都是W合</div><div>ANSI C标准的。其q行l果如下所C:</div><div>[root@localhost Gcc]# Gcc –pedantic warning.c –o warning</div><div>warning.c: 在函?#8220;main”中:</div><div>warning.c:5 警告QISO C90不支?#8220;long long”</div><div>warning.c:7 警告Q在无返回值的函数中,“return”带返回?/div><div>warning.c:4 警告Q?#8220;main”的返回类型不?#8220;int”</div><div>可以看出Q用该选项查看Z“long long”q个无效数据cd的错误?/div><div>· “-Wall”</div><div>允许发出Gcc能够提供的所有有用的报警信息。该选项的运行结果如下所C:</div><div>[root@localhost Gcc]# Gcc –Wall warning.c –o warning</div><div>warning.c:4 警告Q?#8220;main”的返回类型不?#8220;int”</div><div>warning.c: 在函?#8220;main”中:</div><div>warning.c:7 警告Q在无返回值的函数中,“return”带返回?/div><div>warning.c:5 警告Q未使用的变?#8220;tmp”</div><div>使用“-Wall”选项扑և了未使用的变量tmpQ但它ƈ没有扑և无效数据cd的错误?/div><div>另外QGcc q可以利用选项对单独的常见错误分别指定警告Q有兛_体选项的含义感?/div><div>的读者可以查看Gcc手册q行学习?/div><div>Q?Q优化选项</div><div>Gcc可以对代码进行优化,它通过~译选项“-On”来控制优化代码的生成Q其中n是一个代表优化别的整数。对于不同版本的Gcc 来讲Qn 的取D围及其对应的优化效果可能q不完全相同Q比较典型的范围是从0变化???/div><div>不同的优化别对应不同的优化处理工作。如使用优化选项“-O”主要q行U程跌{QThread JumpQ和延迟退栈(Deferred Stack PopsQ两U优化。用优化选项“-O2”除了完成所?#8220;-O1”U别的优化之外,同时q要q行一些额外的调整工作Q如处理器指令调度等。选项“-O3”则还包括循环展开和其他一些与处理器特性相关的优化工作。虽然优化选项可以加速代码的q行速度Q但对于调试而言是一个很大的挑战。因Z码在l过优化之后Q原先在源程序中声明和用的变量很可能不再用,控制也可能会突然蟩转到意外的地方,循环语句也有可能因ؓ循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。所以笔者徏议在调试的时候最好不使用M优化选项Q只有当E序在最l发行的时候才考虑对其q行优化?/div><div>Q?Q体pȝ构相关选项</div><div>Gcc的体pȝ构相关选项如表3.9 所C?/div><div>?.9 Gcc体系l构相关选项列表</div><div>????/div><div>-mcpu=type 针对不同的CPU使用相应的CPU指o。可选择的type有i386、i486、pentium及i686{?/div><div>-mieee-fp 使用IEEE标准q行点数的比较</div><div>-mno-ieee-fp 不用IEEE标准q行点数的比较</div><div>-msoft-float 输出包含点库调用的目标代码</div><div>-mshort 把intcd作ؓ16位处理,相当于short int</div><div>-mrtd 函数参C数固定的函数用ret NUMq回Q节省调用函数的一条指?/div><div>q些体系l构相关选项在嵌入式的设计中会有较多的应用,读者需Ҏ不同体系l构?/div><div>对应的选项q行l合处理。在本书后面涉及到具体实例会有针Ҏ的讲解?/div></div><img src ="http://www.tkk7.com/jjshcc/aggbug/408978.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-15 15:21 <a href="http://www.tkk7.com/jjshcc/archive/2014/01/15/408978.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://ynkmht.com" target="_blank">ƷƬҹɫ</a>| <a href="http://adcbgy.com" target="_blank">þþƷav鶹ѿ </a>| <a href="http://69xjj.com" target="_blank">99þþùƷ޿</a>| <a href="http://83k5.com" target="_blank">ŷרһ</a>| <a href="http://t66p.com" target="_blank">þҹɫƷAV</a>| <a href="http://69ct.com" target="_blank">ڵĤѿƵ</a>| <a href="http://zygwkqf.com" target="_blank">ɫҹƵ˵</a>| <a href="http://qinglou31.com" target="_blank"> ˬ AVˬ</a>| <a href="http://fholaer.com" target="_blank">ۺһƷ</a>| <a href="http://666mou.com" target="_blank">޹˳ɾƷ</a>| <a href="http://99880524.com" target="_blank">ŮƷƵѹۿ</a>| <a href="http://wwyw99977.com" target="_blank">ѿŮճˮ</a>| <a href="http://hbwhgd.com" target="_blank">˳Ƶ69</a>| <a href="http://828556.com" target="_blank">ҰȫƵ</a>| <a href="http://www026qqcom.com" target="_blank">һëƬѿ</a>| <a href="http://www759696b.com" target="_blank">պav</a>| <a href="http://51708695.com" target="_blank">ձ</a>| <a href="http://kmc19.com" target="_blank">˳վѲ</a>| <a href="http://appmofun.com" target="_blank">޾Һ</a>| <a href="http://dingdingduo.com" target="_blank">Ļһȥ̨</a>| <a href="http://plladay.com" target="_blank">˳ӰԺ߸</a>| <a href="http://www48646.com" target="_blank">˾þô߽</a>| <a href="http://www4jbd.com" target="_blank">޹Ʒ˾Ʒ</a>| <a href="http://bbyy7.com" target="_blank">޾Ʒ456߲</a>| <a href="http://jioupin.com" target="_blank">޹Ʒþ˰</a>| <a href="http://225ck.com" target="_blank">˳ӰԺ</a>| <a href="http://72c5.com" target="_blank">Ʒպһ</a>| <a href="http://91haikala.com" target="_blank">㽶Ƶ߹ۿ</a>| <a href="http://http99.com" target="_blank">aaaëƬƵѹۿ</a>| <a href="http://1000hu.com" target="_blank">һëƬѹۿ</a>| <a href="http://pengkaimjg.com" target="_blank">ѹ˸߹ۿվ</a>| <a href="http://77133144.com" target="_blank">òƵ</a>| <a href="http://nonobo.com" target="_blank">ѹ˸߹ۿ鶹</a>| <a href="http://dou18.com" target="_blank">Ƶ</a>| <a href="http://2255325.com" target="_blank">ƷAһ</a>| <a href="http://xmjcjc.com" target="_blank">һ</a>| <a href="http://633223.com" target="_blank">ɫaAV</a>| <a href="http://lyjhjx.com" target="_blank"> ɫһ վ</a>| <a href="http://dddd20.com" target="_blank">freežž</a>| <a href="http://lidajc.com" target="_blank">vavaպ߹ۿ</a>| <a href="http://zhuoyueyc.com" target="_blank">޳</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>