??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲真人无码永久在线观看,亚洲国产另类久久久精品黑人 ,国产偷国产偷亚洲清高APPhttp://www.tkk7.com/sk8boy/articles/59485.html思?/dc:creator>思?/author>Fri, 21 Jul 2006 14:39:00 GMThttp://www.tkk7.com/sk8boy/articles/59485.htmlhttp://www.tkk7.com/sk8boy/comments/59485.htmlhttp://www.tkk7.com/sk8boy/articles/59485.html#Feedback0http://www.tkk7.com/sk8boy/comments/commentRss/59485.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/59485.htmlW一U方法比较复杂,但可以帮助您完全掌握Windows 2003自动d的设|方法。首先单几Z开始 q行”,在输入框中键入“regedit”打开注册表编辑器Q然后在注册表编辑器左方控制C依次单击展开“HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/Current Version/Winlogon”,再选择“编辑 d 字符串值”,在数值名UC键入“AutoAdminLogon”,然后在窗口中的空白位|上点一下,再双d新徏的字W串“AutoAdminLogon”,在弹出的“编辑字W串”对话框中输入?”设|系l允许自动登录。再重复以上的操作,创徏一个名为“DefaultUserName”的字符串|~辑字符串ؓ您准备用于自动登录的账户名称。再新创Z个名为“Defaultpassword”的字符串|q编辑字W串为您准备用于自动d的用戯̎户密码,~辑完ƈ查无误后Q关闭注册表~辑器ƈ重新启动电脑卛_自动d。注意,如果已有“DefaultUserName”,可以不必重新创徏Q直接更改原有字W串倹{如果您的系l工作在局域网环境下,q且在登录到pȝ上时需要登录域服务器,那么您还需要再d一个“DefaultDomainName”ƈ~辑字符串ؓ您登录的域名U?


另一U方法比较简单,您只需单击“开始 q行”,q在输入框中键入“control userpasswords2”,q样可以在“用戯̎户”管理窗口中清除“要使用本机Q用户必输入密码”复选项的选中状态,然后按下键盘的“Ctrl+Shift+A”,会得到一个“自动登录”的讄对话?您可以按自己的需要设|系l在电脑启动时自动登录用的用户账户和密码?/a>

]]>
待机、休眠究竟是咋回事?它们之间I竟有何区别Q(转蝲Q?/title><link>http://www.tkk7.com/sk8boy/articles/45161.html</link><dc:creator>思?/dc:creator><author>思?/author><pubDate>Tue, 09 May 2006 02:48:00 GMT</pubDate><guid>http://www.tkk7.com/sk8boy/articles/45161.html</guid><wfw:comment>http://www.tkk7.com/sk8boy/comments/45161.html</wfw:comment><comments>http://www.tkk7.com/sk8boy/articles/45161.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/sk8boy/comments/commentRss/45161.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/sk8boy/services/trackbacks/45161.html</trackback:ping><description><![CDATA[<p> <strong>如何q入待机和休?/strong> <br /> <br />  按下“开始→x”,在弹出窗口中Q你会看到最后一就是“待机”。怎么没有“休眠”呢Q原来,pȝ默认是不启用休眠的,需要我们自p|,在控刉板中双击“电源选项”,切换到“休眠”标{,N“启用休眠”(见图1 Q,可以在x菜单中看到“休眠”了?/p> <p align="center"> <img src="http://www.dvbbs.net/ShowImg.asp?p=/2006-4-20/68334112113_1.jpg" /></p> <p> <br /> <strong>电脑的高U电源管?/strong> <br /> <br />  要掌握待机和休眠Q必d了解下面两个知识QACPI和APM?br /></p> <strong>1.什么是ACPI<br /><br /></strong>  ACPI是Advanced Configuration and Power Interface的羃写,中文意ؓ“高U配|与甉|接口”,q是微Y、英特尔和东芝共同开发的一U工业标准?br /><br /><strong>ACPI主要可实C下功?</strong><br /><br />①用户可以电脑在指定时间开、关Q?  <br />②即插即用设备在插入时能够由ACPI来控Ӟqؓ其供电;<br />③在无h使用电脑时可以电脑q入休眠状态,但保证一些通信讑֤打开Q?br />④操作系l可以根据外讑֒L具体需求ؓ它分配能源;<br />⑤操作系l可以在应用E序Ҏ间要求不高的情况下降低时钟频率; <br />⑥用笔记本电脑的用户可以指定电脑在低电压情况下q入低功耗状态,以保证重要应用程序运行?  <br /><br />  同时Q可ACPI分ؓ六种不同的工作状态,分别是S0到S5Q它们代表的含义分别是:<br /><br />S0Q电脑正常工作,所有硬件设备全部处于打开或正常工作的状态;<br />S1Q也UCؓPOSQPower on SuspendQCPU停止工作Q,其他的硬件设备仍然正常工作;<br />S2Q将CPU关闭Q但其余的硬件设备仍然运转;<br />S3Q通常UCؓSTRQSuspend to RAMQ挂起到内存Q,运行中的数据写入内存后关闭盘Q?br />S4Q也UCؓSTDQSuspend to DiskQ挂起到盘Q,内存信息写入盘Q然后所有部件停止工作;<br />S5Q所有硬件设备(包括甉|Q全部都关闭Q也是x?br /><br /><strong>2.什么是APM<br /></strong><br />  APM其实是Advanced Power ManagerQ高U电源管理)的羃写,q是通过操作pȝ来控制、管理电脑硬件电源的一U管理模式,其实也是一套电脑电源管理程序(软gQ,版本不同Q功能也有所不同Q比如APM V1.0&V1.1,q两个版本都是直接由BIOS执行甉|理Q而APM V1.2则是可以先通过操作pȝ定义甉|理Q然后再由BIOS负责执行?br />在如今流行的操作pȝ中,都内|了APMQ而在以前的DOS时代QAPMq未真正被引入操作系l,所以无法执行待机、休眠等操作Q重启也只能用CtrlQAltQDeletel合键或甉|的Reset键?br /><br /><strong>3.BIOS中的甉|理讄<br /></strong><br />  一般而言Q主板商定义BIOS的默认设|都是启动了“高U电源管理”这个功能的Q大多数情况下不需要我们自p|,只需采用光认设|即可。如果碰C前能使用“高U电源管理”,但后来又不行了,排除pȝ或其他硬件可能外Q才会考虑BIOS中的讄是否有问题。遇到这U情况,可以BIOS讄q原到默认状态即可,Ҏ为:启动电脑Q用DEL键进入BIOSQ用键盘上方向键定位到“Load Optimized Defaults”,然后按F10保存q出BIOS讄卛_。这里以Intel845PELZQ其他类型主板大致相同,q里仅作为参考?br /><br /><strong>“Power Management Setup”常见设|D?br /><br />ACPI Function:是否允许ACPI功能</strong><br /><br />  ACPI Suspend Type:ACPI的挂L型,通常q里只有一个选择Q即S1QPOSQ状态,其实q个包含了其他的挂L态(S2、S3、S4Q?br /><br />  Power Management:电能理方式Q默认ؓUser DefineQ用戯定义Q,q有是Min SavingQ最)和Max SavingQ最大)<br /><br /><strong>Video Off Method:昄器开?br /></strong><br />  可以讄的?Blank Screen表示昄器不发射电子光束Q即可减耗电QV/H SYNCQBlank表示除Blank Screen外,q可由BIOS来控制显C器水^与垂直同步信P辑ֈ省电目的Q此ؓ默认讄QDPMS SupportQDPMS是显C器与显卡之间的甉|理协定。在两者都支持DPMS的状态下Q只要BIOS支持Q显卡即可通过信号通知昄器进入省甉|式?br /><br />  HDD Power Down:讄IDE盘在多长时间内完全没有d操作Ӟ便可q入省电状态,切断盘甉|以省电,~省gؓDisabled?br /><br />  Modem Use IRQ:该选项说明Modem使用的端口所占用的IRQ~号Q让pȝ在省늊态下仍可以监视。Modem是否有活动,可以讄的|N/A??????1。其中N/A表示不对Modemq行监测Q?br /><br />  USB KB Wake-Up Drom S3:是否采用USB键盘唤醒Q缺省gؓ“Disabled”?br /><br />  Soft-Off by PWR-Button:q是机箱甉|开关的功能讄Q在开机状态下Q按住开机电源按键超q四U钟Q系l就一定会xQ如果不过4U,pȝ׃按此讄操作。可以设|的|Delay 4 Sec表示过4U关机,如果不超q?U则q入Suspend模式Q此ؓ默认讄QInstant-Off表示不需要等?U,只要按下x按钮立刻x?br /><strong>待机、休眠是怎样工作?br /><br />1.Z么需要待机、休?br /><br /></strong>  管电脑gq行速度来快Q但操作pȝ的体U也在不断膨胀Q得电脑开、关机时Q启动、关闭的E序来多Q花Ҏ间也来Oѝ因此如何让电脑能够快速启动、一开机就q入WindowsQ就成ؓ用户兛_的问题?br />于是Q随着g和Y件的升Q操作系l开始引入了高甉|理Q其作用是在电脑闲|时关闭部分讑֤Q将电脑q入{待休息状态,q样当需要重C用电脑时Q能够直接从{待休息状态尽快恢复到原先的工作状态,起到cM于快速启动的效果Q同Ӟ不用电脑时还能节省不电能?br /><br /><strong>2.把数据存到内存中——待?/strong><br /><br />  我们都知道,从硬盘读取数据的速度q低于从内存d的速度。因此,电脑q行旉先是硬盘中的数据提出ƈ存到内存中,然后再由内存数据发送到CPU中进行处理,接着处理后的数据先q回内存Q再写进盘。正在运行的数据几乎都保存在内存中。然而,q入待机状态也是当前数据保存在内存中,然后硬盘关闭,也就是挂起到内存QSuspend to RAM,USTRQ?br /><br />  q时除硬盘外Q其他设备还是处于加늭待状态(也就是说唤醒时无重新加电,通俗地说是原地待命Q,所以电源、CPU、显卡等讑֤的风扇还是处于工作中Q键盘指C灯也是亮着的。我们可以通过按键盘Q意键或动一下鼠标来唤醒电脑Q这时硬盘就会重新加电ƈ启动Q然后和内存、CPU{设备交换数据,从而完成返回到原来工作状态的d?br /><br /><strong>3.内存装q硬盘——休?/strong><br /><br />  休眠Q在q义上包括挂起到内存QSTRQ也是待机Q和挂v到硬盘(Suspend to DiskQ简USTDQ两U,而我们通常所指的休眠其实是STD。当电脑q入休眠状态时Q电脑首先将内存中的状态复制到盘Q然后关闭电源。此时电脑几乎和通常x一样“安静”,你完全可以切断电源,因ؓ保存到硬盘里面的数据不会׃断电而丢失!它和Ghostl系l做镜像的道理一P不过与Ghost不同的是QGhost保存q恢复的是整个系l信息,而休眠保存ƈ恢复的是pȝq行的信息。与待机相比Q休眠是不能通过外部讑֤来唤醒的Q它和正常开Z样启动电脑;不过和开机相比,休眠后启动电脑无需一个一个进E地来启动,只须要将盘中的内存镜像d到内存中卛_?br /><br />  ׃内存中的资料是电脑当前的“状态”,Z持这个状态不变(可理解ؓ不能压羃Q,pȝ必须在硬盘中开辟一个和内存定w大小相等的空间以保证能装下整个内存的“当前状态”,而这个空间的名字叫hiberfil.sysQ它的体U一般ؓ物理内存的大(比如电脑的内存是256MBQ这个文件的体积也将?56MBQ如?Q,和我们管虚拟内存叫做pagefile.sys道理是一L?br /><br /><strong>  你知道吗Q?br /><br />Z么Windows 98中不要启用休眠?</strong><br /><br />  原因有两个:①在刚推出Windows 98Ӟ很多g对ACPI支持不是很好Q所以Windows 98不能自动识别ACPI规范Q不q可以在安装时用“Setup /PJ”命令来安装Windows 98Q或升Windows 98“高U电源管理”的驱动Q让其支持ACPI。②׃Windows 98的内核对内存理上的~陷Q很多时候Windows 98需要将电脑重启Q清I内存后才能保证pȝ正常高效地运行。休眠正好是不清I内存信息而将其存储到盘里面Q所以休眠对Windows 98pȝ而言Q也失M原来的意义。相比之下,NT内核的系l在内存理斚w要优U得多Q可以连l用很多天而无重启,pȝ照样能高效运行? <p><strong>巧用待机、休眠,助你事半功?br /><br />实例1Q一键待机,一键关?/strong><br /><br />  在控刉板中打开“电源选项”,切换到“高U”标{,“在按下计算机电源按钮时”设|ؓ“关机”,“在按下计算机睡眠按钮时”设|ؓ“待机”(见图2Q,q样按键盘上的“Power”键是“关机”,按“Sleep”键是“待机”,是不是方便了不少?</p><p align="center"><img alt="WindowsQ俺是这样休息的" src="http://www.dvbbs.net/ShowImg.asp?p=/2006-4-20/65674112113_2.jpg" border="0" /></p><p>  如果你的键盘没有“Sleep”键Q可以在桌面叛_q择“新建→快捷方式”,在弹出对话框的“请键入目的位|”中输入“rundll32.exe powrprof.dll,SetSuspendState”,完成后再l它讄一个快捷键l合Q比如:CtrlQF12。这个快h式的功能与“在按下计算机睡眠按钮时”的讄有很大关p,如果你将q里改ؓ“休眠”,那么它就成了休眠的快h式了?br /></p><strong>实例2Q让鼠标别来打搅爱机休息<br /><br /></strong>  有不朋友都Cq由于鼠标太灉|了,待机ӞE微震动一下电脑桌唤醒了电脑Q你可以依次打开“开始→q行”,输入devmgmt.mscQ打开讑֤理?然后定位到“鼠标和其他指针讑֤”,打开当前鼠标讑֤的属性,切换到“电源管理”,取消“允许这台设备用计机q待机状态”(见图3Q,q样鼠标׃会来打扰爱机的休息了? <p align="center"><img alt="WindowsQ俺是这样休息的" src="http://www.dvbbs.net/ShowImg.asp?p=/2006-4-20/37565112113_3.jpg" border="0" /></p><p><strong>实例3Q超快速关机法——待机+断电<br /></strong><br />  ׃待机是将数据存储到内存后正常地将盘关闭Q也是不会损坏盘。如果这时断电,所有在内存中的数据丢失。从另外一个角度看Q断电造成内存数据丢失Q也可看作将内存清空Q而此前待机已l将盘关闭了。我们^时的正常x不就是在不会损坏盘的情况下其关闭Q然后切断内存电源关机目的吗Q从q个角度看,待机后断电就{同于安全关机。所以,当正常关机速度太慢Q就可以考虑先待机,然后拔电源来到达安全x目的。不q,在执行这Ҏ作前Q记得先保存未完成的工作Q比如打开的文档,正在q行的程序等?/p><p><em>提C?/em><br /><br />  q种xҎ虽然快捷Q但毕竟不是微Y推荐的方法,属于一U有风险的强q式xҎQ但׃它对盘没有影响Q所以不会造成g损坏Q特别适用于那些急于x的用戗比如同事在甉|口催促Cornel甉|来了Q让我赶快出门,只好用这U方法了?</p><img src ="http://www.tkk7.com/sk8boy/aggbug/45161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/sk8boy/" target="_blank">思?/a> 2006-05-09 10:48 <a href="http://www.tkk7.com/sk8boy/articles/45161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DUSE--让DOS支持USB驱动?转蝲http://publishblog.blogchina.com/blog/tb.b?diaryID=3749687)http://www.tkk7.com/sk8boy/articles/43102.html思?/dc:creator>思?/author>Tue, 25 Apr 2006 11:20:00 GMThttp://www.tkk7.com/sk8boy/articles/43102.htmlhttp://www.tkk7.com/sk8boy/comments/43102.htmlhttp://www.tkk7.com/sk8boy/articles/43102.html#Feedback0http://www.tkk7.com/sk8boy/comments/commentRss/43102.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/43102.html 
q好微Yq不能决定一切,Pocketec公司开发的DUSE׃ؓ我们提供了在DOS下对USB存储讑֤QUSB盘、Y驱、光驱)的支持,不过它目前还 不支持较常见的USB ThumbDriveQ即U盘)。若要在DOS下驱动USB的U盘,请用Motto Hairu驱动E序。另外,如果惛_UDOS下用其它USB讑֤Q如USB鼠标、USB打印机等Q则可以使用其它的USB驱动E序Q如USB_Link 中的OHCI/UHCIQ以及USB4DOS{,均可在本站的“驱动程序”中扑ֈ相应的链接,q可在“DOS使用中的常见问题解答(FAQ)”中看到一?DOS下用USB讑֤的信息?

DUSE是DOS下的USB存储讑֤的驱动程序,目前的最新版本ؓ4.2Q是今年刚推出的。它的用法很单,可在CONFIG.SYS中加载,也可以用?自带的DUSELDR.COME序来实现在DOS命o行下Q包括批处理文g中)的加载。例如在CONFIG.SYS中加上一行:DEVICE=C:\ DOS\DUSE.EXE或在DOS命o行下执行DUSELDR C:\DOS\DUSE.EXE均可?

如果要加载的是USB光驱Q除加蝲DUSE驱动E序外,q需q行光驱扩展驱动E序Q通常可以使用DOS自带的MSCDEX.EXE。DUSE的默认光p备名是USBCDROMQ在DOS命o行下可以像下面这栯行MSCDEX.EXEQ?

MSCDEX /D:USBCDROM /K

如果要更好地使用和控制DUSEQ可以用它提供的参敎ͼDUSE的运行参数如下表Q?
Q说明:以下为它?.2版的参数Q其最?.4版又增加了EMUIRQ、UBNU、DDWAIT{参数。[]中表C可以省略的Q以VER[BOSE]ZQVERBOSE是参数的完整写法Q而VER则是写,即[]中的BOSE可以省略。)

1: VER[BOSE][=x], 允许昄状态信息。x的合法值是0???表示不显CZ息,1表示昄文本消息Q?表示采用弹出式窗口显CZ息。默认gؓ0Q如果输入了VERBOSE参数但未讑֮x的值的话,默认gؓ2?
2: WAI[T]=x, 讄昄弹出式窗口到关闭此窗口的旉Q以U来计算Q。x的合法gؓ0?55之间Q默认gؓ3。只有当VERBOSE的gؓ2的时候此参数才有效?
3: DRI[VES]=x, 讄允许的USB驱动器的数目。X取g0?。如果设|ؓ0的话表示止USB驱动器的支持。默认gؓ1?
4: NOD[RIVES], 止对USB驱动器的支持。此参数覆盖DRIVES参数讄?
5: NOC[DROM], 止对USB CD-ROM光驱的支持?
6: MEM[POOL]=x, 讄分配附加的内存的大小。DUSE会根据USB控制器的数目、传输的速度{来q行计算Q确定最佛_配内存的大小。而设|此参数由用户军_内存分配的大,x值的单位为KBQ合法值在0?28之间?
7: XFER[SIZE]=x, 讄允许的最大传输缓冲区Qx值单位ؓKB来。增加传输缓冲区增Z输性能Q但也需要占用更多的内存。默认gؓ16?
8: SEC[TORSIZE]=x, 讄USB驱动器的扇区大小。x的值用字节来表C。合法gؓ512Q?024?048Q默认ؓ512?
9: APM[STATE]=x, 讄APMQ高U电源管理)功能已启用的USB讑֤中APM的别。增加此U别增加设备的性能Q但会增加电源的损耗。下面列Z合法的APM的状态x|
* 最大性能 FEh
* 无挂起功能时中间的电源管理?81h-FDh
* 无挂起功能时最电源损?80h
* 带挂起功能时中间的电源管理?02h-7Fh
* 带挂起功能时最电源损?01h
x的默认gؓ0x7F?
10: INT[13], 启用盘的INT13功能支持. 此功能对一些磁盘工P如FDISKQ提供支持?
11: DMA[SAFE], 分配在数据传输中使用的DMA安全~冲区。在q行一些需要从扩展内存中分配的~冲的应用程序时此参数是必须指定的?
12: NOU[HCI], 防止初始化UHCI USB控制器?
13: NOO[HCI], 防止初始化OHCI USB控制器?
14: NOE[HCI], 防止初始化EHCI USB控制器?
15: UHCN=x, 指定DUSE初始化的UHCI控制器的最大数目ؓx?
16: OHCN=x, 指定DUSE初始化的OHCI控制器的最大数目ؓx?
17: EHCN=x, 指定DUSE初始化的EHCI控制器的最大数目ؓx?
18: LATE[INIT], 启用“g时初始化”的功能. 当用此功能Ӟ驱动E序在DOS启动阶段从CONFIG.SYS文g中加载,但是直到在DOS命o中用INIT参数q行DUSE时才会正式启用USB 讑֤Q典型是在AUTOEXEC.BAT文g的结。可看下面的“g时初始化”和“将DUSE当作应用E序来运行”的部分?
19: EBAR=x, 指定EHCI BARQ基地址寄存器)被分配到内存中的地址。x的值必L四位?6q制数字q带上前~0xQ例如要EHCI BAR的地址|ؓ0xE000Q那么正的命o行选项是EBAR=0xE000。合法的地址区域?xA000?xF400之间?
20: OBAR=x, 指定OHCI BAR被分配到内存中的地址。上面对EBAR的描q可应用于OBAR?
21: UBAR=x, 指定UHCI BAR被分配到内存中的地址。上面对EBAR的描q可应用于UBARQ不q它的合法的地址区域?x0400?xF400之间?
22: CDW[AIT][=x], 指示DUSE的初始化要等到第一个USB CD-ROM光驱的盘W被分配Q或在xU钟之内不要l束。x的合法值在0?0之间。x=0是一个特D|它表CDUSE一直等到第一个USB CD-ROM光驱的盘W被分配或用h下键盘上的ESC键。如果没有指定x的值的话,默认为x=0?
23: CDD[EVICE]=<讑֤?gt;, 指定USB CD-ROM光驱的设备名。默认设备名是USBCDROM?
24: VFLOP[PY], 初始化时建立一个启动Y盘的虚拟映像?

以下是用一个命令行参数的例子。可参考此行把DUSE加入到CONFIG.SYS文g中:

DEVICE=C:\DUSE\DUSE.EXE VERBOSE DRIVES=2 XFER=8 SEC=2048 NOCD

此例子设|:
* 昄弹出式状态窗?
* 支持两个USB驱动?
* 最大传输缓冲区大小设ؓ8K
* 默认扇区大设?048字节
* 止对USB CD-ROM光驱提供支持

* 关于“g时初始化”的功能
当在CONFIG.SYS中以LATE[INIT]参数来运行DUSEQ例如用DEVICE=DUSE.EXE LATEQ时Q要真正使用USB讑֤q需q行一ơ真正的初始化。真正的初始化的Ҏ是在DOS命o行下Q包括批处理文g中)使用DUSE INIT命o?

* 关于“将DUSE当作应用E序来运行”的功能
DUSE当作应用E序来在DOS命o行下q行ӞDUSE只支持INIT参数。此参数在上面的“g时初始化”以后于DOS命o行上加蝲Q得DUSE真正初始化USB讑֤Q以真正使用USB讑֤?



]]>
RedHat下服务的启动配置http://www.tkk7.com/sk8boy/articles/37924.html思?/dc:creator>思?/author>Tue, 28 Mar 2006 15:01:00 GMThttp://www.tkk7.com/sk8boy/articles/37924.htmlhttp://www.tkk7.com/sk8boy/comments/37924.htmlhttp://www.tkk7.com/sk8boy/articles/37924.html#Feedback0http://www.tkk7.com/sk8boy/comments/commentRss/37924.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/37924.html ?/span> RedHat 下,发现有三个命令可以用来配|系l服务的启动Q分别是Q?/span>

l         ntsysv

l         chkconfig

l         serviceconf

其中Q?/span> serviceconf 是在 X 下面的图形化的配|,很方便,׃作过多的介绍。剩下的两个都是可以在终端启动的。其中, ntsysv 是终端下面的囑Ş化配|程序,默认是用来配|当前运行别的启动服务。但是可以通过在后面加入参?/span> --level xxx 来指定修Ҏ影响的运行别。其?/span> “xxx?/span> 表示q行U别的数字,?/span> 0 ?/span> 9 Q不加Q何空根{如Q?/span>

ntsysv --level 345

表示要对q行?/span> 3 ?/span> 4 ?/span> 5 U的相应服务的启动配|作修改。启动之后,q单的选择希望在指定别下自动启动的服务了?/span>

chkconfig 可以用来列出、添加和删除pȝ服务的信息。这里需要特别指出的是,当我们向pȝ中添加一个服务时Q如 Mysql Server Q如果不?/span> RPM 安装Q需要手动进行启动。这Ӟ我们可以?/span> MySQL 的启动脚本,可能?/span> mysql.server 拯?/span> /etc/init.d/ 目录下。根据喜好,也可以将其更名ؓ mysqld 。这h较符合系l的命名习惯。这ӞZ使该服务可以在系l启动的时候自动运行,可以采用如下命o来添加:

chkconfig –add mysqld on

默认情况下,参数 on ?/span> off ?/span> reset 只媄?/span> 2 ?/span> 3 ?/span> 4 ?/span> 5 U的pȝ启动信息。如果需要特D定Ӟ可以使用参数 --level 对其q行指定。方式跟 ntsysv ?/span> --level 参数一致?/span>



]]>
CVS的安装配|?/title><link>http://www.tkk7.com/sk8boy/articles/15649.html</link><dc:creator>思?/dc:creator><author>思?/author><pubDate>Sun, 16 Oct 2005 08:34:00 GMT</pubDate><guid>http://www.tkk7.com/sk8boy/articles/15649.html</guid><wfw:comment>http://www.tkk7.com/sk8boy/comments/15649.html</wfw:comment><comments>http://www.tkk7.com/sk8boy/articles/15649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/sk8boy/comments/commentRss/15649.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/sk8boy/services/trackbacks/15649.html</trackback:ping><description><![CDATA[     摘要: 1 准备 在安装之前,首先通过q行下面命o查看pȝ上是否已l安装了CVSQ? root# rpm –q cvs q是我系l上输出的内容: cvs-1.11.19-8 说明pȝ上已l安装了CVSQ要卸蝲再安装新的版本或者重新安装。可以输入如下命令进行卸载: root# rpm –e cvs q时pȝ输出如下提示Q? warning: /etc/xinetd.d/cvs s...  <a href='http://www.tkk7.com/sk8boy/articles/15649.html'>阅读全文</a><img src ="http://www.tkk7.com/sk8boy/aggbug/15649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/sk8boy/" target="_blank">思?/a> 2005-10-16 16:34 <a href="http://www.tkk7.com/sk8boy/articles/15649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一些有用的工具http://www.tkk7.com/sk8boy/articles/15648.html思?/dc:creator>思?/author>Sun, 16 Oct 2005 08:30:00 GMThttp://www.tkk7.com/sk8boy/articles/15648.htmlhttp://www.tkk7.com/sk8boy/comments/15648.htmlhttp://www.tkk7.com/sk8boy/articles/15648.html#Feedback0http://www.tkk7.com/sk8boy/comments/commentRss/15648.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/15648.htmlIperf  http://dast.nlanr.net/Projects/Iperf/

 Iperf was developed as a modern alternative for measuring TCP and UDP bandwidth performance.

Hping http://www.hping.org/

Hping is a command-line oriented TCP/IP packet assembler/analyzer.

Curl http://curl.haxx.se/

curl is a command line tool for transferring files with URL syntax, supporting FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. Curl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks.

adore-ng http://stealth.openwall.net/  rootkits

AIRT http://159.226.5.93/projects/airt.htm

        http://159.226.5.93/projects.htm

AIRT(Advanced incident response tool) is a set of incident response assistant tools on linux platform.

openhids http://www.openhids.com/download.html

stunnel   http://www.stunnel.org/

 engage            http://www.engagesecurity.com/

 Analog              http://www.analog.cx/

logfile analyser

sysinternals  http://www.sysinternals.com/ Tools for windows

FreeMind  http://freemind.sourceforge.net/wiki/index.php/Main_Page

free mind mapping software



]]>
从程序员角度看ELFQ{载)http://www.tkk7.com/sk8boy/articles/15646.html思?/dc:creator>思?/author>Sun, 16 Oct 2005 08:27:00 GMThttp://www.tkk7.com/sk8boy/articles/15646.htmlhttp://www.tkk7.com/sk8boy/comments/15646.htmlhttp://www.tkk7.com/sk8boy/articles/15646.html#Feedback0http://www.tkk7.com/sk8boy/comments/commentRss/15646.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/15646.htmlhttp://www.xfocus.net/articles/200109/260.htmlQ?BR>
原文:?ELF:From The Programmer's Perspective?BR>
作者:Hongjiu Lu <mailto: hjl@nynexst.com>
    NYNEX Science & Technology, Inc.
    500 Westchester Avenue
    White Plains, NY 10604, USA

译Qalert7 <mailto: alert7@21cn.com alert7@xfocus.org>

主页: http://www.xfocus.org
旉: 2001-9-10


★概要:

q片文档从程序员的角度讨Zlinux的ELF二进制格式。介l了一些ELF执行
文g在运行控制的技术。展CZ如何使用动态连接器和如何动态装载ELF?BR>我们也演CZ如何在LINUX使用GNU C/C++~译器和一些其他工h创徏׃n?BR>C/C++库?BR>
?前言

最初,UNIXpȝ实验?USL)开发和发布了Executable and linking Format
(ELF)q样的二q制格式。在SVR4和Solaris 2.x上,都做为可执行文g默认?BR>二进制格式。ELF比a.out和COFF更强大更灉|。结合一些适当的工PE序?BR>使用ELF可以在q行时控制程序的程?BR>

? ELFcd

三种主要的ELF文gcdQ?BR>
.可执行文Ӟ包含了代码和数据。具有可执行的程序?
    例如q样一个程?BR>    
    # file dltest
    dltest: ELF 32-bit LSB executable, Intel 80386, version 1,
        dynamically linked (uses shared libs), not stripped

.可重定位文gQ包含了代码和数据(q些数据是和其他重定位文件和׃n?BR>    object文g一赯接时使用的)
    例如q样文g

    # file libfoo.o
    libfoo.o: ELF 32-bit LSB relocatable, Intel 80386, version 1,
       not stripped

.׃nobject文gQ又可叫做共享库Q:包含了代码和数据Q这些数据是在连?BR>    时候被q接器ld和运行时动态连接器使用的)。动态连接器可能UCؓ
    ld.so.1,libc.so.1 或?ld-linux.so.1?BR>    例如q样文g
    
    # file libfoo.so
    libfoo.so: ELF 32-bit LSB shared object, Intel 80386, version
    1, not stripped

ELF section部分是非常有用的。用一些正的工具和技术,E序员就?BR>熟练的操作可执行文g的执行?BR>
? .init?fini sections

在ELFpȝ上,一个程序是由可执行文g或者还加上一些共享object文gl成?BR>Z执行q样的程序,pȝ使用那些文g创徏q程的内存映象。进E映?BR>有一些段(segment),包含了可执行指oQ数据,{等。ؓ了一个ELF文g
装蝲到内存,必须有一个program header(该program header是一个描q段
信息的结构数l和一些ؓE序q行准备的信??BR>
一个段可能有多个sectionl成.q些section在程序员角度来看更显的重要?BR>
每个可执行文件或者是׃nobject文g一般包含一个section table,该表
是描qELF文g里sections的结构数l。这里有几个在ELF文档中定义的比较
特别的sections.以下q些是对E序特别有用的:

.fini
    该section保存着q程l止代码指o。因此,当一个程序正帔R出时Q?nbsp;       
    pȝ安排执行q个section的中的代码?BR>.init    
    该section保存着可执行指令,它构成了q程的初始化代码?BR>    因此Q当一个程序开始运行时Q在main函数被调用之?c语言UCؓ
    main)Q系l安排执行这个section的中的代码?BR>
.init?fini sections的存在有着特别的目的。假如一个函数放?BR>.init sectionQ在main函数执行前系l就会执行它。同理,假如一
个函数放?fini sectionQ在main函数q回后该函数׃执行?BR>该特性被C++~译器用,完成全局的构造和析构函数功能?BR>
当ELF可执行文件被执行Q系l将在把控制权交l可执行文g前装载所以相?BR>的共享object文g。构造正的.init?fini sections,构造函数和析构函数
以正确的次序被调用?BR>
?.1 在c++中全局的构造函数和析构函数

在c++中全局的构造函数和析构函数必须非常心的处理碰到的语言规范问题?BR>构造函数必dmain函数之前被调用。析构函数必dmain函数q回之后
被调用。例如,除了一般的两个辅助启动文gcrti.o和crtn.o外,GNU C/C++
~译?-gccq提供两个辅助启动文件一个称为crtbegin.oQ还有一个被UCؓ
crtend.o。结?ctors?dtors两个sectionQc++全局的构造函数和析构函数
能以q行时最的负蝲Q正的序执行?BR>

.ctors
    该section保存着E序的全局的构造函数的指针数组?BR>
.dtors
    该section保存着E序的全局的析构函数的指针数组?nbsp;   

ctrbegin.o
    有四个section:
    1 .ctors section
    local标号__CTOR_LIST__指向全局构造函数的指针数组头。在
    ctrbegin.o中的该数l只有一个dummy元素?BR>
    [译注Q?BR>    # objdump -s -j .ctors                 
    /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o

    /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o:
    file format elf32-i386
    Contents of section .ctors:
    0000 ffffffff                             ....
    q里说的dummy元素应该是指的是ffffffff
    ]

    2 .dtors section
    local标号__DTOR_LIST__指向全局析构函数的指针数l头。在
    ctrbegin.o中的该数l仅有也只有一个dummy元素?BR>
    3 .text section
    只包含了__do_global_dtors_aux函数,该函数遍历__DTOR_LIST__
    列表Q调用列表中的每个析构函数?BR>函数如下Q?BR>
Disassembly of section .text:

00000000 <__do_global_dtors_aux>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 3d 04 00 00 00 00    cmpl   $0x0,0x4
   a:   75 38                   jne    44 <__do_global_dtors_aux+0x44>
   c:   eb 0f                   jmp    1d <__do_global_dtors_aux+0x1d>
   e:   89 f6                   mov    %esi,%esi
  10:   8d 50 04                lea    0x4(%eax),%edx
  13:   89 15 00 00 00 00       mov    %edx,0x0
  19:   8b 00                   mov    (%eax),%eax
  1b:   ff d0                   call   *%eax
  1d:   a1 00 00 00 00          mov    0x0,%eax
  22:   83 38 00                cmpl   $0x0,(%eax)
  25:   75 e9                   jne    10 <__do_global_dtors_aux+0x10>
  27:   b8 00 00 00 00          mov    $0x0,%eax
  2c:   85 c0                   test   %eax,%eax
  2e:   74 0a                   je     3a <__do_global_dtors_aux+0x3a>
  30:   68 00 00 00 00          push   $0x0
  35:   e8 fc ff ff ff          call   36 <__do_global_dtors_aux+0x36>
  3a:   c7 05 04 00 00 00 01    movl   $0x1,0x4
  41:   00 00 00
  44:   c9                      leave
  45:   c3                      ret
  46:   89 f6                   mov    %esi,%esi


    4 .fini section
    它只包含一个__do_global_dtors_aux的函数调用。请CQ它仅是
    一个函数调用而不q回的,因ؓcrtbegin.o?fini section是这?BR>    函数体的一部分?BR>函数如下Q?BR>Disassembly of section .fini:

00000000 <.fini>:
   0:   e8 fc ff ff ff          call   1 <.fini+0x1>


crtend.o
    也有四个section:

    1 .ctors section
    local标号__CTOR_END__指向全局构造函数的指针数组N?BR>
    2 .dtors section
    local标号__DTOR_END__指向全局析构函数的指针数l尾部?BR>
    3 .text section
    只包含了__do_global_ctors_aux函数,该函数遍历__CTOR_LIST__
    列表Q调用列表中的每个构造函数?BR>函数如下Q?BR>00000000 <__do_global_ctors_aux>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   bb fc ff ff ff          mov    $0xfffffffc,%ebx
   9:   83 3d fc ff ff ff ff    cmpl   $0xffffffff,0xfffffffc
  10:   74 0c                   je     1e <__do_global_ctors_aux+0x1e>
  12:   8b 03                   mov    (%ebx),%eax
  14:   ff d0                   call   *%eax
  16:   83 c3 fc                add    $0xfffffffc,%ebx
  19:   83 3b ff                cmpl   $0xffffffff,(%ebx)
  1c:   75 f4                   jne    12 <__do_global_ctors_aux+0x12>
  1e:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  21:   c9                      leave
  22:   c3                      ret
  23:   90                      nop

    4 .init section
    它只包含一个__do_global_ctors_aux的函数调用。请CQ它仅是
    一个函数调用而不q回的,因ؓcrtend.o?init section是这个函
    C的一部分?BR>函数如下Q?BR>Disassembly of section .init:

00000000 <.init>:
   0:   e8 fc ff ff ff          call   1 <.init+0x1>


crti.o
    ?init section中仅是个_init的函数标受?BR>    ?fini section中的_fini函数标号?BR>
crtn.o
    ?init?fini section中仅是返回指令?BR>
Disassembly of section .init:

00000000 <.init>:
   0:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
   3:   c9                      leave
   4:   c3                      ret
Disassembly of section .fini:

00000000 <.fini>:
   0:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
   3:   c9                      leave
   4:   c3                      ret

~译产生可重定位文gӞgcc把每个全局构造函数挂在__CTOR_LIST?BR>Q通过把指向构造函数的指针攑ֈ.ctors section中)?BR>它也把每个全局析构函挂在__DTOR_LIST上(通过把指向析构函的指?BR>攑ֈ.dtors section中)?BR>
q接Ӟgcc在所有重定位文g前处理crtbegin.o,在所有重定位文g后处?BR>crtend.o。另外,crti.o在crtbegin.o之前被处理,crtn.o在crtend.o之后
被处理?BR>
当生可执行文gӞq接器ld分别的连接所有可重定位文件的ctors ?BR>.dtors section到__CTOR_LIST__和__DTOR_LIST__列表中?init section
由所有的可重定位文g中_init函数l成?fini由_fini函数l成?BR>
q行Ӟpȝ在main函数之前执行_init函数Q在main函数q回后执?BR>_fini函数?BR>

? ELF的动态连接与装蝲

?.1 动态连?BR>
当在UNIXpȝ下,用C~译器把C源代码编译成可执行文件时Qc~译驱动器一?BR>调用C的预处理Q编译器Q汇~器和连接器?BR>
.     c~译驱动器首先把C源代码传到C的预处理器,它以处理q的宏和
    指示器Ş式输出纯C语言代码?BR>
.    c~译器把处理q的C语言代码译为机器相关的汇编代码?BR>
.    汇编器把l果的汇~语a代码译成目标的机器指o。结果这?BR>    机器指op存储成指定的二进制文件格式,在这里,我们使用?BR>    ELF格式?BR>
.    最后的阶段Q连接器q接所有的object文gQ加入所有的启动代码?BR>    在程序中引用的库函数?BR>
    下面有两U方法用lib?BR>    
    --static library
    一个集合,包含了那些object文g中包含的library例程和数据。用
    该方法,q接时连接器生一个独立的object文g(q些
    object文g保存着E序所要引用的函数和数?的copy?BR>    
    --shared library
    是共享文Ӟ它包含了函数和数据。用q样q接出来的程序仅在可执行
    E序中存储着׃n库的名字和一些程序引用到的标受在q行Ӟ动?BR>    q接器(在ELF中也叫做E序解释器)把׃n库映象到q程的虚?BR>    地址I间里去Q通过名字解析在共享库中的标号。该处理q程也称?BR>    动态连?dynamic linking)

E序员不需要知道动态连接时用到的共享库做什么,每g事情对程序员都是
透明的?BR>

?.2 动态装?Dynamic Loading)

动态装载是q样一个过E:把共享库攑ֈ执行时进E的地址I间Q在库中查找
函数的地址Q然后调用那个函敎ͼ当不再需要的时候,卸蝲׃n库。它的执?BR>q程作ؓ动态连接的服务接口?BR>
在ELF下,E序接口通常?lt;dlfcn.h>中被定义。如下:

void *dlopen(const char * filename,int flag);
const char * dlerror(void);
const void * dlsym (void handle*,const char * symbol);
int dlclose(void * handle);

q些函数包含在libdl.so中。下面是个例子,展示动态装载是如何工作的?BR>ȝ序在q行时动态的装蝲׃n库。一斚w可指出哪个共享库被用,哪个
函数被调用。一斚w也能在访问共享库中的数据?

[alert7@redhat62 dl]# cat dltest.c
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <dlfcn.h>
#include <ctype.h>

typedef void (*func_t) (const char *);

void dltest(const char *s)
{
    printf("From dltest:");
    for (;*s;s++)
    {    
        putchar(toupper(*s));
    }
    putchar('\n');
}

main(int argc,char **argv)
{
void *handle;
func_t fptr;
char * libname = "./libfoo.so";
char **name=NULL;
char *funcname = "foo";
char *param= "Dynamic Loading Test";
int ch;
int mode=RTLD_LAZY;    

while ((ch = getopt(argc,argv,"a:b:f:l:"))!=EOF)
{
    switch(ch)
    {
    case 'a':/*argument*/
        param=optarg;
        break;
    case 'b':/*how to bind*/
        switch(*optarg)
        {
        case 'l':/*lazy*/
        mode = RTLD_LAZY;
        break;
        case 'n':/*now*/
        mode = RTLD_NOW;
        break;
        }
        break;
    case 'l':/*which shared library*/
        libname= optarg;
        break;
    case 'f':/*which function*/
        funcname= optarg;
    }
   }

handle = dlopen(libname,mode);
if (handle ==NULL)
{
fprintf(stderr,"%s:dlopen:'%s'\n",libname,dlerror());
exit(1);
}

fptr=(func_t)dlsym(handle,funcname);
if (fptr==NULL)
{
fprintf(stderr,"%s:dlsym:'%s'\n",funcname,dlerror());
exit(1);
}


name = (char **) dlsym(handle,"libname");
if (name==NULL)
{
fprintf(stderr,"%s:dlsym:'libname'\n",dlerror());
exit(1);
}

printf("Call '%s' in '%s':\n",funcname,*name);

/*call that function with 'param'*/
(*fptr)(param);

dlclose(handle);
return 0;

}

q里有两个共享库Q一个是libfoo.so一个是libbar.so。每个都用同L全局
字符串变量libname,分别各自有foo和bar函数。通过dlsymQ对E序来说,他们
都是可用的?BR>
[alert7@redhat62 dl]# cat libbar.c
#include <stdio.h>

extern void dltest(const char *);
const char * const libname = "libbar.so";

void bar (const char *s)
{
dltest("Called from libbar.");
printf("libbar:%s\n",s);
}


[alert7@redhat62 dl]# cat libfoo.c
#include <stdio.h>

extern void dltest (const char *s);
const char *const libname="libfoo.so";

void foo(const char *s)
{
    const char *saved=s;
    
    dltest("Called from libfoo");
    printf("libfoo:");
    for (;*s;s++);
    for (s--;s>=saved;s--)
    {
    putchar (*s);
    }
    putchar ('\n');
}

使用Makefile文g来编译共享库和主E序是很有用的。因为libbar.so?BR>libfoo.so也调用了ȝ序里的dltest函数?BR>
[alert7@redhat62 dl] #cat Makefile
CC=gcc
LDFLAGS=-rdynamic
SHLDFLAGS=
RM=rm

all:dltest

libfoo.o:libfoo.c
    $(CC) -c -fPIC $<

libfoo.so:libfoo.o
    $(CC) $(SHLDFLAGS) -shared -o $@ $^

libbar: libbar.c
    $(CC) -c -fPIC $<

libbar.so:libbar.o
    $(CC) $(SHLDFLAGS) -shared -o $@ $^

dltest: dltest.o libbar.so libfoo.so
    $(CC) $(LDFLAGS) -o $@ dltest.o -ldl

clean:
    $(RM) *.o *.so dltest

处理程Q?BR>
[alert7@redhat62 dl]# export ELF_LD_LIBRARY_PATH=.
[alert7@redhat62 dl]# ./dltest
Call 'foo' in 'libfoo.so':
From dltest:CALLED FROM LIBFOO
libfoo:tseT gnidaoL cimanyD
[alert7@redhat62 dl]# ./dltest -f bar
bar:dlsym:'./libfoo.so: undefined symbol: bar'
[alert7@redhat62 dl]# ./dltest -f bar -l ./libbar.so
Call 'bar' in 'libbar.so':
From dltest:CALLED FROM LIBBAR.
libbar:Dynamic Loading Test


在动态装载进E中调用的第一个函数就是dlopen,它得共享可库对
q行着的进E可用。dlopenq回一个handle,该handle被后面的dlsym
和dlclose函数使用。dlopen的参CؓNULL有特D的意?--它得在
E序导出的标号和当前已经装蝲q内存的׃n库导出的标号通过dlsym
可利用?BR>
在一个共享库已经装蝲q运行着的进E的地址I间后,dlsym可用?BR>获得在共享库中导出的标号地址。然后就可以通过dlsymq回的地址
来访问里面的函数和数据?BR>
当一个共享库不再需要用的时候,可以调用dlclose卸蝲该函数库?BR>假如׃n库在启动时刻或者是通过其他的dlopen调用被装载的话,?BR>׃n库不会从调用的进E的地址I间被移走?BR>
假如dlclose操作成功Q返回ؓ0。dlopen和dlsym如果有错误,返?BR>为NULL。ؓ了获取诊断信息,可调用dlerror.


? 支持ELF的LINUX上的~译器GNU GCC

感谢Eric Youngdale (eric@aib.com),lan Lance Taylor (ian@cygnus.com)
q有许多为gcc支持ELF功能的默默做贡献的h。我们能用gcc和GNU的二q制
工具很容易的创徏ELF可执行文件和׃n库?BR>
?.1 ׃nC?Shared C Library

在ELF下构造一个共享库比其他的Ҏ的多。但是需要编译器Q汇~器Q?BR>q接器的支持。首先,需要生位|无?position-independent)代码?BR>要做到这一点,gcc需要加上编译选项-fPIC
[alert7@redhat62 dl]# gcc -fPIC -O -c libbar.c

q时候就适合构造共享库了,加上-shared~译选项
[alert7@redhat62 dl]# gcc -shared -o libbar.so libbar.o

现在我们构造的libbar.so可以被q接?link editor)和动态连接器
(dynamic linker)。只要编译时带上-fPIC~译选项,可以把许多重定位
文g加到׃n库中。ؓ了把baz.o和共享库q接在一P可以如下操作Q?BR># gcc -O -c baz.c
# gcc -o baz baz.o -L. -lbar

在把libbar.so安装到动态连接器能找到的正确位置上之后,q行baz?BR>使libbar.so映象到baz的进E地址I间。内存中libbar.so的一份拷贝将
被所有的可执行文?q些可执行程序连接时和它一块儿q接的或?BR>在运行时动态装载的)׃n?BR>
?.2 ׃nC++?Shared C++ Library

在共享c++库中主要的困难是如何对待构造函数和析构函数?BR>在SunOS下,构造和使用一个共享的ELF C库是Ҏ的,但是在SunOS下不?BR>构造共享的C++库,因ؓ构造函数和析构函数有特别的需求。ؓ止,在ELF
中的.init?init section提供了完的解决Ҏ?BR>
当构造共享C++库时Q我们用crtbegin.o和crtend.oq两个特D的版本Q?BR>(它们已经是经q?fPIC?。对于连接器(link editor)来说Q构造共?BR>的C++库几乎是和一般的可执行文件一L。全局的构造函数和析构函数
?init?fini section处理(在上?.1节中已经讨论q??BR>
但一个共享库被映到q程的地址I间Ӟ动态连接器在传控制权l程?BR>之前执行_init函数Qƈ且将为_fini函数安排在共享库不再需要的时候被
执行?BR>
q接选项-shared是告诉gcc以正的序攄必要的辅助文件ƈ且告诉它?BR>产生一个共享库?v选项显CZ么文件什么选项被传Cq接?BR>(link editor).

[alert7@redhat62 dl]# gcc -v -shared -o libbar.so libbar.o
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/collect2 -m elf_i386
-shared -o libbar.so /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat
    -linux/egcs-2.91.66/crtbeginS.o
-L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66
-L/usr/i386-redhat-linux/lib libbar.o -lgcc -lc --version-script
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/libgcc.map
-lgcc /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtendS.o
/usr/lib/crtn.o

crtbeginS.o和crtendS.o?fPIC~译的两个特D的版本。带?shared
创徏׃n库是重要的,因ؓ那些辅助的文件也提供其他服务。我们将?BR>5.3节中讨论?BR>
?.3 扩展的GCCҎ?BR>
GCC有许多扩展的Ҏ。有些对ELF特别的有用。其中一个就是__attribute__?BR>使用__attribute__可以使一个函数放到__CTOR_LIST__或者__DTOR_LIST__里?BR>例如Q?BR>
[alert7@redhat62 dl]# cat miss.c

#include <stdio.h>
#include <stdlib.h>

static void foo(void) __attribute__ ((constructor));
static void bar(void) __attribute__ ((destructor));


int main(int argc, char *argv[])
{
        printf("foo == %p\n", foo);
        printf("bar == %p\n", bar);

        exit(EXIT_SUCCESS);
}

void foo(void)
{
        printf("hi dear njlily!\n");
}

void bar(void)
{
        printf("missing u! goodbye!\n");
}

[alert7@redhat62 dl]# gcc -o miss miss.c
[alert7@redhat62 dl]# ./miss
hi dear njlily!
foo == 0x8048434
bar == 0x8048448
missing u! goodbye!

我们来看看是否加C.ctors?dtors中?BR>[alert7@redhat62 dl]# objdump -s -j .ctors miss

miss:     file format elf32-i386

Contents of section .ctors:
8049504 ffffffff 34840408 00000000           ....4.......

[alert7@redhat62 dl]# objdump -s -j .dtors miss

miss:     file format elf32-i386

Contents of section .dtors:
8049510 ffffffff 48840408 00000000           ....H.......

已经把foo和bar地址分别攑ֈ?ctors?dorsQ显C?4840408只是因ؓ
x86上是LSB~码的,端序?BR>
__attribute__ ((constructor))促函数foo在进入main之前会被自动调用?BR>__attribute__ ((destructor))促函数bar在mainq回或者exit调用之后
会被自动调用。foo和bar必须是不能带参数的而且必须是static voidcd?BR>函数。在ELF下,q个Ҏ在一般的可执行文件和׃n库中都能很好的工作?BR>

我们也可以创qsection,在这里我创徏了一个alert7 section.
[alert7@redhat62 dl]# cat test.c
#include <stdio.h>
#include <stdlib.h>

static void foo(void) __attribute__ ((section ("alert7")));
static void bar(void) __attribute__ ((section ("alert7")));


int main(int argc, char *argv[])
{
        foo();

        printf("foo == %p\n", foo);
        printf("bar == %p\n", bar);
        bar();
        exit(EXIT_SUCCESS);
}

void foo(void)
{
        printf("hi dear njlily!\n");
}
void bar(void)
{
        printf("missing u! goodbye!\n");
}
[alert7@redhat62 dl]# gcc -o test test.c
[alert7@redhat62 dl]# ./test
hi dear njlily!
foo == 0x804847c
bar == 0x8048490
missing u! goodbye!

[alert7@redhat62 dl]# objdump -x test
....
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480f4  080480f4  000000f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
...
12 alert7        00000026  0804847c  0804847c  0000047c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
...

[alert7@redhat62 dl]# objdump -D test
Disassembly of section alert7:

0804847c <foo>:
804847c:       55                      push   %ebp
804847d:       89 e5                   mov    %esp,%ebp
804847f:       68 de 84 04 08          push   $0x80484de
8048484:       e8 a3 fe ff ff          call   804832c <_init+0x70>
8048489:       83 c4 04                add    $0x4,%esp
804848c:       c9                      leave
804848d:       c3                      ret
804848e:       89 f6                   mov    %esi,%esi

08048490 <bar>:
8048490:       55                      push   %ebp
8048491:       89 e5                   mov    %esp,%ebp
8048493:       68 ef 84 04 08          push   $0x80484ef
8048498:       e8 8f fe ff ff          call   804832c <_init+0x70>
804849d:       83 c4 04                add    $0x4,%esp
80484a0:       c9                      leave
80484a1:       c3                      ret

在这里,我创Z一个自qalert7 section,q把foo,bar两个函数攑ֈ了这?BR>section中。一般定义的函数都会攑֜.text section中?BR>


?.3.1 在C库中的初始化函数

另外一个GCC的特性是__attribute__( section ("sectionname") ).使用q个Q?BR>能把一个函数或者是数据l构攑ֈM的section中?BR>
static void
foo (int argc,char **argc,char **envp)
    __attribute__ ((section ("_libc_foo")));

static void
foo (int argc,char **argv,char **envp)
{
}

static void
bar (int argc,char **argv,char **envp)
{
}

static void * __libc_subinit_bar__
    __attribute__ (( section ("_libc_subinit")))=&(bar);

q里Q我们把foo攑ֈ了_libc_foo sectionQ把__libc_subinit_bar__?BR>C_libc_subinit section中。在Linux C库中Q_libc_subinit 是一个特?BR>的sectionQ它包含了一个函数指针(有如下原型)的数l?BR>
void (*) (int argc,char **argv,char **envp);

q里的argc,argv,envp跟在main中的有同L意义。该section中的函数在进?BR>main函数之前׃被调用。这是很有用的,可用来在Linux C库中初始化一?BR>全局变量?BR>
    [译注Q_libc_subinit section真有q个特别的功能吗Q我是没有试
    成功Q如果有成功或者认为我理解有误的地方,千万记得maill?BR>    ?)
    试E序如下Q?BR>    #include <stdio.h>
    #include <stdlib.h>
    static void foo(int argc,char **argv,char **envp)
    {
        printf("hi dear njlily!\n");
    }
    
    int main(int argc, char *argv[])
    {
        printf("foo == %p\n", foo);
        exit(EXIT_SUCCESS);
    }
    
    static void * __libc_subinit_bar__
            __attribute__ (( section ("_libc_subinit")))=&(foo);
    
    [alert7@redhat62 dl]# gcc -o test1 test1.c
    [alert7@redhat62 dl]# ./test1
    foo == 0x8048400
    :( 用objdumpQ显C已l创Z一个_libc_subinit section,q且
    该section前四个字节就是foo地址0x8048400
    
    ]



?.4 利用GCC和GNU ld

q一些命令行的选项对GCC和GNU ld创徏ELF时特别有用?shared告诉gcc
产生一个共享库Q该׃n库能在连接时和其他的׃n文g一起Ş成可执行
文gQ该׃n库也能在q行时装载进可执行文件的地址I间。?shared
是创Z个共享ELF库的首选方法?BR>
另外一个有用的命o行选项?Wl,ldoption,传递参数ldoption作ؓq接?BR>的选项。假如ldoption包含多个逗号Q将分离成多个选项?BR>
-static选项生一个和static库一道连接的可执行文件。当没有开?BR>-static选项Ӟq接器首先试着用共享库Q假如共享版本不可用Q然?BR>再试着用静?static)库?BR>
q里q有些特别的命o行选项对ELF来说特别的或者说是有用的?BR>
-dynamic-linker file
    讄动态连接器(dynamic linker)的名字。默认的动态连接器
    或者是/usr/lib/libc.so.1或者是/usr/lib/libd1.so.1
    

-export-dynamic
    告诉q接器在可执行文g中的所有标号对动态连接器可用。当一?BR>    动态装载进的共享库参考可执行文g中的标号Q该标号一般在动态连
    接时是不可用Ӟq时候就特别有用?BR>
-lfile
    加文件到需要连接的列表中。该选项可用在许多时候。ld搜索它?BR>    path-list查找文glibfile.so(也就是说假如库ؓlibbar.soQ那?BR>    使用的时候就q样使用Q?lbar),或者libfile.aQstatic版本的)?BR>    一些情况下Q共享库名libfile.so会被存储在resulting executable
    或者是׃n库中。当resulting executable或者是׃n库被装蝲q内
    存,动态连接器也将把用记录过的共享库装蝲到进E的地址I间厅R?BR>    在以后的事情情况下,把必要的函数和数据被拯到可执行文gQ减
    代码长度?BR>
-m emulation
    仿效emulationq接器r.-V参数可列出所有可用的选项.

-M | -Map mapfile
    把连接map输出到标准输出或者一个mapfile文g里,该连接map含有
    关于标号被ld映象C哪里的一些诊断信息,q有全局共同的存?BR>    分配信息?BR>
-rpath directory
    加一个目录到q行时library的搜索\径。所有的-rpath参数被连?BR>    在一L后传l动态连接器。它们被用来在运行时定位׃n库?BR>
-soname name
    当创Z个共享库Ӟ指定的名字被攑֜׃n库中。当和这个共?BR>    库连接的可执行文件被q行Q动态连接器试着map记录着的指?BR>    名字的共享库而不是传l连接器的文件名?BR>
-static
    告诉q接器不要和M׃n库连接?BR>
-verbose
    告诉q接器打印它每个要打开的文件名?BR>
linux下gcc beta版本使用-dynamic-linker file选项讄动态连接器?BR>/lib/ld-linker.so.1。该选项可以使ELF和a.out׃n库很好的共存?BR>
有g事情是另人感兴趣的?BR>
[alert7@redhat62 dl]# gcc -shared -o libbar.so libbar.o -lfoo

假如libfoo.so被用来创建共享库Ӟ有趣的时候就会发生了。当libbar.so
被映象到q程的地址I间的时候,动态连接器也把libfoo.so映象到内存?BR>假如libbar.so需要libfoo.so的时候,q个Ҏ非常有用。实际上使用
libbars.o库的E序~译时是不需?lfoo的。假如archive版本的libfoo.a
被用,当在libbar.a中的标号被libbar.o引用Ӟ它将会被搜烦到。假使在
libbar.so中包含libfoo.a甚至它们Ҏ不被libbar.o使用Q在q样的情况下
必须逐步?o文g加到libbar.o中:

# rm -rf /tmp/foo
# mkdir /tmp/foo
# (cd /tmp/foo/;ar -x ....../libfoo.a)
# gcc -shared -o libbar.so libbar.o /tmp/foo/*.o
# rm -rf /tmp/foo

在libfoo.a中的.o文g必须?fPIC~译或者至和PICQ位|无养I?BR>兼容的?BR>
当?BR>
static void * __libc_subinit_bar__
    __attribute__    ((section ("_libc_subinit")))=&(bar);

来把一个标hC个没有被q接器定义的section中(在这里是
_libc_subinit).q接器将所有在_libc_subinit section中的标号共同
创徏两个标号Q一个是__start__libc_subinit和__stop__libc_subinit,
它们作ؓC的标志符被用?BR>
警告Q?BR>下面是完全可能的Q连接器可能不能搜烦到包含_libc_subinit section
的文?该section中没有程序执行需要的标号)。这׃ɽE序要确定
_libc_subinit section能被q接器搜索得到?BR>
一U解决的办法是:把一个dummy标号攑ֈ_libc_subinit section中,
在文件中定义它,使它参考引用_libc_subinit section.


?.5 Linux下的ELF

在Linux下ELF的执行有独特的特性,q些Ҏ对Linux的用者来说是很有?BR>的。一些Linux自己的扩展跟Solaris ELF的执行很cM?BR>
?.5.1 ELF的宏(macros)

<gnu-stabs.h>中,定义了能l护标号的一些宏?BR>
elf_alias(name1,name2)
    为标号name1定义一个化名name2.当文件中标号名已l被定义的时?BR>    应该是有很用的?BR>
weak_alias(name1,name2)
    为标号name1定义一个弱化名name2。仅当name2没有在Q何地方定?BR>    Ӟq接器就会用name1解析name2相关的符受在文g中定义的
    标号name1也会同样处理?BR>
elf_set_element(set,symbol)
    标号成ؓset集合的元素。ؓ每个set集合创徏一个section.

symbol_set_declare(set)
    在该模块中宣告一个集合set.事实上宣告了两个标号Q?BR>    1  一个set的开始标?BR>    extern void * const __start_set
    2  一个set的结标?BR>    extern void * const __stop_set

symbol_set_first_element(set)
    q回一个指?void * const *),指向set集合W一个元素?BR>
symbol_set_end_p(set,ptr)
    假如ptr(void * const *)逐渐增加指向set的最后一个元素,
    p回ؓtrue.

使用q些宏,E序员能L从不同的源文件中创徏列表?BR>

?.5.2 library(?的定位和搜烦路径

在Linux下,大部分系l的library库被安装?usr/lib目录下。只有一?BR>基本的共享库被安装在/lib目录下。例如:libc.so,libcurses.so,libm.so
,libtermcap.so(各个版本对应的文件会有些不同)Q在其他部分被mount?BR>之前Q那些文件是启动Linuxpȝ所必须的。连接器默认的搜索\径是
/lib,/usr/lib,/usr/local/lib,/usr/i486-linux/lib?BR>
环境变量LD_LIBRARY_PATH也可保存目录列表Q用(:)分开Q该变量被动?BR>q接器检查ƈ用该变量指出的目录查扑օ享库?BR>例如Q?usr/X11R6/lib:/usr/local/lib:告诉动态连接器查找׃n库除?BR>现在在默认的目录查找外,然后?usr/X11R6/lib目录Q然后再?BR>/usr/local/lib目录Q然后再是当前目录?BR>
新的环境变量ELF_LD_LIBRARY_PATH扮演着和LD_LIBRARY_PATHcM的角艌Ӏ?BR>因ؓLD_LIBRARY_PATH也被老的a.out DLL linux的共享库使用。ؓ了避?BR>来自DLLq接器的不必要的警告Q对于在Linux下ELF的动态连接器来说Q?BR>最好用LD_LIBRARY_PATH环境变量?BR>
另外一个特性是/etc/ld.so.conf文gQ该文g包含了一些目录列表?BR>例如Q?BR>
/usr/X11R6/lib
/usr/lib
/usr/kerberos/lib
/usr/i486-linux-libc5/lib
/usr/lib/gconv
/usr/lib/qt-2.1.0/lib
/usr/lib/qt-1.45/lib

E序ldconfig把/etc/ld.so.conf文g中列出的搜烦目录中的所有的
׃n库存储到/etc/ld.so.cache中。假如共享库已经被从默认的目录中
U走QLinux ELF动态连接库在/etc/ld.so.cache文g中找该共享库?BR>


?.5.3 ׃n库的版本

在ELFpȝ上,假如两个׃n库有同样的应用程序二q制接口(ABI)的子?BR>的话,寚w些仅仅用那些ABI子集的程序来_q两个共享库是可以互?BR>通用的(当然那两个共享库有同L函数功能Q?BR>
当一个库被改变,只要新的ABI和前面一个版本的׃n库有100%的兼容的话,
所有和前面版本q接的程序在新的׃n库下也能很好的运行。ؓ了支持这Q?BR>foo库必d心的l护Q?BR>
1.q个׃n库应该如下构造:

[alert7@redhat62 dl]# gcc -shared -Wl,-soname,libfoo.so.major \
    -o libfoo.so.major.minor.patch-level libfoo.o

动态连接器q行时将试着定位和映象libfoo.so.major而不事实上用的׃n
文g名libfoo.so.major.patch-level?BR>
2.一个符可接应该指向正的׃n?BR>
[alert7@redhat62 dl]# ln -s libfoo.so.major.minor.patch-level \
    libfoo.so.major

3.当ABI改变和原来版本不兼容的时Q主(major)版本号应该升U?BR>
当搜索共享库的时候,Linuxq接器将使用最新的׃n库(它们有最高的
major,minor和patch level的版本号Q?BR>

?.5.4 ׃n(shared)库和静?static)库的混合q接

默认情况下,假如׃n库可用,q接器会使用׃n库。但?Bdynamic?BR>-Bstatic提供了很好控制库的方法。它们可以决定用׃n库还是用静态库?BR>
?Bdynamic?Bstatic选项l连接器Q如下操作:
# gcc -o main main.o -Wl,-Bstatic \
    -lfoo -Wl,-Bdynamic -lbar

# gcc -o main main.o -Wl,-Bstatic
告诉q接器所有的?象libc{等)都用静态的版本?BR>

?.5.5 装蝲附加的共享库

在ELFpȝ上,Z执行一个ELF文gQ内核要把控制权交给动态连接器
ld-linux.so.1(在linux上动态连接器是ld-linux.so.1Q版本不同也会不同的Q?BR>在默认的redhat6.2上是/lib/ld-linux.so.2)。在l对路径/lib/ld-linux.so.1
以二q制存放着。假如动态连接器不存在,没有哪个ELF可执行文件能q行?BR>
动态连接器执行以下一个步骤完成从E序到进E映象:

    1.分析可执行文件中的动态信息sectionQ决定需要哪些库?BR>
    2.定位和映?map)那些׃n库,q且分析它们动态信息section
      军_是否需要附加的׃n库?BR>
    3.为可执行E序和那些需要的׃n库执行重定位?BR>
    4.调用׃n库中提供的Q何初始化函数q且安排׃n库提供的
      清除(cleanup)函数在共享库卸栽E空间的时候运行?BR>
    5.传控制给E序

    6.为应用程序提供函数的qg装定服务

    7.为应用程序提供动态{载服务?BR>
环境变量LD_PRELOAD讄׃n库名或者用":"把文件名隔开。动态连接器?BR>M那些h的共享库之前把环境变量LD_PRELOAD的共享库装蝲到进E地址
I间厅R例如:

# LD_PRELOAD=./mylibc.so myprog

q里./mylibc.so第一旉map到程序myprog的空间。因为动态连接器在找
LL时候L使用W一ơ碰到的标号Q所以我们可以用LD_PRELOAD?BR>覆盖标准׃n库中的函数。这个特性对E序员来说是很有用的Q可用来在还
没有建好整个׃n库的时候对单个函数功能先做调试实验?BR>
我们可以q样Q?BR>#gcc -c -fPIC -O3 print.c
#gcc -shared print.o -o print.so.1.0
创徏自己的共享连接库

?.5.6 Linux下动态装?Dynamic loading)

_dlinfo是动态连接接口库的一个函数。它列出所有映到执行E序和通过
dlopen打开的每个共享库。它的输出类试以下:

List of loaded modules
    00000000 50006163 50006200 Exe 1
    50007000 5000620c 50006200 Lib 1 /lib/elf/libd1.so.1
    5000a000 500062c8 50006200 Lib 2 /lib/elf/libc.so.4
    50000000 50006000 00000000 Int 1 /lib/elf/ld-linux.so.1
    500aa000 08006f00 08005ff0 Mod 1 ./libfoo.so

Modules for application (50006200):
    50006163
    5000620c /lib/elf/libdl.so.1
    500062c8 /lib/elf/libc.so.4
    50006000 /lib/ld-linux.so.1
Modules for handle 8005ff0
    08006f00 ./libfoo.so
    500062c8 /lib/elf/lib.so.4
    50006163
    5000620c /lib/elf/libd1.so.1
    500062c8 /lib/elf/libc.so.4
    50006000 /lib/elf/ld-linux.so.1

以上可被用来解释动态的q接和动态的装蝲?BR>
在linux支持ELF上配|的GCC假如使用?rdynamic选项Q它把
-export-dynamic传给q接器。强烈徏议用动态装载。这是Z么在
我们的Makefile例子中用了LDFLAGS=-rdynamic。暂Ӟq个选项只能?BR>linux下用。但?Wl,-export-dynamic能在其他的^C?export-dynamic
传给GNU的连接器?BR>
你能在GNU link editor的[3]和[4]部分扑ֈ它详l的描述?BR>

? 位置无关代码(PIC)的汇~语a~程

当用gcc指定-fPIC的时候,gcc从C源代码中产生PIC的汇~语a代码。但?BR>时候,我们需要用汇编语言来生PIC代码?BR>
在ELF下,PIC的实现是使用基寄存器(base register)。在PIC下,所有的
标号引用都是通过基寄存器实现的,为此Q要用汇~写PIC的话Q必M?BR>基寄存器(base register)。由于位|无关代码,控制传送指令的目的地址
必须被替换或者是在PIC情况下计的。对X86机器来说Q该基寄存器
(base register)是ebx.q里我们介l在X86上安全的PIC汇编代码?BR>两种Ҏ。这些技术在Linux C库中也被使用到?BR>

?.1 在C中内嵌汇~?BR>
gcc支持内嵌汇编的声明,可让E序员在C语言中用汇~语a。当写LINUXp?BR>l调用接口的时候这是很有用的,而无M用机器相x令?BR>
在linux 下系l调用是通过int $0x80的。一般的Q系l调用会有三个参?

#include <sys/syscall.h>

extern int errno;

int read( int fd,void *buf ,size count)
{
long ret;

__asm__ __volatile__ ("int $0x80"
        :"=a"(ret)
        :"O"(SYS_read),"b"((long)fd),
         "c"((long)buf),"d"((long)count):"bx");
    
    if (ret>=0)
    {
    return (int) ret:
    }
    errno=-ret;
retrun -1;
}

以上汇编代码把系l调用号SYS_read攑ֈ了eax中,fd到ebx中,buf?BR>ecx中,count到edx中,从int $0x80中返回值ret攑֜eax中。在不用
-fPIC的情况下Q这样定义运行良好。带-fPIC的gcc应该要检查ebx是否?BR>被改变,q且应该在汇~代码里保存和恢复ebx。但是不q的是,事实上不?BR>q样的。我们ؓ了支持PIC必须自己写汇~代码?BR>
#include <sys/syscall.h>

extern int errno;

int read( int fd,void *buf ,size count)
{
long ret;

__asm__ __volatile__ ("pushl %%ebx\n\t"
        "movl %%esi,%%ebx\n\t"        
        "int $0x80\n\t"
        "popl %%ebx"
        :"=a"(ret)
        :"O"(SYS_read),"S"((long)fd),
         "c"((long)buf),"d"((long)count):"bx");
    
    if (ret>=0)
    {
    return (int) ret:
    }
    errno=-ret;
return -1;
}

q里首先把fd攑ֈesi中,然后保存ebx,把esiUdebxQ在int $0x80后恢?BR>ebx。这样保证ebx不被改变(除了在int $0x80中断调用?。同L原则?BR>适用于其他内嵌的汇编?BR>
在Q何时候,当ebx可能要被改变Ӟ千万要记得保存和恢复ebx.


?.2 用汇~语a~程

假如我们在系l调用时需要传5个参数时候,内嵌的汇~代码即使是PIC
的,也不能工作,因ؓx86没有_的寄存器。我们需要直接用汇编语言
~写?BR>
syscall(int syscall_number,...)的一般汇~代码如下:

    .file "syscall.S"
    .text
    .global syscall
    .global errno
    .align 16

syscall:
    pushl 5ebp
    movl %esp,%ebp
    pushl %edi
    pushl %esi
    pushl %ebx
    movl 8(%ebp),%eax    
    movl 12(%ebp),%ebx    
    movl 16(%ebp),%ecx    
    movl 20(%ebp),%edx    
    movl 24(%ebp),%esi    
    movl 28(%ebp),%edi    
    int $0x80
    test %eax,%eax
    jpe .LLexit
    negl %eax
    movl %eax,errno
    movl $-1, %eax

.LLexit:
    popl %ebx
    popl %esi
    popl %edi
    movl %ebp,%esp
    popl %ebp
    ret
    .type syscall,@function
.L_syscall_end:
    .size syscall,.L_syscall_end -syscall

在PIC下,我们必须通过GOT(global offset table)来访问Q何全局变量
(除了保存在基寄存器ebx中的)。修改的代码如下Q?BR>
.file "syscall.S"
.text
.global syscall
.global errno
.align 16
syscall:
    pushl %ebp
    movl %esp,%ebp
    pushl %edi
    pushl %esi
    pushl %ebx
    call .LL4
.LL4:
    popl %ebx
    addl $_GLOBAL_OFFSET_TABLE_+[.- .LL4],%ebx
    pushl %ebx
    movl 8(%ebp),%eax
    movl 12(%ebp),%ebx
    movl 16(%ebp),%ecx
    movl 20(%ebp),%edx
    movl 24(%ebp),%esi
    movl 28(%ebp),%edi
    int $0x80
    popl %ebx
    movl %eax,%edx
    test %edx,%edx
    jge .LLexit
    negl %edx
    movl errno@GOT(%ebx),%eax
    movl %edx,(%eax)
    movl $-1,%eax
.LLexit:
    popl %ebx
    popl %esi
    popl %edi
    movl %ebp,%esp
    popl %ebp
    ret
    .type syscall,@function
.L_syscall_end:
    .size syscall,.L_syscall_end-syscall

假如要得到PIC的汇~代码,但是又不知道如何写,你可以写一个C的,然后如下
~译Q?BR>
#gcc -O -fPIC -S foo.c

它将告诉gcc产生汇编代码foo.s输出,Ҏ需要,可以修改它?BR>

? l束?BR>
Ҏ以上讨论的,我们可以得出q样的结论:ELF是非常灵zȝ二进制格式?BR>它提供了非常有用的功能。这U规范没有给E序和程序员太多限制。它?BR>创徏׃n库容易,使动态装载和׃n库的l合更加Ҏ。在ELF下,在C++
中,全局的构造函数和析构函数在共享库和静态库中用同样Ҏ处理?BR>

[译注Q?BR>    到此Q文章是译好了Q但里面的一些东西看h可能
    有点问题Q比如说_libc_subinit section没有他说?BR>    那个功能Q?dynamic-linker选项在默认的redhat 6.2pȝ
    上不能用Q_dlinfo动态连接接口库函数好象在linux没有实现
    {等一pd问题Q欢q讨论指?BR>    mailto: alert7@21cn.com
                 alert7@xfocus.org
]

参考:

1. Operating System API Reference:UNIX SVR4.2,UNIX Press,1992

2. SunOs 5.3 Linker and Libraries Manual,SunSoft ,1993.

3. Richard M.Stallman,Using and porting GNU CC for version 2.6,
   Free Software Foundation,September 1994.

4. Steve Chamberlain and Roland Pesch,Using ld:The GNU linker,ld
   version 2,Cygnus Support,January 1994.

]]>
convert+批处理文件实现png2eps转换http://www.tkk7.com/sk8boy/articles/2458.html思?/dc:creator>思?/author>Fri, 25 Mar 2005 18:20:00 GMThttp://www.tkk7.com/sk8boy/articles/2458.htmlhttp://www.tkk7.com/sk8boy/comments/2458.htmlhttp://www.tkk7.com/sk8boy/articles/2458.html#Feedback2http://www.tkk7.com/sk8boy/comments/commentRss/2458.htmlhttp://www.tkk7.com/sk8boy/services/trackbacks/2458.html边学习LaTeXQ边把自q毕业论文从原先的Word文档ҎLaTeX的。进度比较慢Q所以现在菜开始向文档中加入图片。因Z前作囄的是Visio 2003Q所以考虑怎样图片格式{换成eps的?BR>
因ؓVisio 2003不能图片直接另存ؓeps格式的,所以开始只选择了另存ؓpng的。但是又如何png格式的图片{换位eps的呢Q这个我想了半天。后来尝试用Adobe的Acrobat 7.0对其q行转换Q首先保存ؓpdf格式的,后来有另存ؓeps的。高兴edQ可是插入tex文档的时候发现出了问题。发C个页面里面只有一张图片。所以翻开LaTeX graphics又看了看Q才发可能是eps文g格式的问题?BR>
但是用UltraEdit打开看了看又Acrobat生成的这个文Ӟ虽然多了很多其他的东西,但是BoundingBox的值是对的。不知道Z么会发生q种情况。后来下载安装了ImageMagickQ它有一个图片浏览器Q可以看eps文g。用q个览器打开发现QAcrobat生成的eps文g居然被放在了屏幕的中_应该是放在左下角的)。因为对eps文g的语法规范不是很熟,所以没有搞懂是怎么回事?BR>
后来在ImageMagick里面扑ֈ了convertq个工具Q试着用了一下,l果可以生成我想要的eps文g了。但是又面的一个问题是我又很多png文g需要{换,不想一个一个调用命令。也是尝试用命令:

convert  *.png  *.eps

但是生成的文件名都ؕ了,都被Ҏ数字~号了。怎么办呢Q所以就想着自习写一个程序来完成Q但是{念一惻IZ么不用DOS的批处理文g试一试呢Q说不定也可以搞定?BR>
可是面的问题是不知道怎么得到一个文件的文g名(没有.和后~Q。在|上看了几篇关于批处理命令的文章Q发现写得都差不多。而且也没有找到我惌的(其实当时看露了,是有的)。正当我在郁L时候,同学告诉我Windows XP自带的帮助里面就有DOS下批处理的命令的语法介绍。于是我如莯宝的开始看来v来。果然被我找CQ而且比网上的要好理解一些。下面就是我写得一个简单的E序Q?/P>

echo off
for  %%f  in  (*.png)  do  convert  %%f   %%~nf.eps
pause

嘿嘿Q搞定了Q?BR>
不过后来有在|上发现?FONT face=Arial>xConvertq个软gQ是用C写的。它对GhostView和ImageMagickq行了封装,通过命o行可以方便的实现上述功能。当然还有其他更强大的功能等着你去发现啊!

今天有安装了TechSmith公司的SnagItQ发现这个Y仉了可以抓屏外Q也可以方便地将png格式转换成eps格式?img src ="http://www.tkk7.com/sk8boy/aggbug/2458.html" width = "1" height = "1" />

]]>
վ֩ģ壺 ȫ߹ۿѹۿȫ| Ʒվ| ëƬ޾Ʒ| ھƷƵѡ߹ۿ | ѹۿëƬֻƵ| ҹAV| Ƶֻ| ˳վ߸| 91| ɫɫwww| ޾ƷԴ26u| Ƶ| aëƬȫ| ͵ͼƬ | Ƶ| ޹ۺϾƷһ߲| Ļȫ8| Ƶѹۿ| ˳վ18ֹþӰԺ| ŷ޾Ʒ˾þԻӰƬ| 97ѹۿƵ߹ۿ| վѴȫպ| ˳ӰԺ| ŮƷþþþ| 鶹Ʒѹۿ| һëƬëƬһëƬ | Ƶַ| ɫɫwww˿| ߹ѹۿ| 2019ĻƵ| һ߹ۿ| йchina[ձ| vaþþþ| ޹ƷԲ߲| Ů׽Ƶ| ҹ1000Ƶ| þþWWWѾƷ| Ʒۿ˳| һ91| ޾ƷۺϾþĻ| ˾޾ƷӰwww|