﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Charles-随笔分类-拿来主义</title><link>http://www.cppblog.com/Winux32/category/3068.html</link><description>Thinking low level, Coding high level</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 18:43:53 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 18:43:53 GMT</pubDate><ttl>60</ttl><item><title>HP中国区的总裁的退休感言zz</title><link>http://www.cppblog.com/Winux32/archive/2008/03/04/43692.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 04 Mar 2008 08:14:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2008/03/04/43692.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/43692.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2008/03/04/43692.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/43692.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/43692.html</trackback:ping><description><![CDATA[朋友发给我的，看完之后觉得写的很实在，现特献给天涯上的朋友们<br>　　<br>　　一、关于工作与生活<br>　　<br>　　　　我有个有趣的观察，外企公司多的是25-35岁的白领，40岁以上的员工很少，二三十岁的外企员工是意气风发的，但外企公司40岁附近的经理人是很尴尬的。我见过的40岁附近的外企经理人大多在一直跳槽，最后大多跳到民企，比方说，唐骏。外企员工的成功很大程度上是公司的成功，并非个人的成功，西门子的确比国美大，但并不代表西门子中国经理比国美的老板强，甚至可以说差得很远。而进外企的人往往并不能很早理解这一点，把自己的成功90％归功于自己的能力，实际上，外企公司随便换个中国区总经理并不会给业绩带来什么了不起的影响。好了问题来了，当这些经理人40多岁了，他们的薪资要求变得很高，而他们的才能其实又不是那么出众，作为外企公司的老板，你会怎么选择？有的是只要不高薪水的，要出位的精明强干精力冲沛的年轻人，有的是，为什么还要用你？<br>　　　　从上面这个例子，其实可以看到我们的工作轨迹，二三十岁的时候，生活的压力还比较小，身体还比较好，上面的父母身体还好，下面又没有孩子，不用还房贷，也没有孩子要上大学，当个外企小白领还是很光鲜的，挣得不多也够花了。但是人终归要结婚生子，终归会老，到了40岁，父母老了，要看病要吃药，要有人看护，自己要还房贷，要过基本体面的生活，要养小孩&#8230;&#8230;那个时候需要挣多少钱才够花才重要。所以，看待工作，眼光要放远一点，一时的谁高谁低并不能说明什么。<br>　　　　从这个角度上来说，我不太赞成过于关注第一份工作的薪水，更没有必要攀比第一份工作的薪水，这在刚刚出校园的学生中间是很常见的。正常人大概要工作35年，这好比是一场马拉松比赛，和真正的马拉松比赛不同的是，这次比赛没有职业选手，每个人都只有一次机会。要知到，有很多人甚至坚持不到终点，大多数人最后是走到终点的，只有少数人是跑过终点的，因此在刚开始的时候，去抢领先的位置并没有太大的意义。刚进社会的时候如果进500强公司，大概能拿到3k-6k/月的工资，有些特别技术的人才可能可以到8k/月，可问题是，5年以后拿多少？估计5k-10k了不起了。起点虽然高，但增幅有限，而且，后面的年轻人追赶的压力越来越大。<br>　　　　我前两天问我的一个销售，你会的这些东西一个新人2年就都学会了，但新人所要求的薪水却只是你的一半，到时候，你怎么办？<br>　　　　职业生涯就像一场体育比赛，有初赛、复赛、决赛。初赛的时候大家都刚刚进社会，大多数都是实力一般的人，这时候努力一点认真一点很快就能让人脱颖而出，于是有的人二十多岁做了经理，有的人迟些也终于赢得了初赛，三十多岁成了经理。然后是复赛，能参加复赛的都是赢得初赛的，每个人都有些能耐，在聪明才智上都不成问题，这个时候再想要胜出就不那么容易了，单靠一点点努力和认真还不够，要有很强的坚忍精神，要懂得靠团队的力量，要懂得收服人心，要有长远的眼光&#8230;&#8230;<br>　　　　看上去赢得复赛并不容易，但，还不是那么难。因为这个世界的规律就是给人一点成功的同时让人骄傲自满，刚刚赢得初赛的人往往不知道自己赢得的仅仅是初赛，有了一点小小的成绩大多数人都会骄傲自满起来，认为自己已经懂得了全部，不需要再努力再学习了，他们会认为之所以不能再进一步已经不是自己的原因了。虽然他们仍然不好对付，但是他们没有耐性，没有容人的度量，更没有清晰长远的目光。就像一只愤怒的斗牛，虽然猛烈，最终是会败的，而赢得复赛的人则象斗牛士一样，不急不躁，跟随着自己的节拍，慢慢耗尽对手的耐心和体力。赢得了复赛以后，大约已经是一位很了不起的职业经理人了，当上了中小公司的总经理，大公司的副总经理，主管着每年几千万乃至几亿的生意。<br>　　　　最终的决赛来了，说实话我自己都还没有赢得决赛，因此对于决赛的决胜因素也只能凭自己的猜测而已，这个时候的输赢或许就像武侠小说里写得那样，大家都是高手，只能等待对方犯错了，要想轻易击败对手是不可能的，除了使上浑身解数，还需要一点运气和时间。世界的规律依然发挥着作用，赢得复赛的人已经不只是骄傲自满了，他们往往刚愎自用，听不进去别人的话，有些人的脾气变得暴躁，心情变得浮躁，身体变得糟糕，他们最大的敌人就是他们自己，在决赛中要做的只是不被自己击败，等着别人被自己击败。这和体育比赛是一样的，最后高手之间的比赛，就看谁失误少谁就赢得了决赛。<br>二、 根源<br>　　<br>　　　　你工作快乐么？你的工作好么？<br>　　　　有没有觉得干了一段时间以后工作很不开心？有没有觉得自己入错了行？有没有觉得自己没有得到应有的待遇？有没有觉得工作像一团乱麻每天上班都是一种痛苦？有没有很想换个工作？有没有觉得其实现在的公司并没有当初想象得那么好？有没有觉得这份工作是当初因为生存压力而找的，实在不适合自己？你从工作中得到你想要得到的了么？你每天开心么？<br>　　　　天涯上愤怒的人很多，你有没有想过，你为什么不快乐？你为什么愤怒？<br>　　　　其实，你不快乐的根源，是因为你不知道要什么！你不知道要什么，所以你不知道去追求什么，你不知道追求什么，所以你什么也得不到。<br>　　　　我总觉得，职业生涯首先要关注的是自己，自己想要什么？大多数人大概没想过这个问题，唯一的想法只是——我想要一份工作，我想要一份不错的薪水，我知道所有人对于薪水的渴望，可是，你想每隔几年重来一次找工作的过程么？你想每年都在这种对于工作和薪水的焦急不安中度过么？不想的话，就好好想清楚。饮鸩止渴，不能因为口渴就拼命喝毒药。越是焦急，越是觉得自己需要一份工作，越饥不择食，越想不清楚，越容易失败，你的经历越来越差，下一份工作的人看着你的简历就皱眉头。于是你越喝越渴，越渴越喝，陷入恶性循环。最终只能哀叹世事不公或者生不逢时，只能到天涯上来发泄一把，在失败者的共鸣当中寻求一点心理平衡罢了。大多数人都有生存压力，我也是，有生存压力就会有很多焦虑，积极的人会从焦虑中得到动力，而消极的人则会因为焦虑而迷失方向。所有人都必须在压力下做出选择，这就是世道，你喜欢也罢不喜欢也罢。<br>　　　　一般我们处理的事情分为重要的事情和紧急的事情，如果不做重要的事情就会常常去做紧急的事情。比如锻炼身体保持健康是重要的事情，而看病则是紧急的事情。如果不锻炼身体保持健康，就会常常为了病痛烦恼。又比如防火是重要的事情，而救火是紧急的事情，如果不注意防火，就要常常救火。找工作也是如此，想好自己究竟要什么是重要的事情，找工作是紧急的事情，如果不想好，就会常常要找工作。往往紧急的事情给人的压力比较大，迫使人们去赶紧做，相对来说重要的事情反而没有那么大的压力，大多数人做事情都是以压力为导向的，压力之下，总觉得非要先做紧急的事情，结果就是永远到处救火，永远没有停歇的时候。（很多人的工作也像是救火队一样忙碌痛苦，也是因为工作中没有做好重要的事情。）那些说自己活在水深火热为了生存顾不上那么多的朋友，今天找工作困难是当初你们没有做重要的事情，是结果不是原因。如果今天你们还是因为急于要找一份工作而不去思考，那么或许将来要继续承受痛苦找工作的结果。<br>　　　　我始终觉得我要说的话题，沉重了点，需要很多思考，远比唐笑打武警的话题来的枯燥乏味，但是，天下没有轻松的成功，成功，要付代价。请先忘记一切的生存压力，想想这辈子你最想要的是什么？所以，最要紧的事情，先想好自己想要什么。<br>　　<br>　　三、什么是好工作<br>　　<br>　　　　当初微软有个唐骏，很多大学里的年轻人觉得这才是他们向往的职业生涯，我在清华bbs里发的帖子被这些学子们所不屑，那个时候学生们只想出国或者去外企，不过如今看来，我还是对的，唐骏去了盛大，陈天桥创立的盛大，一家民营公司。一个高学历的海归在500强的公司里拿高薪水，这大约是很多年轻人的梦想，问题是，每年毕业的大学生都在做这个梦，好的职位却只有500个。<br>　　　　人都是要面子的，也是喜欢攀比的，即使在工作上也喜欢攀比，不管那是不是自己想要的。大家认为外企公司很好，可是好在哪里呢？好吧，他们在比较好的写字楼，这是你想要的么？他们出差住比较好的酒店，这是你想要的么？别人会羡慕一份外企公司的工作，这是你想要的么？那一切都是给别人看的，你干吗要活得那么辛苦给别人看？另一方面，他们薪水福利一般，并没有特别了不起，他们的晋升机会比较少，很难做到很高阶的主管，他们虽然厌恶常常加班，却不敢不加班，因为&#8220;你不干有得是人干&#8221;，大部分情况下会找个台湾人香港人新加坡人来管你，而这些人又往往有些莫名其妙的优越感。你想清楚了么？500强一定好么？找工作究竟是考虑你想要什么，还是考虑别人想看什么？<br>　　　　我的大学同学们大多数都到美国了，甚至毕业这么多年了，还有人最近到国外去了。出国真的有那么好么？我的大学同学们，大多数还是在博士、博士后、访问学者地挣扎着，至今只有一个正经在一个美国大学里拿到个正式的教职。国内的教授很难当么？我有几个表亲也去了国外了，他们的父母独自在国内，没有人照顾，有好几次人在家里昏倒都没人知道，出国，真的这么光彩么？就像有人说的&#8220;很多事情就像看A片，看的人觉得很爽，做的人未必。&#8221;<br>　　　　人总想找到那个最好的，可是，什么是最好的？你觉得是最好的那个，是因为你的确了解，还是因为别人说他是最好的？即使他对于别人是最好的，对于你也一定是最好的么？<br>　　　　对于自己想要什么，自己要最清楚，别人的意见并不是那么重要。很多人总是常常被别人的意见所影响，亲戚的意见，朋友的意见，同事的意见&#8230;&#8230;问题是，你究竟是要过谁的一生？人的一生不是父母一生的续集，也不是儿女一生的前传，更不是朋友一生的外篇，只有你自己对自己的一生负责，别人无法也负不起这个责任。自己做的决定，至少到最后，自己没什么可后悔。对于大多数正常智力的人来说，所做的决定没有大的对错，无论怎么样的选择，都是可以尝试的。比如你没有考自己上的那个学校，没有入现在这个行业，这辈子就过不下去了？就会很失败？不见得。<br>　　<br>　　　　我想，好工作，应该是适合你的工作，具体点说，应该是能给你带来你想要的东西的工作，你或许应该以此来衡量你的工作究竟好不好，而不是拿公司的大小，规模，外企还是国企，是不是有名，是不是上市公司来衡量。小公司，未必不是好公司，赚钱多的工作，也未必是好工作。你还是要先弄清楚你想要什么，如果你不清楚你想要什么，你就永远也不会找到好工作，因为你永远只看到你得不到的东西，你得到的，都是你不想要的。<br>　　 可能，最好的，已经在你的身边，只是，你还没有学会珍惜。人们总是盯着得不到的东西，而忽视了那些已经得到的东西。<br>　　 <br>　　四、普通人<br>　　<br>　　　　我发现中国人的励志和国外的励志存在非常大的不同，中国的励志比较鼓励人立下大志愿，卧薪尝胆，有朝一日成富成贵。而国外的励志比较鼓励人勇敢面对现实生活，面对普通人的困境，虽然结果也是成富成贵，但起点不一样，相对来说，我觉得后者在操作上更现实，而前者则需要用999个失败者来堆砌一个成功者的故事。<br>　　　　我们都是普通人，普通人的意思就是，概率这件事是很准的。因此，我们不会买彩票中500万，我们不会成为比尔盖茨或者李嘉诚，我们不会坐飞机掉下来，我们当中很少的人会创业成功，我们之中有30％的人会离婚，我们之中大部分人会活过65岁&#8230;&#8230;<br>　　　　所以请你在想自己要什么的时候，要得&#8220;现实&#8221;一点，你说我想要做李嘉诚，抱歉，我帮不上你。成为比尔盖茨或者李嘉诚这种人，是靠命的，看我写的这篇文章绝对不会让你成为他们，即使你成为了他们，也绝对不是我这篇文章的功劳。&#8220;王侯将相宁有种乎&#8221;但真正当皇帝的只有一个人，王侯将相，人也不多。目标定得高些对于喜欢挑战的人来说有好处，但对于大多数普通人来说，反而比较容易灰心沮丧，很容易就放弃了。<br>　　　　回过头来说，李嘉诚比你有钱大致50万倍，他比你更快乐么？或许。有没有比你快乐50万倍，一定没有。他比你最多也就快乐一两倍，甚至有可能还不如你快乐。寻找自己想要的东西不是和别人比赛，比谁要得更多更高，比谁的目标更远大。虽然成为李嘉诚这个目标很宏大，但你并不见得会从这个目标以及追求目标的过程当中获得快乐，而且基本上你也做不到。你必须听听你内心的声音，寻找真正能够使你获得快乐的东西，那才是你想要的东西。<br>　　　　你想要的东西，或者我们把它称之为目标，目标其实并没有高低之分，你不需要因为自己的目标没有别人远大而不好意思，达到自己的目标其实就是成功，成功有大有小，快乐却是一样的。我们追逐成功，其实追逐的是成功带来的快乐，而非成功本身。职业生涯的道路上，我们常常会被攀比的心态蒙住眼睛，忘记了追求的究竟是什么，忘记了是什么能使我们更快乐。<br>　　　　社会上一夜暴富的新闻很多，这些消息，总会在我们的心里面掀起很多涟漪，涟漪多了就变成惊涛骇浪，心里的惊涛骇浪除了打翻承载你目标的小船，并不会使得你也一夜暴富。&#8220;只见贼吃肉，不见贼挨揍。&#8221;我们这些普通人既没有当贼的勇气，又缺乏当贼的狠辣绝决，虽然羡慕吃肉，却更害怕挨揍，偶尔看到几个没挨揍的贼就按奈不住，或者心思活动，或者大感不公，真要叫去做贼，却也不敢。<br>　　　　我还是过普通人的日子，要普通人的快乐，至少，晚上睡得着觉。<br>五、跳槽与积累<br>　　<br>　　　　首先要说明，工作是一件需要理智的事情，所以不要在工作上耍个性，天涯上或许会有人觉得你很有个性而叫好，煤气公司电话公司不会因为觉得你很有个性而免了你的帐单。当你很帅地炒掉了你的老板，当你很酷地挖苦了一番招聘的HR，账单还是要照付，只是你赚钱的时间更少了，除了你自己，没人受损失。<br>　　　　我并不反对跳槽，但跳槽决不是解决问题的办法，而且频繁跳槽的后果是让人觉得没有忠诚度可言，而且不能安心工作。现在很多人从网上找工作，很多找工作的网站常常给人出些馊主意，要知道他们是盈利性企业，当然要从自身盈利的角度来考虑，大家越是频繁跳槽频繁找工作他们越是生意兴隆，所以鼓动人们跳槽是他们的工作。所以他们会常常告诉你，你拿的薪水少了，你享受的福利待遇差了，又是&#8220;薪情快报&#8221;又是&#8220;赞叹自由奔放的灵魂&#8221;。至于是否会因此让你不能安心，你跳了槽是否解决问题，是否更加开心，那个，他们管不着。<br>　　　　要跳槽肯定是有问题，一般来说问题发生了，躲是躲不开的，很多人跳槽是因为这样或者那样的不开心，如果这种不开心，在现在这个公司不能解决，那么在下一个公司多半也解决不掉。你必须相信，90%的情况下，你所在的公司并没有那么烂，你认为不错的公司也没有那么好。就像围城里说的，&#8220;城里的人拼命想冲出来，而城外的人拼命想冲进去。&#8221;每个公司都有每个公司的问题，没有问题的公司是不存在的。换个环境你都不知道会碰到什么问题，与其如此，不如就在当下把问题解决掉。很多问题当你真的想要去解决的时候，或许并没有那么难。有的时候你觉得问题无法解决，事实上，那只是&#8220;你觉得&#8221;。<br>　　　　人生的曲线应该是曲折向上的，偶尔会遇到低谷但大趋势总归是曲折向上的，而不是象脉冲波一样每每回到起点，我见过不少面试者，30多岁了，四五份工作经历，每次多则3年，少则1年，30多岁的时候回到起点从一个初级职位开始干起，拿基本初级的薪水，和20多岁的年轻人一起竞争，不觉得有点辛苦么？这种日子好过么？<br>　　　　我非常不赞成在一个行业超过3年以后换行业，基本上，35岁以前我们的生存资本靠打拼，35岁以生存的资本靠的就是积累，这种积累包括人际关系，经验，人脉，口碑&#8230;&#8230;如果常常更换行业，代表几年的积累付之东流，一切从头开始，如果换了两次行业，35岁的时候大概只有5年以下的积累，而一个没有换过行业的人至少有了10年的积累，谁会占优势？工作到2-3年的时候，很多人觉得工作不顺利，好像到了一个瓶颈，心情烦闷，就想辞职，乃至换一个行业，觉得这样所有一切烦恼都可以抛开，会好很多。其实这样做只是让你从头开始，到了时候还是会发生和原来行业一样的困难，熬过去就向上跨了一大步，要知道每个人都会经历这个过程，每个人的职业生涯中都会碰到几个瓶颈，你熬过去了而别人没有熬过去你就领先了。跑长跑的人会知道，开始的时候很轻松，但是很快会有第一次的难受，但过了这一段又能跑很长一段，接下来会碰到第二次的难受，坚持过了以后又能跑一段，如此往复，难受一次比一次厉害，直到坚持不下去了。大多数人第一次就坚持不了了，一些人能坚持到第二次，第三次虽然大家都坚持不住了，可是跑到这里的人也没几个了，这点资本足够你安稳活这一辈子了。<br>　　　　一份工作到两三年的时候，大部分人都会变成熟手，这个时候往往会陷入不断的重复，有很多人会觉得厌倦，有些人会觉得自己已经搞懂了一切，从而懒得去寻求进步了。很多时候的跳槽是因为觉得失去兴趣了，觉得自己已经完成比赛了。其实这个时候比赛才刚刚开始，工作两三年的人，无论是客户关系，人脉，手下，和领导的关系，在业内的名气&#8230;&#8230;还都是远远不够的，但稍有成绩的人总是会自我感觉良好的，每个人都觉得自己跟客户关系铁得要命，觉得自己在业界的口碑好得很。其实可以肯定地说，一定不是，这个时候，还是要拿出前两年的干劲来，稳扎稳打，积累才刚刚开始。<br>　　　　你足够了解你的客户吗？你知道他最大的烦恼是什么吗？你足够了解你的老板么？你知道他最大的烦恼是什么吗？你足够了解你的手下么？你知道他最大的烦恼是什么吗？如果你不知道，你凭什么觉得自己已经积累够了？如果你都不了解，你怎么能让他们帮你的忙，做你想让他们做的事情？如果他们不做你想让他们做的事情，你又何来的成功？<br>　　<br>　　六、等待<br>　　<br>　　　　这是个浮躁的人们最不喜欢的话题，本来不想说这个话题，因为会引起太多的争论，而我又无意和人争论这些，但是考虑到对于职业生涯的长久规划，这是一个躲避不了的话题，还是决定写一写，不爱看的请离开吧。<br>　　　　并不是每次穿红灯都会被汽车撞，并不是每个罪犯都会被抓到，并不是每个错误都会被惩罚，并不是每个贪官都会被枪毙，并不是你的每一份努力都会得到回报，并不是你的每一次坚持都会有人看到，并不是你每一点付出都能得到公正的回报，并不是你的每一个善意都能被理解&#8230;&#8230;这个，就是世道。好吧，世道不够好，可是，你有推翻世道的勇气么？如果没有，你有更好的解决办法么？有很多时候，人需要一点耐心，一点信心。每个人总会轮到几次不公平的事情，而通常，安心等待是最好的办法。<br>　　　　有很多时候我们需要等待，需要耐得住寂寞，等待属于你的那一刻。周润发等待过，刘德华等待过，周星驰等待过，王菲等待过，张艺谋也等待过&#8230;&#8230;看到了他们如今的功成名就的人，你可曾看到当初他们的等待和耐心？你可曾看到金马奖影帝在街边摆地摊？你可曾看到德云社一群人在剧场里给一位观众说相声？你可曾看到周星驰的角色甚至连一句台词都没有？每一个成功者都有一段低沉苦闷的日子，我几乎能想象得出来他们借酒浇愁的样子，我也能想象得出他们为了生存而挣扎的窘迫。在他们一生最中灿烂美好的日子里，他们渴望成功，但却两手空空，一如现在的你。没有人保证他们将来一定会成功，而他们的选择是耐住寂寞。如果当时的他们总念叨着&#8220;成功只是属于特权阶级的&#8221;，你觉得他们今天会怎样？<br>　　　　曾经我也不明白有些人为什么并不比我有能力却要坐在我的头上，年纪比我大就一定要当我的领导么？为什么有些烂人不需要努力就能赚钱？为什么刚刚改革开放的时候的人能那么容易赚钱，而轮到我们的时候，什么事情都要正规化了？有一天我突然想，我还在上学的时候他们就在社会里挣扎奋斗了，他们在社会上奋斗积累了十几二十年，我们新人来了，他们有的我都想要，我这不是在要公平，我这是在要抢劫。因为我要得太急，因为我忍不住寂寞。二十多岁的男人，没有钱，没有事业，却有蓬勃的欲望。<br>　　　　人总是会遇到挫折的，人总是会有低潮的，人总是会有不被人理解的时候的，人总是有要低声下气的时候，这些时候恰恰是人生最关键的时候，因为大家都会碰到挫折，而大多数人过不了这个门槛，你能过，你就成功了。在这样的时刻，我们需要耐心等待，满怀信心地去等待，相信，生活不会放弃你，机会总会来的。至少，你还年轻，你没有坐牢，没有生治不了的病，没有欠还不起的债。比你不幸的人远远多过比你幸运的人，你还怕什么？路要一步步走，虽然到达终点的那一步很激动人心，但大部分的脚步是平凡甚至枯燥的，但没有这些脚步，或者耐不住这些平凡枯燥，你终归是无法迎来最后的那些激动人心。<br>　　　　逆境，是上帝帮你淘汰竞争者的地方。要知道，你不好受，别人也不好受，你坚持不下去了，别人也一样，千万不要告诉别人你坚持不住了，那只能让别人获得坚持的信心，让竞争者看着你微笑的面孔，失去信心，退出比赛。胜利属于那些有耐心的人。<br>　　　　在最绝望的时候，我会去看电影《The Pursuit of Happyness》《JerryMaguire》，让自己重新鼓起勇气，因为，无论什么时候，我们总还是有希望。当所有的人离开的时候，我不失去希望，我不放弃。每天下班坐在车里，我喜欢哼着《隐形的翅膀》看着窗外，我知道，我在静静等待，等待属于我的那一刻。<br>　　　　原贴里伊吉网友的话我很喜欢，抄录在这里：<br>　　　　每个人都希望，自己是独一无二的特殊者<br>　　　　含着金匙出生、投胎到好家庭、工作安排到电力局拿1w月薪这样的小概率事件，当然最好轮到自己<br>　　　　红军长征两万五、打成右派反革命、胼手胝足牺牲尊严去奋斗，最好留给祖辈父辈和别人<br>　　　　自然，不是每个吃过苦的人都会得到回报<br>　　　　但是，任何时代，每一个既得利益者身后，都有他的祖辈父辈奋斗挣扎乃至流血付出生命的身影<br>　　　　羡慕别人有个好爸爸，没什么不可以<br>　　　　问题是，你的下一代，会有一个好爸爸吗？<br>　　　　至于问到为什么不能有同样的赢面概率？我只能问：为什么物种竞争中，人和猴子不能有同样的赢面概率？<br>　　　　物竞天择。猴子的灵魂不一定比你卑微，但你身后有几十万年的类人猿进化积淀。<br>　　<br>　　七、入对行跟对人<br>　　<br>　　　　在中国，大概很少有人是一份职业做到底的，虽然如此，第一份工作还是有些需要注意的地方，有两件事情格外重要，第一件是入行，第二件事情是跟人。第一份工作对人最大的影响就是入行，现代的职业分工已经很细，我们基本上只能在一个行业里成为专家，不可能在多个行业里成为专家。很多案例也证明即使一个人在一个行业非常成功，到另外一个行业，往往完全不是那么回事情，&#8220;你想改变世界，还是想卖一辈子汽水？&#8221;是乔布斯邀请百事可乐总裁约翰&#183;斯考利加盟苹果时所说的话，结果这位在百事非常成功的约翰，到了苹果表现平平。其实没有哪个行业特别好，也没有哪个行业特别差，或许有报道说哪个行业的平均薪资比较高，但是他们没说的是，那个行业的平均压力也比较大。看上去很美的行业一旦进入才发现很多地方其实并不那么完美，只是外人看不见。<br>　　　　说实话，我自己都没有发大财，所以我的建议只是让人快乐工作的建议，不是如何发大财的建议，我们只讨论一般普通打工者的情况。我认为选择什么行业并没有太大关系，看问题不能只看眼前。比如，从前年开始，国家开始整顿医疗行业，很多医药公司开不下去，很多医药行业的销售开始转行。其实医药行业的不景气是针对所有公司的，并非针对一家公司，大家的日子都不好过，这个时候跑掉是非常不划算的，大多数正规的医药公司即使不做新生意撑个两三年总是能撑的，大多数医药销售靠工资撑个两三年也是可以撑的，国家不可能永远捏着医药行业不放的，两三年以后光景总归还会好起来的，那个时候别人都跑了而你没跑，那时的日子应该会好过很多。有的时候觉得自己这个行业不行了，问题是，再不行的行业，做得人少了也变成了好行业，当大家都觉得不好的时候，往往却是最好的时候。大家都觉得金融行业好，金融行业门槛高不说，有多少人削尖脑袋要钻进去，竞争激励，进去以后还要时时提防，一个疏忽，就被后来的人给挤掉了，压力巨大，又如何谈得上快乐？也就未必是&#8220;好&#8221;工作了。<br>　　　　太阳能这个东西至今还不能进入实际应用的阶段，但是中国已经有7家和太阳能有关的公司在纽交所上市了，国美苏宁永乐其实是贸易型企业，也能上市，鲁泰纺织连续10年利润增长超过50%，卖茶的一茶一座，卖衣服的海澜之家都能上市&#8230;&#8230;其实选什么行业真的不重要，关键是怎么做。事情都是人做出来的，关键是人。<br>　　　　有一点是需要记住的，这个世界上，有史以来直到我们能够预见得到的未来，成功的人总是少数，有钱的人总是少数，大多数人是一般的，普通的，不太成功的。因此，大多数人的做法和看法，往往都不是距离成功最近的做法和看法。因此大多数人说好的东西不见得好，大多数人说不好的东西不见得不好。大多数人都去炒股的时候说明跌只是时间问题，大家越是热情高涨的时候，跌的日子越近。大多数人买房子的时候，房价不会涨，而房价涨的差不多的时候，大多数人才开始买房子。不会有这样一件事情让大家都变成功，发了财，历史上不曾有过，将来也不会发生。有些东西即使一时运气好得到了，还是会在别的时候别的地方失去的。<br>　　　　年轻人在职业生涯的刚开始，尤其要注意的是，要做对的事情，不要让自己今后几十年的人生总是提心吊胆，更不值得为了一份工作赔上自己的青春年华。我的公司是个不行贿的公司，以前很多人不理解，甚至自己的员工也不理解，不过如今，我们是同行中最大的企业，客户乐意和我们打交道，尤其是在国家打击腐败的时候，每个人都知道我们做生意不给钱的名声，都敢于和我们做生意。而勇于给钱的公司，不是倒了，就是跑了，要不就是每天睡不好觉，人还是要看长远一点。很多时候，看起来最近的路，其实是最远的路，看起来最远的路，其实是最近的路。<br>　　　　跟对人是说，入行后要跟个好领导好老师，刚进社会的人做事情往往没有经验，需要有人言传身教。对于一个人的发展来说，一个好领导是非常重要的。所谓&#8220;好&#8221;的标准，不是他让你少干活多拿钱，而是以下三个。<br>　　　　首先，好领导要有宽广的心胸，如果一个领导每天都会发脾气，那几乎可以肯定他不是个心胸宽广的人，能发脾气的时候却不发脾气的领导，多半是非常厉害的领导。中国人当领导最大的毛病是容忍不了能力比自己强的人，所以常常可以看到的一个现象是，领导很有能力，手下一群庸才或者手下一群闲人。如果看到这样的环境，还是不要去的好。<br>　　　　其次，领导要愿意从下属的角度来思考问题，这一点其实是从面试的时候就能发现的，如果这位领导总是从自己的角度来考虑问题，几乎不听你说什么，这就危险了。从下属的角度来考虑问题并不代表同意下属的说法，但他必须了解下属的立场，下属为什么要这么想，然后他才有办法说服你，只关心自己怎么想的领导往往难以获得下属的信服。<br>　　　　第三，领导敢于承担责任，如果出了问题就把责任往下推，有了功劳就往自己身上揽，这样的领导不跟也罢。选择领导，要选择关键时刻能抗得住的领导，能够为下属的错误买单的领导，因为这是他作为领导的责任。<br>　　　　有可能，你碰不到好领导，因为，中国的领导往往是屁股决定脑袋的领导，因为他坐领导的位置，所以他的话就比较有道理，这是传统观念官本位的误区，可能有大量的这种无知无能的领导，只是，这对于你其实是好事，如果将来有一天你要超过他，你希望他比较聪明还是比较笨？相对来说这样的领导其实不难搞定，只是你要把自己的身段放下来而已。多认识一些人，多和比自己强的人打交道，同样能找到好的老师，不要和一群同样郁闷的人一起控诉社会，控诉老板，这帮不上你，只会让你更消极。和那些比你强的人打交道，看他们是怎么想的，怎么做的，学习他们，然后跟更强的人打交道。<br>八、选择<br>　　<br>　　　　我们每天做的最多的事情，其实是选择，因此在谈职业生涯的时候不得不提到这个话题。<br>　　　　我始终认为，在很大的范围内，我们究竟会成为一个什么样的人，决定权在我们自己，每天我们都在做各种各样的选择，我可以不去写这篇文章，去别人的帖子拍拍砖头，也可以写下这些文字，帮助别人的同时也整理自己的思路，我可以多注意下格式让别人易于阅读，也可以写成一堆，我可以就这样发上来，也可以在发以前再看几遍，你可以选择不刮胡子就去面试，也可以选择出门前照照镜子&#8230;&#8230;每天，每一刻我们都在做这样那样的决定，我们可以漫不经心，也可以多花些心思，成千上万的小选择累计起来，就决定了最终我们是个什么样的人。<br>　　　　从某种意义上来说我们的未来不是别人给的，是我们自己选择的，很多人会说我命苦啊，没得选择阿，如果你认为&#8220;去微软还是去IBM&#8221;&#8220;上清华还是上北大&#8221;&#8220;当销售副总还是当厂长&#8221;这种才叫选择的话，的确你没有什么选择，大多数人都没有什么选择。但每天你都可以选择是否为客户服务更周到一些，是否对同事更耐心一些，是否把工作做得更细致一些，是否把情况了解得更清楚一些，是否把不清楚的问题再弄清楚一些&#8230;&#8230;你也可以选择在是否在痛苦中继续坚持，是否抛弃掉自己的那些负面的想法，是否原谅一个人的错误，是否相信我在这里写下的这些话，是否不要再犯同样的错误&#8230;&#8230;生活每天都在给你选择的机会，每天都在给你改变自己人生的机会，你可以选择赖在地上撒泼打滚，也可以选择咬牙站起来。你永远都有选择。有些选择不是立杆见影的，需要累积，比如农民可以选择自己常常去浇地，也可以选择让老天去浇地，诚然你今天浇水下去苗不见得今天马上就长出来，但常常浇水，大部分苗终究会长出来的，如果你不浇，收成一定很糟糕。<br>　　　　每天生活都在给你机会，他不会给你一叠现金也不会拱手送你个好工作，但实际上，他还是在给你机会。我的家庭是一个普通的家庭，没有任何了不起的社会关系，我的父亲在大学毕业以后就被分配到了边疆，那个小县城只有一条马路，他们那一代人其实比我们更有理由抱怨，他们什么也没得到，年轻的时候文化大革命，书都没得读，支援边疆插队落户，等到老了，却要给年轻人机会了。他有足够的理由象成千上万那样的青年一样坐在那里抱怨生不逢时，怨气冲天。然而在分配到边疆的十年之后，国家恢复招研究生，他考回了原来的学校。研究生毕业，他被分配到了安徽一家小单位里，又是3年以后，国家第一届招收博士生，他又考回了原来的学校，成为中国第一代博士，那时的他比现在的我年纪还大。生活并没有放弃他，他也没有放弃生活。10年的等待，他做了他自己的选择，他没有放弃，他没有破罐子破摔，所以时机到来的时候，他改变了自己的人生。你最终会成为什么样的人，就决定在你的每个小小的选择之间。<br>　　　　你选择相信什么？你选择和谁交朋友？你选择做什么？你选择怎么做？&#8230;&#8230;我们面临太多的选择，而这些选择当中，意识形态层面的选择又远比客观条件的选择来得重要得多，比如选择做什么产品其实并不那么重要，而选择怎么做才重要。选择用什么人并不重要，而选择怎么带这些人才重要。大多数时候选择客观条件并不要紧，大多数关于客观条件的选择并没有对错之分，要紧的是选择怎么做。一个大学生毕业了，他要去微软也好，他要卖猪肉也好，他要创业也好，他要做游戏代练也好，只要不犯法，不害人，都没有什么关系，要紧的是，选择了以后，怎么把事情做好。<br>　　　　除了这些，你还可以选择时间和环境，比如，你可以选择把这辈子最大的困难放在最有体力最有精力的时候，也可以走一步看一步，等到了40岁再说，只是到了40多岁，那正是一辈子最脆弱的时候，上有老下有小，如果在那个时候碰上了职业危机，实在是一件很苦恼的事情。与其如此不如在20多岁30多岁的时候吃点苦，好让自己脆弱的时候活得从容一些。你可以选择在温室里成长，也可以选择到野外磨砺，你可以选择在办公室吹冷气的工作，也可以选择40度的酷热下，去见你的客户，只是，这一切最终会累积起来，引导你到你应得的未来。<br>　　　　我不敢说所有的事情你都有得选择，但是绝大部分事情你有选择，只是往往你不把这当作一种选择。认真对待每一次选择，才会有比较好的未来。<br>　　<br>　　九、选择职业<br>　　<br>　　　　职业的选择，总的来说，无非就是销售、市场、客服、物流、行政、人事、财务、技术、管理几个大类，有个有趣的现象就是，500强的CEO当中最多的是销售出身，第二多的人是财务出身，这两者加起来大概超过95％。现代IT行业也有技术出身成为老板的，但实际上，后来他们还是从事了很多销售和市场的工作，并且表现出色，公司才获得了成功，完全靠技术能力成为公司老板的，几乎没有。这是有原因的，因为销售就是一门跟人打交道的学问，而管理其实也是跟人打交道的学问，这两者之中有很多相通的东西，他们的共同目标就是&#8220;让别人去做某件特定的事情。&#8221;而财务则是从数字的层面了解生意的本质，从宏观上看待生意的本质，对于一个生意是否挣钱，是否可以正常运作有着最深刻的认识。<br>　　　　公司小的时候是销售主导公司，而公司大的时候是财务主导公司，销售的局限性在于只看人情不看数字，财务的局限性在于只看数字不看人情。公司初期，运营成本低，有订单就活得下去，跟客户也没有什么谈判的条件，别人肯给生意做已经谢天谢地了，这个时候订单压倒一切，客户的要求压倒一切，所以当然要顾人情。公司大了以后，一切都要规范化，免得因为不规范引起一些不必要的风险，同时运营成本也变高，必须提高利润率，把有限的资金放到最有产出的地方。对于上市公司来说，股东才不管你客户是不是最近出国，最近是不是那个省又在搞严打，到了时候就要把业绩拿出来，拿不出来就抛股票，这个时候就是数字压倒一切。<br>　　　　前两天听到有人说一句话觉得很有道理，开始的时候我们想&#8220;能做什么？&#8221;，等到公司做大了有规模了，我们想&#8220;不能做什么。&#8221;很多人在工作中觉得为什么领导这么保守，这也不行那也不行，错过很多机会。很多时候是因为，你还年轻，你想的是&#8220;能做什么&#8221;，而作为公司领导要考虑的方面很多，他比较关心&#8220;不能做什么&#8221;。<br>　　　　我并非鼓吹大家都去做销售或者财务，究竟选择什么样的职业，和你究竟要选择什么样的人生有关系，有些人就喜欢下班按时回家，看看书听听音乐，那也挺好，但就不适合找个销售的工作了，否则会是折磨自己。有些人就喜欢出风头，喜欢成为一群人的中心，如果选择做财务工作，大概也干不久，因为一般老板不喜欢财务太积极，也不喜欢财务话太多。先想好自己要过怎样的人生，再决定要找什么样的职业。有很多的不快乐，其实是源自不满足，而不满足，很多时候是源自于心不定，而心不定则是因为不清楚究竟自己要什么，不清楚要什么的结果就是什么都想要，结果什么都没得到。<br>　　　　我想，我们还是因为生活而工作，不是因为工作而生活，生活是最要紧的，工作只是生活中的一部分。我总是觉得生活的各方方面都是相互影响的，如果生活本身一团乱麻，工作也不会顺利。所以要有娱乐、要有社交、要锻炼身体，要有和睦的家庭&#8230;&#8230;最要紧的，要开心，我的两个销售找我聊天，一肚子苦水，我问他们，2年以前，你什么都没有，工资不高，没有客户关系，没有业绩，处于被开的边缘，现在的你比那时条件好了很多，为什么现在却更加不开心了？如果你做得越好越不开心，那你为什么还要工作？首先的首先，人还是要让自己高兴起来，让自己心态好起来，这种发自内心的改变会让你更有耐心，更有信心，更有气质，更能包容&#8230;&#8230;否则，看看镜子里的你，你满意么？<br>　　　　有人会说，你说得容易，我每天加班，不加班老板就会把我炒掉，每天累得要死，哪有时间娱乐、社交、锻炼？那是人们把目标设定太高的缘故，如果你还在动不动就会被老板炒掉的边缘，那么你当然不能设立太高的目标，难道你还想每天去打高尔夫？你没时间去健身房锻炼身体，但是上下班的时候多走几步可以吧，有楼梯的时候走走楼梯不走电梯可以吧？办公的间隙扭扭脖子拉拉肩膀做做俯卧撑可以吧？谁规定锻炼就一定要拿出每天2个小时去健身房？你没时间社交，每月参加郊游一次可以吧，周末去参加个什么音乐班，绘画班之类的可以吧，去尝试认识一些同行，和他们找机会交流交流可以吧？开始的时候总是有些难的，但迈出这一步就会向良性循环的方向发展。而每天工作得很苦闷，剩下的时间用来咀嚼苦闷，只会陷入恶性循环，让生活更加糟糕。<br>　　<br>　　虽然离开惠普仅有十五天，但感觉上惠普已经离我很远。我的心思更多放在规划自己第二阶段的人生，这并非代表我对惠普没有任何眷恋，主要还是想以此驱动自己往前走。<br>　　　　万科王石登珠穆朗玛峰的体验给我很多启发，虽然在出发时携带大量的物资，但是登顶的过程中，必须不断减轻负荷，最终只有一个氧气瓶和他登上峰顶。登山如此，漫长的人生又何尝不是。<br>　　　　我宣布退休后，接到同事朋友同学的祝贺。大部分人都认为我能够在这样的职位上及年龄选择退休，是一种勇气，也是一种福气。 <br>　　　　还有一部分人怀疑我只是借此机会换个工作，当然还有一些人说我在HP做不下去了，趁此机会离开。<br>　　　　我多年来已经习惯别人对我的说三道四，但对于好友，我还是挺关心大家是否真正理解我的想法，这也是写这篇文章的目的。<br>　　　　由于受我父亲早逝的影响，我很早就下定决心，要在有生之年实现自己的愿望，我不要像我父亲一样，为家庭生活忙碌一辈子，临终前感伤，懊恼自己有很多没有实现的理想。<br>　　　　一本杂志的文章提到我们在生前就应该思考自己的墓志铭，因为那代表你自己对完美人生的定义，我们应该尽可能在有生之年去实现它。<br>　　　　我希望我的墓志铭上除了与家人及好友有关的内容外，是这样写着：<br>　　　　1.这个人曾经服务于一家全球最大的IT公司（HP）25年，和她一起经历过数次重大的变革，看着她从以电子仪表为主要的业务变革成全球最大的IT公司。<br>　　　　2.这个人曾经在全球发展最快的国家（中国）工作16年，并担任HP中国区总裁7年，见证及经历过中国改革开放的关键最新突破阶段，与中国一起成长。<br>　　　　3.这个人热爱飞行，曾经是一个有执照的飞行员，累积飞行时数超过X小时，曾经在X个机场起降过。<br>　　　　4.这个人曾经获得管理硕士学位，在领导管理上特别关注中国企业的组织行为及绩效，并且在这个领域上获得中国企业界的认可。<br>　　　　我费时25年才总结1和2两项成果，我不知还要费时多久才能达成3和4的愿望，特别是第4个愿望需要经历学术的训练，才能将我的经验总结成知识。<br>　　否则我的经验将无法有效影响及传授他人。因此重新进入学校学习，拿一个管理学位是有必要的，更何况这是我一个非常重要的愿望。<br>　　　　另一方面，我25年的时间都花在运营(operation)的领域，兢兢业业的做好职业人士的工作，它是一份好工作，特别是在HP，这份工作也帮助我建立财务的基础，支持家庭的发展。<br>　　　　但是我不想终其一生，都陷入在运营的领域，我想象企业家一样，有机会靠一些点子(ideas)赚钱，虽然风险很高，但是值得一试，即使失败，也不枉走一回，这也是第4个愿望其中的一部份。<br>　　　　Carly Fiorina曾经对我说过&#8220;这个世界上有好想法的人很多，但有能力去实现的人很少&#8221;，2007年5月21日在北大演讲时，有人问起那些书对我影响较大，我想对我人生观有影响的其中一本书叫&#8220;TriggerPoint&#8221;，它的主要观点是：人生最需要的不是规划，而是在适当的时机掌握机会，采取行动。<br>　　　　我这些愿望在我心中已经酝酿一段很长的时间，开始的时候，也许一年想个一两次，过了也就忘掉，但逐渐的，这个心中的声音，愈来愈大，出现的频率也愈来愈高，当它几乎每一个星期都会来与我对话时，我知道时机已经成熟。<br>　　　　但和任何人一样，要丢掉自己现在所拥有的，所熟悉的环境及稳定的收入，转到一条自己未曾经历过，存在未知风险的道路，需要绝大的勇气，家人的支持和好友的鼓励。有舍才有得，真是知易行难，我很高兴自己终于跨出了第一步。<br>　　　　我要感谢HP的EER提前退休优惠政策，它是其中一个关键的TriggerPoints,另一个关键因素是在去年五六月发生的事。<br>　　　　当时我家老大从大学毕业，老二从高中毕业，在他们继续工作及求学前，这是一个黄金时段，让我们全家可以相聚一段较长的时间，我为此很早就计划休一个长假，带着他们到各地游玩。<br>　　　　但这个计划因为工作上一件重要的事情（Mark Hurd访华）不得不取消。这个事件刺激了我必须严肃的去对待那心中的声音，我会不会继续不断的错失很多关键的机会?<br>　　　　我已经年过50，我会不会走向和我父亲一样的道路？人事部老总Charles跟我说，很多人在所有对他有利的星星都排成一列时，还是错失时机。<br>　　　　我知道原因，因为割舍及改变对人是多么的困难，我相信大部分的人都有自己人生的理想，但我也相信很多人最终只是把这些理想当成是<br>　　　　幻想，然后不断的为自己寻找不能实现的藉口，南非前总统曼德拉曾经说过，&#8220;与改变世界相比，改变自己更困难&#8221;，真是一针见血。<br>　　　　什么是快乐及有意义的人生？我相信每一个人的定义都不一样，对我来说，能实现我墓志铭上的内容就是我的定义。<br>　　　　在中国惠普总裁的位置上固然可以吸引很多的关注及眼球，但是我太太及较亲近的好友，都知道那不是我追求的，那只是为扮演好这个角色必须尽力做好的地方。<br>　　　　做一个没有名片的人士，虽然只有十多天的时间，但我发现我的脑袋里已经空出很多空间及能量，让我可以静心的为我ChapterII的新生活做细致的调研及规划。<br>　　　　我预订以两年的时间来完成转轨的准备工作，并且花多点时间与家人共处。这两年的时间我希望拿到飞行执照，拿到管理有关的硕士学位，提升英文的水平，建立新的网络，多认识不同行业的人，保持与大陆的联系。希望两年后，我可以顺利回到大陆去实现我第四个愿望。<br>　　　　毫不意外，在生活上，我发现很多需要调整的地方。<br>　　　　二十多年来，我生活的步调及节奏，几乎完全被公司及工作所左右，不断涌出的deadline及任务驱动我每天的安排，一旦离开这样的环境，第一个需要调整的就是要依靠自己的自律及意志力来驱动每天的活动，睡觉睡到自然醒的态度绝对不正确，放松自己，不给事情设定目标及时间表，或者对错失时间目标无所谓，也不正确，没有年度，季度，月及周计划也不正确。<br>　　　　担任高层经理多年，已经养成交待事情的习惯，自己的时间主要花在思考，决策及追踪项目的进展情况，更多是依靠一个庞大的团队来执行具体的事项及秘书来处理很多协调及繁琐的事情。<br>　　　　到美国后，很多事情需要打800号电话联系，但这些电话很忙，常让你在waitingline上等待很长的时间，当我在等待时，我可以体会以前秘书工作辛苦的地方，但同时也提醒我自己，在这个阶段要改变态度，培养更大的耐性及自己动手做的能力。<br>　　　　生活的内容也要做出很大的调整，多出时间锻炼身体，多出时间关注家人，多出时间关注朋友，多出时间体验不同的休闲活动及飞行，一步步的，希望生活逐步调整到我所期望的轨道上，期待这两年的生活既充实又充满乐趣及意义。<br>　　　　第一个快乐的体验就是准备及参加大儿子的订婚礼，那种全心投入，不需担忧工作数字的感觉真好。同时我也租好了公寓，买好了家具及车子，陪家人在周末的时候到Reno及Lake Tahoe玩了一趟，LakeTahoe我去了多次，但这次的体验有所不同，我从心里欣赏到它的美丽。<br>　　　　但同时我也在加紧调研的工作，为申请大学及飞行学校做准备，这段时间也和在硅谷的朋友及一些风险投资公司见面，了解不同的产业。<br>　　　　我的人生观是&#8220;完美的演出来自充分的准备&#8221;，&#8220;勇于改变自己，适应不断变化的环境，机会将不断出现&#8221;，&#8220;快乐及有意义的人生来自于实现自己心中的愿望，而非外在的掌声&#8221;。<br>　　　　我离开时，有两位好朋友送给我两个不同的祝语，Baron的是&#8220;多年功过化烟尘&#8221;，杨华的是&#8220;莫春者，风乎舞雩，咏而归&#8221;，它们分别代表了我离开惠普及走向未来的心情。<br>　　　　我总结人生有三个阶段，一个阶段是为现实找一份工作，一个阶段是为现实，但可以选择一份自己愿意投入的工作，一个阶段是为理想去做一些事情。<br>　　　　我珍惜我的福气，感激HP及同事、好朋友给我的支持，鼓励及协助，这篇文字化我心声的文章与好友分享。<br>
<img src ="http://www.cppblog.com/Winux32/aggbug/43692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2008-03-04 16:14 <a href="http://www.cppblog.com/Winux32/archive/2008/03/04/43692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COFF格式续篇—Lib文件的结构zz</title><link>http://www.cppblog.com/Winux32/archive/2007/07/19/28363.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Thu, 19 Jul 2007 08:54:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/07/19/28363.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/28363.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/07/19/28363.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/28363.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/28363.html</trackback:ping><description><![CDATA[上一篇文章介绍了COFF目标文件的结构。如果你试着做一个应用程序的连接器（Linker），就会发现，仅仅有目标文件是不够的。我们在连接程序时，不仅仅要用到目标文件，库文件也是必不可少的。<br>&nbsp;&nbsp;&nbsp;&nbsp;库文件是怎么样的结构呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;其实，库文件的结构也很简单。它就是&#8220;一堆&#8221;目标文件的集合。把目标文件做成库以后，我们在使用目标文件中所实现的功能时，连接程序会自动在库文件里查找相应的目标文件，并使用它。这大大减少了我们对目标文件的管理工作，减轻了代码重用的负担。<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>Lib文件中的节</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;COFF格式中所用到的&#8220;节&#8221;的概念再次出现在Lib格式中。不过，Lib文件的节要简单得多。先让我们来看看它的整体结构：<br>
<div>
<table cellSpacing=0 cellPadding=0 width="85%" align=left border=0>
    <tbody>
        <tr>
            <td>&nbsp;&nbsp;&nbsp;&nbsp;如右图所示：<br>&nbsp;&nbsp;&nbsp;&nbsp;Lib格式只有四种类型的节（Section），即First Sec，Second Sec，Longname Sec和Obj Sec；其中Second Sec与Longname Sec是可选节，很多Lib文件中都没有。而开头的Singature只是一个标识，它相当于COFF目标文件中的魔法数字。它是一个长度为8的字符串，值为&#8220;!&lt;arch&gt;\n&#8221;。<br>&nbsp;&nbsp;&nbsp;&nbsp;First Sec，顾名思义，就是第一个节。它包含了库中所有的符号名以及这些符号所在的目标文件在库中的位置（绝对偏移）。<br>&nbsp;&nbsp;&nbsp;&nbsp;Second Sec就是第二节。它的内容和First Sec是相同的。不同的是，Second Sec是一个有序表，通过它来查找库中的符号比通过First Sec来查找要快很多。</td>
            <td>
            <table cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width=100 align=center bgColor=#ffffff borderColorLight=#000000 border=1>
                <tbody>
                    <tr>
                        <td>Signature</td>
                    </tr>
                    <tr>
                        <td>First Sec</td>
                    </tr>
                    <tr>
                        <td>Second Sec</td>
                    </tr>
                    <tr>
                        <td>Longname Sec</td>
                    </tr>
                    <tr>
                        <td>Obj Sec1</td>
                    </tr>
                    <tr>
                        <td>Obj Sec2</td>
                    </tr>
                    <tr>
                        <td>&#8230;&#8230;</td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div><br><br><br><br><br><br><br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;Longname Sec是长名称节。这一节是一个字符串表。它包含了所有长目标文件名。如果后面的Obj Sec中没有给出相应的目标文件名，我们就要到这一节中来查找。<br>&nbsp;&nbsp;&nbsp;&nbsp;Obj Sec就是目标文件节。这些节中存储着不同的目标文件的原始数据。</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;在库文件中，每一节都有两个部分。一个部分是头，另一个部分才是该节的数据；数据紧跟在头的后面。头描述了该节数据的类型、长度等信息。这些头的格式都是相同的。其结构用C语言描述如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char Name[16];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 名称<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char Time[12];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 时间<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char UserID[6];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 用户ID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char GroupID[6]; &nbsp;&nbsp; // 组ID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char Mode[8];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 模式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char Size[10];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 长度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char EndOfHeader[2];// 结束符<br>&nbsp;&nbsp;&nbsp;&nbsp;} SectionHeader;<br>&nbsp;&nbsp;&nbsp;&nbsp;可以看到，头中的数据全都是字符串。用字符串的好处是可以提高格式的兼容性，因为在不同的机器上，数据的排列方式是不同的。有的机器是以Little-Endian方式工作，还有的是以Big-Endian方式工作，它们互不兼容（这两种方式的区别！？请看我的《COFF格式》一文，其中的文件头一节有说明）。用字符串就不会有这种问题（后面我们将会遇到）。但它也有不方便的地方，就是必须把字符串转换成数值，多了一个步骤。<br>&nbsp;&nbsp;&nbsp;&nbsp;在这个结构中，最常用的Name、Size以及EndOfHeader三个成员。Name就是节的名称啦！Size也很好理解，就是该节数据的长度。现在要注意的就是这个EndOfHeader成员了！这个成员标志着头的结束，其内容为&#8220;`\n&#8221;（注意，这里没有打错，是两个字符&#8220;`&#8221;和&#8220;\n&#8221;）。怎么样？有点奇怪吧？为什么要有这个结束符？每一节的头长度一定，每节中的数据长度也知道。按顺序向下读不行吗？答案是：不行！因为每一节之间存在间隙！通常是一个字节或零个字节。如果是零个字节倒好，按顺序向下读是OK的。可是如果不为零的话，这样读就要错位了。要知道错位没有，只好用一个结束符来定位了。如果在读头的时候发现结束符不对，那就要一个字节一个字节地向下查找，直到找到结束符，才能算是对齐了。切记！切记！<br>&nbsp;&nbsp;&nbsp;&nbsp;当然，通过First Sec或Second Sec中给出的偏移来读数据就不存在这个问题。不会发生错位，放心读吧！<br>&nbsp;&nbsp;&nbsp;&nbsp;现在让我们来看看每一节中的数据是什么样子。</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;<strong>First Sec</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;第一节，通常就是Lib中的每一个小节。它的名称是&#8220;/&#8221;。其数据部分的结构如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned long SymbolNum;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 库中符号的数量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned long SymbolOffset[n];&nbsp;&nbsp; // 符号所在目标节的偏移<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char StrTable[m];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 符号名称字符串表<br>&nbsp;&nbsp;&nbsp;&nbsp;}FirstSec;<br>&nbsp;&nbsp;&nbsp;&nbsp;第一个成员SymbolNum是符号的数量。注意！它是以Big-Endian方式储存的（x86平台上的数据是以Little-Endian方式储存的。这里应该注意转换。后面给出的convert函数可以在Little-Endian格式与Big-Endian格式之间进行相互转换）。<br>&nbsp;&nbsp;&nbsp;&nbsp;第二个成员SymbolOffset是一个数组，它的长度n就是符号的数量，也就是SymbolNum。这个数组储存了每一个符号所在的目标节的偏移。我们可以方便地通过它来查找符号所在的目标文件。注意！它也是以Big-Endian格式储存的。<br>&nbsp;&nbsp;&nbsp;&nbsp;第三个成员StrTable是一个字符串表，它的长度m就是SectionHeader.Size的值减去（SymbolNum+1）*4。其结构很简单，就是一堆以&#8216;\0&#8217;结尾的字符串（和COFF文件中的字符串表结构相同）。在有的系统中，它还可能是以&#8220;/\n&#8221;这两个字符结尾的字符串的集合。<br>&nbsp;&nbsp;&nbsp;&nbsp;很简单的一个结构，不过有两个成员的长度是不定的。怎么才能方便地从Lib中读出这些数据，留给大家自己想吧！下面我只给出一个进行Little-Endian与Big-Endian互转的函数。<br>&nbsp;&nbsp;&nbsp;&nbsp;inline void convert(void * p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 要转换的数据的指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,size_t size = 4&nbsp;&nbsp;// 数据的长度，long为4，short为2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char * buf=(char*)p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ( size_t i=0;i&lt;size/2;i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=buf[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[i]=buf[size-i-1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[size-i-1]=temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;} </div>
<div>&nbsp;</div>
<div><strong>Second Sec<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;现在看看第二节。<br>&nbsp;&nbsp;&nbsp;&nbsp;这一节与第一节很相似！它通常也就是Lib文件的第二个节。它的名字也是&#8220;/&#8221;（注意：文件中第一个叫&#8220;/&#8221;的节是第一节，第二个就是第二节）。不过它的结构与第一节有些不同，如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned long ObjNum;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;// Obj Sec的数量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned long ObjOffset[x];&nbsp;&nbsp;// 每一个Obj Sec的偏移<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned long SymbolNum;&nbsp;&nbsp;&nbsp; &nbsp;// 库中符号的数量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned short SymbolIdx[n];&nbsp;// 符号在ObjOffset表中的索引<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char StrTable[m];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 符号名称字符串表<br>&nbsp;&nbsp;&nbsp;&nbsp;}SecondSec;<br>&nbsp;&nbsp;&nbsp;&nbsp;第一个成员ObjNum是库中Obj Sec的数量。<br>&nbsp;&nbsp;&nbsp;&nbsp;第二个成员ObjOffset是一个偏移表，它记录了库中所有Obj Sec的偏移。这个表的记录数x就是ObjNum。<br>&nbsp;&nbsp;&nbsp;&nbsp;第三个成员SymbolNum与First Sec中的SymbolNum意义相同。<br>&nbsp;&nbsp;&nbsp;&nbsp;第四个成员SymbolIdx变成了一个索引，它记录了相应名称字符串在ObjOffset这个表中的位置，我们要通过两次索引才能找到我们所要符号的Obj Sec位置。它的项目数n为SymbolNum。但请注意，这个索引是unsigned short型，不再是unsigned long型。<br>&nbsp;&nbsp;&nbsp;&nbsp;第五个成员StrTable结构与First Sec中的一样。不过，它的长度m为SectionHeader.Size的值减去((ObjNum+1)*4+(SymbolNum+2)*2)。<br>&nbsp;&nbsp;&nbsp;&nbsp;值得注意的是，这里的所有数据都是Little-Endian格式的。千万不要弄错了！<br><br><strong>Longname Sec</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;这个小节就是一个字符串表，它的名称为&#8220;//&#8221;，其结构同FirstSec.StrTable。这里就不多说了。<br><strong><br>Obj Sec</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;这一节中的数据就是COFF文件的原始数据，把它读出来存成文件，就是一个COFF文件。它的格式请参考《COFF格式》一文。<br>&nbsp;&nbsp;&nbsp;&nbsp;要指出的是它的命名方式有些特殊。如果Obj文件的名称少于16个字符，它就会被保存在SectionHeader的Name成员中，以&#8216;/&#8217;字符结尾。如果无法保存在Name成员中，则Name成员的第一个字符就为&#8216;/&#8217;，之后再跟上这个名称在Longname Sec中的偏移。<br><strong><br>例如</strong>：<br>!&lt;arch&gt;\n<br>&#8230;&#8230;<br>LongName Sec:<br>This_Is_Long_Name0001\0<br>This_Is_Long_Name0002\0<br>&#8230;&#8230;<br>Obj Sec1:<br>&nbsp;Name[16]：&#8220;shortname/&#8221;<br>&nbsp;&#8230;&#8230;<br>Obj Sec2:<br>&nbsp;Name[16]：&#8220;/0&#8221;&nbsp;&nbsp;// 这里使用了第一个长文件名This_Is_Long_Name0001<br>&nbsp;&#8230;&#8230;<br>Obj Sec3:<br>&nbsp;Name[16]：&#8220;/22&#8221;&nbsp;&nbsp;// 这里使用了第二个长文件名This_Is_Long_Name0002<br>&nbsp;&#8230;&#8230;</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;OK！现在已经介绍完了Lib文件的结构。大家的连接器可以加新功能了。不过这里只给出了最基本的Lib文件结构，动态连接库（DLL）的导出库有点特别，我将在PE文件格式中进行详细介绍。</div>
<img src ="http://www.cppblog.com/Winux32/aggbug/28363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-07-19 16:54 <a href="http://www.cppblog.com/Winux32/archive/2007/07/19/28363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COFF文件的格式zz</title><link>http://www.cppblog.com/Winux32/archive/2007/07/19/28362.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Thu, 19 Jul 2007 08:52:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/07/19/28362.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/28362.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/07/19/28362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/28362.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/28362.html</trackback:ping><description><![CDATA[COFF &#8211; 通用对象文件格式（Common Object File Format），是一种很流行的对象文件格式（注意：这里不说它是&#8220;目标&#8221;文件，是为了和编译器产生的目标文件（*.o/*.obj）相区别，因为这种格式不只用于目标文件，库文件、可执行文件也经常是这种格式）。大家可能会经常使用VC吧？它所产生的目标文件（*.obj）就是这种格式。其它的编译器，如GCC（GNU Compiler Collection）、ICL（Intel C/C++ Compiler）、VectorC，也使用这种格式的目标文件。不仅仅是C/C++，很多其它语言也使用这种格式的对象文件。统一格式的目标文件为混合语言编程带来了极大的方便。<br>&nbsp;&nbsp;&nbsp;&nbsp;当然，并不是只有这一种对象文件格式。常用格式的还有OMF-对象模型文件（Object Module File）以及ELF-可执行及连接文件格式（Executable and Linking Format）。OMF是一大群IT巨头在n年制定的一种格式，在Windows平台上很常见。大家喜欢的Borland公司现在使用的目标文件就是这种格式。MS和Intel在n年前用的也是这种格式，现在都改投异侧，用COFF格式了。ELF格式在非Windows平台上使用得比较多，在Windows平台基本上没见过。做为程序员，很有必要认识一下这些你经常打交道的家伙！不过这次让我介绍COFF先！
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;<strong>COFF的文件结构<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;让我们先来看一下COFF文件的整体结构，看看它到底长得什么样！</div>
<table style="WIDTH: 535px; HEIGHT: 197px" cellSpacing=0 cellPadding=0 border=0>
    <center>
    <tbody>
        <tr>
            <td vAlign=top>
            <table style="WIDTH: 130px; HEIGHT: 231px" cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width=130 align=center bgColor=#ffffff borderColorLight=#000000 border=1>
                <tbody>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>File Header</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Optional Header</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Section Header 1</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>......</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Section Header n</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Section Data</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Relocation Directives</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Line Numbers</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>Symbol Table</p>
                        </td>
                    </tr>
                    <tr>
                        <td vAlign=top width=441>
                        <p align=center>String Table</p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td vAlign=top>如左图：<br>COFF文件一共有8种数据，自上而下分别为：<br>1.&nbsp;文件头（File Header）<br>2.&nbsp;可选头（Optional Header）<br>3.&nbsp;段落头（Section Header）<br>4.&nbsp;段落数据（Section Data）<br>5.&nbsp;重定位表（Relocation Directives）<br>6.&nbsp;行号表（Line Numbers）<br>7.&nbsp;符号表（Symbol Table）<br>8.&nbsp;字符串表（String Table）</td>
        </tr>
    </tbody>
</table>
</center>
<div>&nbsp;&nbsp;&nbsp;&nbsp;其中，除了段落头可以有多个节（因为可以有多个段落）以外，其它的所有类型的节最多只能有一个。<br>&nbsp;&nbsp;&nbsp;&nbsp;文件头：顾名思义，它就是COFF文件的头，它用来保存COFF文件的基本信息，如文件标识，各个表的位置等等。<br>&nbsp;&nbsp;&nbsp;&nbsp;可选头：再顾名思义，它也是一个头，还是可选的，而且可有可无。在目标文件中，基本上都没有这个头；但在其它的文件中（如：可执行文件）这个段用来保存在文件头中没有描述到的信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;段落头：又顾&#8230;&#8230;（不顾了，再顾有人要打我了<span lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Wingdings; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-char-type: symbol; mso-symbol-font-family: Wingdings"><span style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"><font color=#000000>J</font></span></span>），这个头（怎么这么多的头啊？！）是用来描述段落信息的，每个段落都有一个段落头来描述。段落的数目在文件头中会指出。<br>&nbsp;&nbsp;&nbsp;&nbsp;段落数据：这通常是COFF文件中最大的数据段，每个段落真正的数据就保存在这个位置。至于怎么区分这些数据是哪个段落的，不要问我，去问段落头。<br>&nbsp;&nbsp;&nbsp;&nbsp;重定位表：这个表通常只存在于目标文件中，它用来描述COFF文件中符号的重定位信息。至于为什么要重定位，请回家看看你的操作系统的书籍。<br>&nbsp;&nbsp;&nbsp;&nbsp;符号表：这个表用来保存COFF文件中所用到的所有符号的信息，连接多个COFF文件时，这个表帮助我们重定位符号。调试程序时也要用到它。<br>&nbsp;&nbsp;&nbsp;&nbsp;字符串表：不用我说，大家也知道它用来保存字符串的。可是字符串保存给谁看呢？不知道了吧！？问我啊！<span lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Wingdings; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-char-type: symbol; mso-symbol-font-family: Wingdings"><span style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"><font color=#000000>J</font></span></span>符号表是以记录的形式来描述符号信息的，但它只为符号名称留置了8个字符的空间，早期的小程序还将就能行，可在现在的程序中，一个符号名动不动就数十个字符，8个字符怎么能够？没办法，只好把这些名称存在字符串表中。而符号表中只记录这些字符串的位置。<br>&nbsp;&nbsp;&nbsp;&nbsp;文件的结构大体上就是这样了。长得是丑了点，不过还算它的设计者有点远见。可扩充性设计得不错，以致于沿用至今。了解了文件的整体结构，现在让我们来逐个段落分析它。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>文件头</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;文件头，自然是从文件的0偏移处开始，它的结构很简单。用C的结构描述如下：<br>typedef struct {<br>&nbsp; unsigned short usMagic;&nbsp;&nbsp;// 魔法数字<br>&nbsp; unsigned short usNumSec;&nbsp;&nbsp;// 段落（Section）数<br>&nbsp; unsigned long&nbsp; ulTime;&nbsp;&nbsp;// 时间戳<br>&nbsp; unsigned long&nbsp; ulSymbolOffset;&nbsp;&nbsp;// 符号表偏移<br>&nbsp; unsigned long&nbsp; ulNumSymbol;&nbsp;&nbsp;// 符号数<br>&nbsp; unsigned short usOptHdrSZ;&nbsp;&nbsp;// 可选头长度<br>&nbsp; unsigned short usFlags;&nbsp;&nbsp;// 文件标记<br>} FILEHDR;<br>&nbsp;&nbsp;&nbsp;&nbsp;结构中usMagic成员是一个魔法数字（Magic Number），在I386平台上的COFF文件中它的值为0x014c。如果COFF文件头中魔法数字不为0x014c，那就不用看了，这不是一个I386平台的COFF文件。其实这就是一个平台标识。<br>&nbsp;&nbsp;&nbsp;&nbsp;第二个成员usNumSec是一个无符号短整型，它用来描述段落的数量。段落头（Section Header）的数目就是它。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulTime成员是一个时间戳，它用来描述COFF文件的建立时间。当COFF文件为一个可执行文件时，这个时间戳经常用来当做一个加密用的比对标识。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulSymbolOffset是符号表在文件中的偏移量，这是一个绝对偏移量，要从文件头开始计数。在COFF文件的其它节中，也存在这种偏移量，它们都是绝对偏移量。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulNumSymbol成员给出了符号表中符号记录的数量。<br>&nbsp;&nbsp;&nbsp;&nbsp;usOptHdrSZ是可选头的长度，通常它为0。而可选头的类型也是从这个长度得知的，针对不同的长度，我们就要选择不同的处理方式。<br>&nbsp;&nbsp;&nbsp;&nbsp;usFlag是COFF文件的属性标记，它标识了COFF文件的类型，COFF文件中所保存的数据等等信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;其值如下：<br></div>
<div>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="80%" align=center bgColor=#ffffff borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=55>值</td>
            <td vAlign=top width=72>名称 </td>
            <td vAlign=top width=441>说明</td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0001 </td>
            <td vAlign=top width=72>F_RELFLG </td>
            <td vAlign=top width=441>无重定位信息标记。这个标记指出COFF文件中没有重定位信息。通常在目标文件中这个标记们为0，在可执行文件中为1。 </td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0002 </td>
            <td vAlign=top width=72>F_EXEC </td>
            <td vAlign=top width=441>可执行标记。这个标记指出 COFF</font> 文件中所有符号已经解析， COFF</font> 文件应该被认为是可执行文件。 </td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0004 </td>
            <td vAlign=top width=72>F_LNNO </td>
            <td vAlign=top width=441><span 无行号标记。这个标记说明 COFF<font>文件中所有行号已经被去掉。 </span></td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0008 </td>
            <td vAlign=top width=72>F_LSYMS </td>
            <td vAlign=top width=441><span 无符号标记。此标记说明 COFF<font>文件中的符号信息已经被去掉。 </span></td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0100 </td>
            <td vAlign=top width=72>F_AR32WR </td>
            <td vAlign=top width=441>些标记指出文件是 32 位的 Little-Endian COFF 文件。 </td>
        </tr>
    </tbody>
</table>
</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;注：Little-Endian，记不得它的中文名称了。它是指数据的排列方式。比如：十六进制的0x1234以Little-Endian方式在内存中的顺序为0x34 0x12。与之相反的是Big-Endian，这种方式下，在内存中的顺序是0x12 0x34。<br>这个表的内容并不全面，但在目标文件中，常用的也就只有这些。其它的标记我将在以后介绍PE格式时给出。<br>可选头<br>&nbsp;&nbsp;&nbsp;&nbsp;可选头接在文件头的后面，也就是从COFF文件的0x0014偏移处开始。长度可以为0。不同长度的可选头，其结构也不同。标准的可选头长度为24或28字节，通常是28啦。这里我就只介绍长度为28的可选头。（因为这种头的长度是自定义的，不同的人定义的结果就不一样，我只能选一种最常用的头来介绍，别的我也不知道）<br>这种头的结构如下：<br>typedef struct {<br>&nbsp; unsigned short usMagic;&nbsp;&nbsp;// 魔法数字<br>&nbsp; unsigned short usVersion;&nbsp;&nbsp;// 版本标识<br>&nbsp; unsigned long&nbsp; ulTextSize;&nbsp;&nbsp;// 正文（text）段大小<br>&nbsp; unsigned long&nbsp; ulInitDataSZ;&nbsp;&nbsp;// 已初始化数据段大小<br>&nbsp; unsigned long&nbsp; ulUninitDataSZ;&nbsp;&nbsp;// 未初始化数据段大小<br>&nbsp; unsigned long&nbsp; ulEntry;&nbsp;&nbsp;// 入口点<br>&nbsp; unsigned long&nbsp; ulTextBase;&nbsp;&nbsp;// 正文段基址<br>&nbsp; unsigned long&nbsp; ulDataBase;&nbsp;&nbsp;// 数据段基址（在PE32中才有）<br>} OPTHDR;<br>&nbsp;&nbsp;&nbsp;&nbsp;第一个成员usMagic还是魔法数字，不过这回它的值应该为0x010b或0x0107。当值为0x010b时，说明COFF文件是一个一般的可执行文件；当值为，0x0107时，COFF则为一个ROM镜像文件。<br>&nbsp;&nbsp;&nbsp;&nbsp;usVersion是COFF文件的版本，ulTextSize是这个可执行COFF的正文段长度，ulInitDataSZ和ulUninitDataSZ分别为已初始化数据段和未初始化数据段的长度。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulEntry是程序的入口点，也就是COFF载入内存时正文段的位置（EIP寄存器的值），当COFF文件是一个动态库时，入口点也就是动态库的入口函数。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulTextBase是正文段的基址。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulDataBase是数据段基址。<br>&nbsp;&nbsp;&nbsp;&nbsp;其实在这些成员中，只要注意usMagic和ulEntry就可以了。<br></div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>段落头</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;段落头紧跟在可选头的后面（如果可选头的长度为0，那么它就是紧跟在文件头后）。它的长度为36个字节，如下：<br>typedef struct {<br>&nbsp; char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cName[8];&nbsp;&nbsp;// 段名<br>&nbsp; unsigned long&nbsp; ulVSize;&nbsp;&nbsp;// 虚拟大小<br>&nbsp; unsigned long&nbsp; ulVAddr;&nbsp;&nbsp;// 虚拟地址<br>&nbsp; unsigned long&nbsp; ulSize;&nbsp;&nbsp;// 段长度<br>&nbsp; unsigned long&nbsp; ulSecOffset;&nbsp;&nbsp;// 段数据偏移<br>&nbsp; unsigned long&nbsp; ulRelOffset;&nbsp;&nbsp;// 段重定位表偏移<br>&nbsp; unsigned long&nbsp; ulLNOffset;&nbsp;&nbsp;// 行号表偏移<br>&nbsp; unsigned short ulNumRel;&nbsp;&nbsp;// 重定位表长度<br>&nbsp; unsigned short ulNumLN;&nbsp;&nbsp;// 行号表长度<br>&nbsp; unsigned long&nbsp; ulFlags;&nbsp;&nbsp;// 段标识<br>} SECHDR;<br>&nbsp;&nbsp;&nbsp;&nbsp;这个头可是个重要的头头，我们要用到的最终信息就由它来描述。一个COFF文件可以不要其它的节，但文件头和段落头这两节是必不可少的。<br>&nbsp;&nbsp;&nbsp;&nbsp;cName用来保存段名，常用的段名有.text，.data，.comment，.bss等。.text段是正文段，通常也就是代码段；.data是数据段，在这个数据段中所保存的数据是初始化过的数据；.bss段也可以用来保存数据，不过这里的数据是未初始化的，这个段也是一个空段；.comment段，看名字也知道，它是注释段，用来保存一些编译信息，算是对COFF文件的注释。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulVSize是段数据载入内存时的大小。只在可执行文件中有效，在目标文件中总为0。如果它的长度大于段的实际长度，则多的部分将用0来填充。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulVAddr是段数据载入或连接时的虚拟地址。对于可执行文件来说，这个地址是相对于它的地址空间而言。当可执行文件被载入内存时，这个地址就是段中数据的第一个字节的位置。而对于目标文件而言，这只是重定位时，段数据当前位置的一个偏移量。为了计算方便，便定位的计算简化，它通常设为0。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulSize这才是段中数据的实际长度，也就是段数据的长度，在读取段数据时就由它来确定要读多少字节。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulSecOffset是段数据在COFF文件中的偏移量。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulRelOffset是该段的重定位信息的偏移量。它指向了重定位表的一个记录。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulLNOffset是该段的行号表的偏移量。它指向的是行号表中的一个记录。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulNumRel是重定位信息的记录数。从ulRelOffset指向的记录开始，到第ulNumRel个记录为止，都是该段的重定位信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulNumLN和ulNumRel相似。不过它是行号信息的记录数。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulFlags是该段的属性标识。其值如下表：<br>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="80%" align=center bgColor=#ffffff borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=55>值</td>
            <td vAlign=top width=72>名称 </td>
            <td vAlign=top width=441>说明</td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0020</td>
            <td vAlign=top width=72>STYP_TEXT</td>
            <td vAlign=top width=441>正文段标识，说明该段是代码。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0040 </td>
            <td vAlign=top width=72>STYP_DATA </td>
            <td vAlign=top width=441>数据段标识，有些标识的段将用来保存已初始化数据。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>0x0080 </td>
            <td vAlign=top width=72>STYP_BSS</td>
            <td vAlign=top width=441><span 无行号标记。这个标记说明 COFF<font>有这个标识段也是用来保存数据，不过这里的数据是未初始化数据。</span></td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;注意，在BSS段中，ulVSize、ulVAddr、ulSize、ulSecOffset、ulRelOffset、ulLNOffset、ulNumRel、ulNumLN的值都为0。（上表只是部分值，其它值在PE格式中介绍，后同）<br></div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>段数据</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;人&#8221;如其名，这里是保存各个段的数据的位置。不同类型的段，数据的内容、结构也不尽相同。但在目标文件中，这些数据都是原始数据（Raw Data）。不存在什么特别的格式。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>重定位表</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;这个表所保存的是各个段的重定位信息。这是一张很大的表，因为所有段的重定位信息都在这个表里。各个段落头记录了自己的重定位信息的偏移和数量。要用到重定位信息时就到这个表里来读。当然，你也可以把整个重定位表看成多个重定位表，每个段落都有一个自己的重定位表。这个表只在目标文件中有，可执行文件中是不存在这个表的。<br>&nbsp;&nbsp;&nbsp;&nbsp;既然有表，那么就会有记录。重定位表中的每一条记录就是一条重定位信息。这个记录的结构很简单，如下：<br>typedef struct {<br>&nbsp; unsigned long&nbsp; ulAddr;&nbsp;&nbsp;// 定位偏移<br>&nbsp; unsigned long&nbsp; ulSymbol;&nbsp;&nbsp;// 符号<br>&nbsp; unsigned short usType;&nbsp;&nbsp;// 定位类型<br>} RELOC;<br>&nbsp;&nbsp;&nbsp;&nbsp;有够简单吧，一共只三个成员！ulAddr是要定位的内容在段内偏移。比如：一个正文段，起始位置为0x010，ulAddr的值为0x05，那你的定位信息就要写在0x15处。而且信息的长度要看你的代码的类型，32位的代码要写4个字节，16位的就只要字2个字节。<br>&nbsp;&nbsp;&nbsp;&nbsp;ulSymbol是符号索引，它指向符号表中的一个记录。注意，这里是索引，不是偏移！它只是符号表中的一个记录的记录号。这个成员指明了重定位信息所对映的符号。<br>usType是重定位类型的标识。32位代码中，通常只用两种定位方式。一是绝对定位，二是相对定位。其代码如下：<br>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="80%" align=center bgColor=#ffffff borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=55>值</td>
            <td vAlign=top width=72>名称 </td>
            <td vAlign=top width=441>说明</td>
        </tr>
        <tr>
            <td vAlign=top width=55>6</td>
            <td vAlign=top width=72>RELOC_ADDR32</td>
            <td vAlign=top width=441>32位绝对定位。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>20</td>
            <td vAlign=top width=72>RELOC_REL32 </td>
            <td vAlign=top width=441>32位相对定位。</td>
        </tr>
        </td>
    </tr>
</tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;对于不同的处理器，这些值也不尽相同。这里给出的是i386平台上最常用的两个种定位方式的标识。<br>&nbsp;&nbsp;&nbsp;&nbsp;其定位方式如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>绝对定位</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;在绝对定位方式下，你要给出符号的绝对地址（注意，有时候这里可能不是地址，而是值，对于常量来说，你不用给出它的地值，只用给出它的值）。当然，这个地址也不是现成的，你要用符号的相对地址＋它所在段的相对地址来得到它的绝对地址。<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>公式：符号绝对地址＝段偏移＋符号偏移</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;这些偏移量你要分别从段落头和符号表中得到。当段落要重定位时，当然还要先重定位段落，才能定位其中的符号。<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>相对定位</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;相对定位要复杂一些。它所要的地址信息是相对于当前位置的偏移，这个当前位置就是ulAddr所指向的这个偏移的绝对地址后四个字节（32位代码是四个字节，16位是两个字节）的位置。也就是用定位偏移＋当前段偏移＋机器字长&#247;8<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>公式：当前地址＝定位偏移＋当前段偏移＋机器字长&#247;8</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;有了当前地址，相对地址就好计算了。只要用符号的绝对地址减去当前地址就可以了。<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>公式：相对地址＝符号绝对地址-当前地址</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;计算好了地址，把它写到ulAddr所指向的位置，就一切OK！你已经完成了重定位的工作了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>行号表</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;行号表在调试时很有用。它把可执行的二进制代码与源代码的行号之间建立了对映关系。这样，当程序执行不正确时（其实正确的也可以<span lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: Wingdings; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-char-type: symbol; mso-symbol-font-family: Wingdings"><span style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"><font color=#000000>J</font></span></span>），我们就可以根据当前执行代码的位置得知出错源代码的行号，再加以修改。如果没有它的话，鬼才知道是哪一行出了毛病！<br>&nbsp;&nbsp;&nbsp;&nbsp;它的格式也很简单。只有两个成员，如下：<br>typedef struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned long ulAddrORSymbol;&nbsp;&nbsp;// 代码地址或符号索引<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned short usLineNo;&nbsp;&nbsp;// 行号<br>} LINENO;<br>&nbsp;&nbsp;&nbsp;&nbsp;让我们先看第二个成员，usLineNo。这是一个从1开始计数的计数器，它代表源代码的行号。第一个成员ulAddrORSymbol在行号大于0时，代表源代码的地址；而当行号为0时，它就成了行号所对映的符号在符号表中的索引。下面让我们来看看符号表吧！<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>符号表</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;符号表是对象文件中用来保存符号信息的一张表，也是COFF文件中最为复杂的一张表。所有段落使用到的符号都在这个表里。它也是由很多条记录组成，每条记录都以如下结构保存：<br>typedef struct {<br>&nbsp; union {<br>&nbsp;&nbsp;&nbsp; char cName[8];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 符号名称<br>&nbsp;&nbsp;&nbsp; struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long ulZero;&nbsp;&nbsp;&nbsp;// 字符串表标识<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long ulOffset;&nbsp;// 字符串偏移<br>&nbsp;&nbsp;&nbsp; } e;<br>&nbsp; } e;<br>&nbsp; unsigned long ulValue;&nbsp; &nbsp;&nbsp;&nbsp;// 符号值<br>&nbsp; short iSection;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 符号所在段<br>&nbsp; unsigned short usType; &nbsp; &nbsp;&nbsp;// 符号类型<br>&nbsp; unsigned char usClass;&nbsp;&nbsp; &nbsp;&nbsp;// 符号存储类型<br>&nbsp; unsigned char usNumAux;&nbsp; &nbsp;&nbsp;// 符号附加记录数<br>} SYMENT;<br>&nbsp;&nbsp;&nbsp;&nbsp;cName符号名称，和前面所有的名称一样，它也是8个字节，但不同的是它在一个联合体中。和它占相同的存储空间的还有ulZero和ulOffset这两个成员。如果符号的名称只有8个字符，那很好，可以直接放到这个cName中；可是，如果名称的长度大于8个字节，这里就放不下了，只好放到字符串表中。这时候，ulZero的值就会为0，而在ulOffset中会给出我们所用的符号的名称在字符串表中的偏移。<br>&nbsp;&nbsp;&nbsp;&nbsp;一个符号有了名称不够，它还要有值！ulValue就是这个符号所代表的值。<br>&nbsp;&nbsp;&nbsp;&nbsp;iSection成员指出了这个符号所在的段落。如果它的值为0，那么这个符号就是一个外部符号，要从其它的COFF文件中解析（连接多个目标文件就是要解析这种符号）。当它的值为-1时，说明这个符号的值是一个常量，不是它在段落中的偏移。而当它的值为-2时，这个符号只是一个调试符号，只有在调试时才会用到它。当它大于0时，才是符号所在段的索引值。<br>&nbsp;&nbsp;&nbsp;&nbsp;usType是符号的类型标识。它用来说明这个符号的类型，是函数？整型？还是其它什么。这个标识是两个字节。<br>&nbsp;&nbsp;&nbsp;&nbsp;低字节的低四位是基本标识，它指出了符号的基本类型，如整型，字符，结构，联合等。高四位指出了符号的高级类型，如指针（0001b），函数（0010b），数组（0011b），无类型（0000b）等。现在的编译器，通常不使用基本类型，只使用高级类型。所以，符号的基本类型通常被设为0。<br>高字节通常未用。<br>&nbsp;&nbsp;&nbsp;&nbsp;usClass是符号的存储类型标识。它指明了符号的存储方式。<br>&nbsp;&nbsp;&nbsp;&nbsp;其值与意义见下表：<br>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="80%" align=center bgColor=#ffffff borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=55>值</td>
            <td vAlign=top width=72>名称 </td>
            <td vAlign=top width=441>说明</td>
        </tr>
        <tr>
            <td vAlign=top width=55>NULL</td>
            <td vAlign=top width=72>0</td>
            <td vAlign=top width=441>无存储类型。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>AUTOMATIC</td>
            <td vAlign=top width=72>1</td>
            <td vAlign=top width=441>自动类型。通常是在栈中分配的变量。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>EXTERNAL</td>
            <td vAlign=top width=72>2</td>
            <td vAlign=top width=441>外部符号。当为外部符号时，iSection的值应该为0，如果不为0，则ulValue为符号在段中的偏移。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>STATIC</td>
            <td vAlign=top width=72>3</td>
            <td vAlign=top width=441>静态类型。ulValue为符号在段中的偏移。如果偏移为0，那么这个符号代表段名。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>REGISTER</td>
            <td vAlign=top width=72>4</td>
            <td vAlign=top width=441>寄存器变量。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>MEMBER_OF_STRUCT</td>
            <td vAlign=top width=72>8</td>
            <td vAlign=top width=441>结构成员。ulValue值为该符号在结构中的顺序。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>STRUCT_TAG</td>
            <td vAlign=top width=72>10</td>
            <td vAlign=top width=441>结构标识符。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>MEMBER_OF_UNION</td>
            <td vAlign=top width=72>11</td>
            <td vAlign=top width=441>联合成员。ulValue值为该符号在联合中的顺序。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>UNION_TAG</td>
            <td vAlign=top width=72>12</td>
            <td vAlign=top width=441>联合标识符。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>TYPE_DEFINITION</td>
            <td vAlign=top width=72>13</td>
            <td vAlign=top width=441>类型定义。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>FUNCTION</td>
            <td vAlign=top width=72>101</td>
            <td vAlign=top width=441>函数名。</td>
        </tr>
        <tr>
            <td vAlign=top width=55>FILE</td>
            <td vAlign=top width=72>102</td>
            <td vAlign=top width=441>文件名。</td>
        </tr>
    </tbody>
</table>
</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;最后一个成员usNumAux是附加记录的数量。附加记录是用来描述符号的一些附加信息，为了便于保存，这些附加记录通常选择成为一条符号信息记录的整数倍（多数为1）。所以，如果这个成员的值为1，那么就表示在当前符号信息记录后附加了一条记录，用来保存附加信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;附加信息的结构是与符号的类型以及存储类型相关的。不同的类型的符号，其附加信息（如果有的话）的结构也不同。如果你不在意这些内容，也可以把它们乎略。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当段的类型为FILE时，附加信息就是一个字符串，它是目标文件对应源文件的名称。其它类型在介绍PE时再进行详细讨论。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>字符串表</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;不用多说，瞎子也能看出这个表是用来保存字符串的。它紧接在符号表后。至于为什么要保存字符串，前面已经说过了。这里就不再多说了，只说说字符串的保存格式。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;字符串表是所有节中最简单一节。如下图：</div>
<div align=center>0&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;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div>
<table style="WIDTH: 162px; HEIGHT: 8px" cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width=162 align=center bgColor=#ffffff borderColorLight=#000000 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=%50>字符串表长度</td>
            <td vAlign=top width=%50>字符串1\0</td>
        </tr>
        <tr>
            <td vAlign=top width=%50>....</td>
            <td vAlign=top width=%50>字符串n\0</td>
        </tr>
        </td>
    </tr>
</tbody>
</table>
</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;字符串表的前四个字节是字符串表的长度，以字节为单位。其后就是以0结尾的字符串（C风格字符串）。要注意的是，字符串表的长度不仅仅是字符串的长度（这个长度要包括每个字符串后的&#8216;\0&#8217;）的总合，它还包括这个长度域的四个字节。符号表中ulOffset成员所指出的偏移就是从字符串表起始处的偏移。比如：指像每一个字符串的符号，ulOffset的值总为4。<br>&nbsp;&nbsp;&nbsp;&nbsp;下面给出的代码，是从字符串表中读取字符串的典型C代码。<br><br>int iStrlen,iCur=4;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // iStrLen是字符串表的长度，iCur是当前字符串偏移<br>char *str;&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>read(fn, &amp;iStrlen, 4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 得到字符串表长度<br>str = (char *)malloc(iStrlen);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 为字符串表分配空间<br>while (iCur&lt;iStrlen )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 读字符串表，直到全部读入内存<br>&nbsp;&nbsp;&nbsp;&nbsp;iCur+=read(fn, str+iCur, iStrlen- iCur);<br>iCur=4;&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;// 把当前字符串偏移指到每一个字符串<br>while (iCur&lt;iStrlen ) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 显示每一个字符串<br>&nbsp;&nbsp;&nbsp;&nbsp;printf("String offset 0x%04X : %s\n", iCur, str + iCur);<br>&nbsp;&nbsp;&nbsp;&nbsp;iCur+=(strlen(str+iCur)+1); &nbsp;&nbsp; &nbsp;// 计算偏移时不要忘了计算&#8216;\0&#8217;字符所占的1个字节！<br>}<br>free(str);&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;// 释放字符串表空间</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;直到这里，整个COFF的结构已经全部介绍完了。很多了解PE格式的朋友一定会奇怪，好像少了很多内容！？是的，标准的COFF文件只有这么多的东西。但MS为了和DOS的可执行文件兼容，以及对可执行文件功能的扩展，在COFF格式中加了很多它自己的标准。让我差点就认不出COFF了。但了解了COFF文件以后，再来学习PE文件的格式，那就很简单了。<br>&nbsp;&nbsp;&nbsp;&nbsp;想了解PE文件的格式？网上有很多它的资料，我将在本文的基础上再写几篇文章，分别介绍PE，OMF以及ELF的格式。<br>&nbsp;&nbsp;&nbsp;&nbsp;现在大家可以自己动手，写一个COFF文件解析器或是一个简单的连接程序了！</div>
<img src ="http://www.cppblog.com/Winux32/aggbug/28362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-07-19 16:52 <a href="http://www.cppblog.com/Winux32/archive/2007/07/19/28362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>微软C/C++ 编译器选项zz</title><link>http://www.cppblog.com/Winux32/archive/2007/07/17/28227.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 17 Jul 2007 15:16:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/07/17/28227.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/28227.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/07/17/28227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/28227.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/28227.html</trackback:ping><description><![CDATA[微软C/C++ 编译器选项 <br>-优化- <br>/O1 最小化空间 minimize space <br>/Op[-] 改善浮点数一致性 improve floating-pt consistency <br>/O2 最大化速度 maximize speed <br>/Os 优选代码空间 favor code space <br>/Oa 假设没有别名 assume no aliasing <br>/Ot 优选代码速度 favor code speed <br>/Ob 内联展开（默认 n=0） inline expansion (default n=0) <br>/Ow 假设交叉函数别名 assume cross-function aliasing <br>/Od 禁用优化（默认值） disable optimizations (default) <br>/Ox 最大化选项。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs) <br>/Og 启用全局优化 enable global optimization <br>/Oy[-] 启用框架指针省略 enable frame pointer omission <br>/Oi 启用内建函数 enable intrinsic functions <br>-代码生成- <br>/G3 为 80386 进行优化 optimize for 80386 <br>/G4 为 80486 进行优化 optimize for 80486 <br>/GR[-] 启用 C++ RTTI enable C++ RTTI <br>/G5 为 Pentium 进行优化 optimize for Pentium <br>/G6 为 Pentium Pro 进行优化 optimize for Pentium Pro <br>/GX[-] 启用 C++ 异常处理（与 /EHsc 相同） enable C++ EH (same as /EHsc) <br>/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH <br>/GD 为 Windows DLL 进行优化 optimize for Windows DLL <br>/GB 为混合模型进行优化（默认） optimize for blended model (default) <br>/EHa 启用异步 C++ 异常处理 enable asynchronous C++ EH <br>/Gd __cdecl 调用约定 __cdecl calling convention <br>/EHc extern&#8220;C&#8221;默认为 nothrow extern "C" defaults to nothrow <br>/Gr __fastcall 调用约定 __fastcall calling convention <br>/Gi[-] 启用增量编译 enable incremental compilation <br>/Gz __stdcall 调用约定 __stdcall calling convention <br>/Gm[-] 启用最小重新生成 enable minimal rebuild <br>/GA 为 Windows 应用程序进行优化 optimize for Windows Application <br>/Gf 启用字符串池 enable string pooling <br>/QIfdiv[-] 启用 Pentium FDIV 修复 enable Pentium FDIV fix <br>/GF 启用只读字符串池 enable read-only string pooling <br>/QI0f[-] 启用 Pentium 0x0f 修复 enable Pentium 0x0f fix <br>/Gy 分隔链接器函数 separate functions for linker <br>/GZ 启用运行时调试检查 enable runtime debug checks <br>/Gh 启用钩子函数调用 enable hook function call <br>/Ge 对所有函数强制堆栈检查 force stack checking for all funcs <br>/Gs[num] 禁用堆栈检查调用 disable stack checking calls <br>-输出文件- <br>/Fa[file] 命名程序集列表文件 name assembly listing file <br>/Fo 命名对象文件 name object file <br>/FA[sc] 配置程序集列表 configure assembly listing <br>/Fp 命名预编译头文件 name precompiled header file <br>/Fd[file] 命名 .PDB 文件 name .PDB file <br>/Fr[file] 命名源浏览器文件 name source browser file <br>/Fe 命名可执行文件 name executable file <br>/FR[file] 命名扩展 .SBR 文件 name extended .SBR file <br>/Fm[file] 命名映射文件 name map file <br>-预处理器- <br>/FI 命名强制包含文件 name forced include file <br>/C 不吸取注释 don't strip comments <br>/U 移除预定义宏 remove predefined macro <br>/D{=|#} 定义宏 define macro <br>/u 移除所有预定义宏 remove all predefined macros <br>/E 将预处理定向到标准输出 preprocess to stdout <br>/I 添加到包含文件的搜索路径 add to include search path <br>/EP 将预处理定向到标准输出，不要带行号 preprocess to stdout, no #line <br>/X 忽略&#8220;标准位置&#8221; ignore "standard places" <br>/P 预处理到文件 preprocess to file <br>-语言- <br>/Zi 启用调试信息 enable debugging information <br>/Zl 忽略 .OBJ 中的默认库名 omit default library name in .OBJ <br>/ZI 启用调试信息的&#8220;编辑并继续&#8221;功能 enable Edit and Continue debug info <br>/Zg 生成函数原型 generate function prototypes <br>/Z7 启用旧式调试信息 enable old-style debug info <br>/Zs 只进行语法检查 syntax check only <br>/Zd 仅要行号调试信息 line number debugging info only <br>/vd{0|1} 禁用/启用 vtordisp disable/enable vtordisp <br>/Zp[n] 在 n 字节边界上包装结构 pack structs on n-byte boundary <br>/vm 指向成员的指针类型 type of pointers to members <br>/Za 禁用扩展（暗指 /Op） disable extensions (implies /Op) <br>/noBool 禁用&#8220;bool&#8221;关键字 disable "bool" keyword <br>/Ze 启用扩展（默认） enable extensions (default) <br>- 杂项 - <br>/?, /help 打印此帮助消息 print this help message <br>/c 只编译，不链接 compile only, no link <br>/W 设置警告等级（默认 n=1） set warning level (default n=1) <br>/H 最大化外部名称长度 max external name length <br>/J 默认 char 类型是 unsigned default char type is unsigned <br>/nologo 取消显示版权消息 suppress copyright message <br>/WX 将警告视为错误 treat warnings as errors <br>/Tc 将文件编译为 .c compile file as .c <br>/Yc[file] 创建 .PCH 文件 create .PCH file <br>/Tp 将文件编译为 .cpp compile file as .cpp <br>/Yd 将调试信息放在每个 .OBJ 中 put debug info in every .OBJ <br>/TC 将所有文件编译为 .c compile all files as .c <br>/TP 将所有文件编译为 .cpp compile all files as .cpp <br>/Yu[file] 使用 .PCH 文件 use .PCH file <br>/V 设置版本字符串 set version string <br>/YX[file] 自动的 .PCH 文件 automatic .PCH <br>/w 禁用所有警告 disable all warnings <br>/Zm 最大内存分配（默认为 %） max memory alloc (% of default) <br>-链接- <br>/MD 与 MSVCRT.LIB 链接 link with MSVCRT.LIB <br>/MDd 与 MSVCRTD.LIB 调试库链接 link with MSVCRTD.LIB debug lib <br>/ML 与 LIBC.LIB 链接 link with LIBC.LIB <br>/MLd 与 LIBCD.LIB 调试库链接 link with LIBCD.LIB debug lib <br>/MT 与 LIBCMT.LIB 链接 link with LIBCMT.LIB <br>/MTd 与 LIBCMTD.LIB 调试库链接 link with LIBCMTD.LIB debug lib <br>/LD 创建 .DLL Create .DLL <br>/F 设置堆栈大小 set stack size <br>/LDd 创建 .DLL 调试库 Create .DLL debug libary <br>/link [链接器选项和库] [linker options and libraries]
<img src ="http://www.cppblog.com/Winux32/aggbug/28227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-07-17 23:16 <a href="http://www.cppblog.com/Winux32/archive/2007/07/17/28227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++各大有名库的介绍z </title><link>http://www.cppblog.com/Winux32/archive/2007/03/13/19771.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 13 Mar 2007 12:51:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/03/13/19771.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/19771.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/03/13/19771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/19771.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/19771.html</trackback:ping><description><![CDATA[
		<p>各大有名库的介绍</p>
		<p>转载自：<a href="http://www.csdn.net/">www.csdn.net</a></p>
		<p>在C++中，库的地位是非常高的。C++之父 Bjarne Stroustrup先生多次表示了设计库来扩充功能要好过设计更多的语法的言论。现实中，C++的库门类繁多，解决的问题也是极其广泛，库从轻量级到重量级的都有。不少都是让人眼界大开，亦或是望而生叹的思维杰作。由于库的数量非常庞大，而且限于笔者水平，其中很多并不了解。所以文中所提的一些库都是比较著名的大型库。</p>
		<p>标准库</p>
		<p>标准库中提供了C++程序的基本设施。虽然C++标准库随着C++标准折腾了许多年，直到标准的出台才正式定型，但是在标准库的实现上却很令人欣慰得看到多种实现，并且已被实践证明为有工业级别强度的佳作。</p>
		<p>1、   Dinkumware C++ Library</p>
		<p>参考站点：<a href="http://www.dinkumware.com/'&gt;http://www.dinkumware.com/">http://www.dinkumware.com/'&gt;http://www.dinkumware.com/</a></p>
		<p>P.J. Plauger编写的高品质的标准库。P.J. Plauger博士是Dr. Dobb's程序设计杰出奖的获得者。其编写的库长期被Microsoft采用，并且最近Borland也取得了其OEM的license，在其C/C++的产品中采用Dinkumware的库。</p>
		<p>2、   RogueWave Standard C++ Library</p>
		<p>参考站点：</p>
		<p>
				<a href="http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/">http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/</a>
		</p>
		<p>这个库在Borland C++ Builder的早期版本中曾经被采用，后来被其他的库给替换了。笔者不推荐使用。</p>
		<p>3、SGI STL</p>
		<p>参考站点：</p>
		<p>
				<a href="http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/">http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/'&gt;http://www.roguewave.com/</a>
		</p>
		<p>SGI公司的C++标准模版库。</p>
		<p>4、STLport</p>
		<p>参考站点：<a href="http://www.stlport.org/'&gt;http://www.stlport.org/">http://www.stlport.org/'&gt;http://www.stlport.org/</a></p>
		<p>SGI STL库的跨平台可移植版本。</p>
		<p> </p>
		<p>准标准库——Boost</p>
		<p>Boost库是一个经过千锤百炼、可移植、提供源代码的C++库，作为标准库的后备，是C++标准化进程的发动机之一。 Boost库由C++标准委员会库工作组成员发起，在C++社区中影响甚大，其成员已近2000人。 Boost库为我们带来了最新、最酷、最实用的技术，是不折不扣的“准”标准库。</p>
		<p>Boost中比较有名气的有这么几个库：</p>
		<p>Regex<br />正则表达式库</p>
		<p>Spirit<br />LL parser framework，用C++代码直接表达EBNF</p>
		<p>Graph<br />图组件和算法</p>
		<p>Lambda<br />在调用的地方定义短小匿名的函数对象，很实用的functional功能</p>
		<p>concept check<br />检查泛型编程中的concept</p>
		<p>Mpl<br />用模板实现的元编程框架</p>
		<p>Thread<br />可移植的C++多线程库</p>
		<p>Python<br />把C++类和函数映射到Python之中</p>
		<p>Pool<br />内存池管理</p>
		<p>smart_ptr<br />5个智能指针，学习智能指针必读，一份不错的参考是来自CUJ的文章：<br />Smart Pointers in Boost,哦，这篇文章可以查到，CUJ是提供在线浏览的。中文版见笔者在《Dr.Dobb's Journal软件研发杂志》第7辑上的译文。</p>
		<p>Boost总体来说是实用价值很高，质量很高的库。并且由于其对跨平台的强调，对标准C++的强调，是编写平台无关，现代C++的开发者必备的工具。但是Boost中也有很多是实验性质的东西，在实际的开发中实用需要谨慎。并且很多Boost中的库功能堪称对语言功能的扩展，其构造用尽精巧的手法，不要贸然的花费时间研读。Boost另外一面，比如Graph这样的库则是具有工业强度，结构良好，非常值得研读的精品代码，并且也可以放心的在产品代码中多多利用。</p>
		<p>参考站点：<a href="http://www.boost.org'&gt;http://www.boost.org">http://www.boost.org'&gt;http://www.boost.org</a>（国内镜像：</p>
		<p>
				<a href="http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.c-view.org/tech/lib/boost/index.htm">http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.c-view.org/tech/lib/boost/index.htm</a>）</p>
		<p>GUI</p>
		<p>在众多C++的库中，GUI部分的库算是比较繁荣，也比较引人注目的。在实际开发中，GUI库的选择也是非常重要的一件事情，下面我们综述一下可选择的GUI库，各自的特点以及相关工具的支持。</p>
		<p>1、   MFC</p>
		<p>大名鼎鼎的微软基础类库（Microsoft Foundation Class）。大凡学过VC++的人都应该知道这个库。虽然从技术角度讲，MFC是不大漂亮的，但是它构建于Windows API 之上，能够使程序员的工作更容易,编程效率高，减少了大量在建立 Windows 程序时必须编写的代码，同时它还提供了所有一般 C++ 编程的优点，例如继承和封装。MFC 编写的程序在各个版本的Windows操作系统上是可移植的，例如，在Windows 3.1下编写的代码可以很容易地移植到 Windows NT 或 Windows 95 上。但是在最近发展以及官方支持上日渐势微。</p>
		<p>2、   QT</p>
		<p>参考网站：<a href="http://www.trolltech.com/'&gt;http://www.trolltech.com/">http://www.trolltech.com/'&gt;http://www.trolltech.com/</a></p>
		<p>Qt是Trolltech公司的一个多平台的C++图形用户界面应用程序框架。它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt是完全面向对象的很容易扩展，并且允许真正地组件编程。自从1996年早些时候，Qt进入商业领域，它已经成为全世界范围内数千种成功的应用程序的基础。Qt也是流行的Linux桌面环境KDE 的基础，同时它还支持Windows、Macintosh、Unix/X11等多种平台。</p>
		<p>3、WxWindows</p>
		<p>参考网站：<a href="http://www.wxwindows.org/'&gt;http://www.wxwindows.org/">http://www.wxwindows.org/'&gt;http://www.wxwindows.org/</a></p>
		<p>跨平台的GUI库。因为其类层次极像MFC，所以有文章介绍从MFC到WxWindows的代码移植以实现跨平台的功能。通过多年的开发也是一个日趋完善的GUI库，支持同样不弱于前面两个库。并且是完全开放源代码的。新近的C++ Builder X的GUI设计器就是基于这个库的。</p>
		<p>4、Fox</p>
		<p>开放源代码的GUI库。作者从自己亲身的开发经验中得出了一个理想的GUI库应该是什么样子的感受出发，从而开始了对这个库的开发。有兴趣的可以尝试一下。</p>
		<p>参考网站：<a href="http://www.fox'&gt;http://www.fox-toolkit.org/">http://www.fox'&gt;http://www.fox-toolkit.org/</a></p>
		<p>5、   WTL</p>
		<p>基于ATL的一个库。因为使用了大量ATL的轻量级手法，模板等技术，在代码尺寸，以及速度优化方面做得非常到位。主要面向的使用群体是开发COM轻量级供网络下载的可视化控件的开发者。</p>
		<p>6、   GTK</p>
		<p>参考网站：<a href="http://gtkmm.sourceforge.net/">http://gtkmm.sourceforge.net/</a></p>
		<p>GTK是一个大名鼎鼎的C的开源GUI库。在Linux世界中有Gnome这样的杀手应用。而GTK就是这个库的C++封装版本。</p>
		<p>
				<br />网络通信</p>
		<p>ACE</p>
		<p>参考网站：</p>
		<p>
				<a href="http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.cs.wustl.edu/~schmidt/ACE.html</a>
		</p>
		<p>C++库的代表，超重量级的网络通信开发框架。ACE自适配通信环境（Adaptive Communication Environment）是可以自由使用、开放源代码的面向对象框架，在其中实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++包装外观（Wrapper Facade）和框架组件，可跨越多种平台完成通用的通信软件任务，其中包括：事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、分布式服务动态（重）配置、并发执行和同步，等等。</p>
		<p>StreamModule</p>
		<p>参考网站：<a href="http://www.omnifarious.org/StrMod/'&gt;http://www.omnifarious.org/StrMod/">http://www.omnifarious.org/StrMod/'&gt;http://www.omnifarious.org/StrMod/</a></p>
		<p>设计用于简化编写分布式程序的库。尝试着使得编写处理异步行为的程序更容易，而不是用同步的外壳包起异步的本质。</p>
		<p>SimpleSocket</p>
		<p>参考网站：<a href="http://home.hetnet.nl/~lcbokkers/simsock.htm">http://home.hetnet.nl/~lcbokkers/simsock.htm</a></p>
		<p>这个类库让编写基于socket的客户/服务器程序更加容易。</p>
		<p>A Stream Socket API for C++</p>
		<p>参考网站：</p>
		<p>
				<a href="http://www.pcs.cnu.edu/'&gt;http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html">http://www.pcs.cnu.edu/'&gt;http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html</a>
		</p>
		<p>又一个对Socket的封装库。</p>
		<p>XML</p>
		<p>Xerces</p>
		<p>参考网站：<a href="http://xml.apache.org/xerces-c/">http://xml.apache.org/xerces-c/</a></p>
		<p>Xerces-C++ 是一个非常健壮的XML解析器，它提供了验证，以及SAX和DOM API。XML验证在文档类型定义(Document Type Definition，DTD)方面有很好的支持，并且在2001年12月增加了支持W3C XML Schema 的基本完整的开放标准。</p>
		<p>XMLBooster</p>
		<p>参考网站：<a href="http://www.xmlbooster.com/'&gt;http://www.xmlbooster.com/">http://www.xmlbooster.com/'&gt;http://www.xmlbooster.com/</a></p>
		<p>这个库通过产生特制的parser的办法极大的提高了XML解析的速度，并且能够产生相应的GUI程序来修改这个parser。在DOM和SAX两大主流XML解析办法之外提供了另外一个可行的解决方案。</p>
		<p>Pull Parser</p>
		<p>         参考网站：</p>
		<p>
				<a href="http://www.extreme.indiana.edu/xgws/xsoap/xpp/'&gt;http://www.extreme.indiana.edu/xgws/xsoap/xpp/">http://www.extreme.indiana.edu/xgws/xsoap/xpp/'&gt;http://www.extreme.indiana.edu/xgws/xsoap/xpp/</a>
		</p>
		<p>         这个库采用pull方法的parser。在每个SAX的parser底层都有一个pull的parser，这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得尝试。</p>
		<p>Xalan</p>
		<p>         参考网站：<a href="http://xml.apache.org/xalan-c/">http://xml.apache.org/xalan-c/</a></p>
		<p>         Xalan是一个用于把XML文档转换为HTML，纯文本或者其他XML类型文档的XSLT处理器。</p>
		<p>CMarkup</p>
		<p>         参考网站：<a href="http://www.firstobject.com/xml.htm'&gt;http://www.firstobject.com/xml.htm">http://www.firstobject.com/xml.htm'&gt;http://www.firstobject.com/xml.htm</a></p>
		<p>         这是一种使用EDOM的XML解析器。在很多思路上面非常灵活实用。值得大家在DOM和SAX之外寻求一点灵感。</p>
		<p>libxml++</p>
		<p>
				<a href="http://libxmlplusplus.sourceforge.net/">http://libxmlplusplus.sourceforge.net/</a>
		</p>
		<p>libxml++是对著名的libxml XML解析器的C++封装版本</p>
		<p> </p>
		<p>科学计算</p>
		<p>Blitz++</p>
		<p>参考网站：<a href="http://www.oonumerics.org/blitz/'&gt;http://www.oonumerics.org/blitz/">http://www.oonumerics.org/blitz/'&gt;http://www.oonumerics.org/blitz/</a></p>
		<p>Blitz++ 是一个高效率的数值计算函数库，它的设计目的是希望建立一套既具像C++ 一样方便，同时又比Fortran速度更快的数值计算环境。通常，用C++所写出的数值程序，比 Fortran慢20%左右，因此Blitz++正是要改掉这个缺点。方法是利用C++的template技术，程序执行甚至可以比Fortran更快。Blitz++目前仍在发展中，对于常见的SVD，FFTs，QMRES等常见的线性代数方法并不提供，不过使用者可以很容易地利用Blitz++所提供的函数来构建。</p>
		<p>POOMA</p>
		<p>参考网站：</p>
		<p>
				<a href="http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.codesourcery.com/pooma/pooma">http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.codesourcery.com/pooma/pooma</a>
		</p>
		<p>POOMA是一个免费的高性能的C++库，用于处理并行式科学计算。POOMA的面向对象设计方便了快速的程序开发，对并行机器进行了优化以达到最高的效率，方便在工业和研究环境中使用。</p>
		<p>MTL</p>
		<p>参考网站：<a href="http://www.osl.iu.edu/research/mtl/'&gt;http://www.osl.iu.edu/research/mtl/">http://www.osl.iu.edu/research/mtl/'&gt;http://www.osl.iu.edu/research/mtl/</a></p>
		<p>Matrix Template Library(MTL)是一个高性能的泛型组件库，提供了各种格式矩阵的大量线性代数方面的功能。在某些应用使用高性能编译器的情况下，比如Intel的编译器，从产生的汇编代码可以看出其与手写几乎没有两样的效能。</p>
		<p>CGAL</p>
		<p>参考网站：<a href="http://www.cgal.org/">www.cgal.org</a></p>
		<p>Computational Geometry Algorithms Library的目的是把在计算几何方面的大部分重要的解决方案和方法以C++库的形式提供给工业和学术界的用户。</p>
		<p> </p>
		<p>游戏开发</p>
		<p>Audio/Video 3D C++ Programming Library</p>
		<p>参考网站：</p>
		<p>
				<a href="http://www.galacticasoftware.com/products/av/'&gt;http://www.galacticasoftware.com/products/av/">http://www.galacticasoftware.com/products/av/'&gt;http://www.galacticasoftware.com/products/av/</a>
		</p>
		<p>AV3D是一个跨平台，高性能的C++库。主要的特性是提供3D图形，声效支持（SB,以及S3M），控制接口（键盘，鼠标和遥感），XMS。</p>
		<p>KlayGE</p>
		<p>参考网站：<a href="http://home.g365.net/enginedev/">http://home.g365.net/enginedev/</a></p>
		<p>国内游戏开发高手自己用C++开发的游戏引擎。KlayGE是一个开放源代码、跨平台的游戏引擎，并使用Python作脚本语言。KlayGE在LGPL协议下发行。感谢龚敏敏先生为中国游戏开发事业所做出的贡献。</p>
		<p>OGRE</p>
		<p>参考网站：<a href="http://www.ogre3d.org'&gt;http://www.ogre3d.org">http://www.ogre3d.org'&gt;http://www.ogre3d.org</a></p>
		<p>OGRE（面向对象的图形渲染引擎）是用C++开发的，使用灵活的面向对象3D引擎。它的目的是让开发者能更方便和直接地开发基于3D硬件设备的应用程序或游戏。引擎中的类库对更底层的系统库（如：Direct3D和OpenGL）的全部使用细节进行了抽象，并提供了基于现实世界对象的接口和其它类。</p>
		<p> </p>
		<p>线程</p>
		<p>C++ Threads</p>
		<p>参考网站：<a href="http://threads.sourceforge.net/">http://threads.sourceforge.net/</a></p>
		<p>这个库的目标是给程序员提供易于使用的类，这些类被继承以提供在Linux环境中很难看到的大量的线程方面的功能。</p>
		<p>ZThreads</p>
		<p>参考网站：<a href="http://zthread.sourceforge.net/">http://zthread.sourceforge.net/</a></p>
		<p>一个先进的面向对象，跨平台的C++线程和同步库。<br /> </p>
		<p>序列化</p>
		<p>s11n</p>
		<p>参考网站：<a href="http://s11n.net/">http://s11n.net/</a></p>
		<p>一个基于STL的C++库，用于序列化POD，STL容器以及用户定义的类型。</p>
		<p>Simple XML Persistence Library</p>
		<p>参考网站：<a href="http://sxp.sourceforge.net/">http://sxp.sourceforge.net/</a></p>
		<p>这是一个把对象序列化为XML的轻量级的C++库。</p>
		<p> </p>
		<p>字符串</p>
		<p>C++ Str Library</p>
		<p>参考网站：<a href="http://www.utilitycode.com/str/'&gt;http://www.utilitycode.com/str/">http://www.utilitycode.com/str/'&gt;http://www.utilitycode.com/str/</a></p>
		<p>操作字符串和字符的库，支持Windows和支持gcc的多种平台。提供高度优化的代码，并且支持多线程环境和Unicode，同时还有正则表达式的支持。</p>
		<p>Common Text Transformation Library</p>
		<p>参考网站：<a href="http://cttl.sourceforge.net/">http://cttl.sourceforge.net/</a></p>
		<p>这是一个解析和修改STL字符串的库。CTTL substring类可以用来比较，插入，替换以及用EBNF的语法进行解析。</p>
		<p>GRETA</p>
		<p>参考网站：<a href="http://research.microsoft.com/projects/greta/">http://research.microsoft.com/projects/greta/</a></p>
		<p>这是由微软研究院的研究人员开发的处理正则表达式的库。在小型匹配的情况下有非常优秀的表现。</p>
		<p>综合</p>
		<p>P::Classes</p>
		<p>参考网站：<a href="http://pclasses.com/">http://pclasses.com/</a></p>
		<p>一个高度可移植的C++应用程序框架。当前关注类型和线程安全的signal/slot机制，i/o系统包括基于</p>
		<p>插件的网络协议透明的i/o架构，基于插件的应用程序消息日志框架，访问sql数据库的类等等。</p>
		<p>ACDK - Artefaktur Component Development Kit</p>
<img src ="http://www.cppblog.com/Winux32/aggbug/19771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-03-13 20:51 <a href="http://www.cppblog.com/Winux32/archive/2007/03/13/19771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图说历史 ：400年来的计算机编年史！</title><link>http://www.cppblog.com/Winux32/archive/2007/03/11/19577.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Sun, 11 Mar 2007 11:24:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/03/11/19577.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/19577.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/03/11/19577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/19577.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/19577.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 图说历史 ：400年来的计算机编年史！																																										        [史前时代：1623——1895] 　　1623年：德国科学家契克卡德（W. Schickard）制造了人类有史以来第一台机械计算机，这台机器能够进行六位数的加减乘除运算。　　　　　　1642年：法国科学家帕斯卡（B.Pascal...&nbsp;&nbsp;<a href='http://www.cppblog.com/Winux32/archive/2007/03/11/19577.html'>阅读全文</a><img src ="http://www.cppblog.com/Winux32/aggbug/19577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-03-11 19:24 <a href="http://www.cppblog.com/Winux32/archive/2007/03/11/19577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 11-What's a Register File?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/24/17947.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Wed, 24 Jan 2007 01:25:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/24/17947.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17947.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/24/17947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17947.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Register File, Part 1 </h3><dd>Consider a typical R-type instruction. <b><font size="+2"><pre>   add $r10, $r3, $r4   <font color="red"># R[10] = R[3] + R[4]</font></pre></font></b>The first step to executing this instruction is fetching the operands. In this case, we need to get the values of <b>$r3</b> and <b>$r4</b>. 
<p>Recall that the CPU processes a 32-bit machine code instruction that's translated from the assembly code above, and encoded in that instruction are the 3 registers. In particular, each of the register is encoded using 5 bit UB. 
</p><p>For example, register 3 is encoded as <b>00011</b> and register 4 is encoded as <b>00100</b>. 
</p><p>We're going to create a circuit called a <i>register file</i>. This circuit contains all 32 user-visible integer registers. We could create one for floating point, but that's not absolutely necessary. You'll still understand how a CPU works if we leave out floating point registers (they work pretty much like the integer registers). 
</p><p>We want the ability to access both registers (in this case, <b>$r3</b> and <b>$r4</b>) at the same time. That way, we can save time. If we have to access one register at a time, it would slow down the execution of the instruction. 
</p><p>So, we have two sets of inputs to our register file, which specify which two registers we want. They can even be the same register. 
</p><p>Here's how our initial register file looks: 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/RegFile/regfile1.png" /></center><p>We've labelled the inputs as <b>SRC 1 Index</b> and <b>SRC 2 Index</b>, which are 5 bits each. We can think of registers 3 and 4 and source registers, and their result is stored in the destination register (in our example, it's <b>$r10</b>). </p></dd><dt></dt><h3>Register File, Part 2 </h3><dd>However, we need the register file to have outputs. These outputs are going to be 32 bits each since each register in MIPS32 has 32 bits. The outputs are the contents of the registers specified by <b>SRC 1 Index</b> and <b>SRC 2 Index</b>. Thus <b>SRC 1 Data</b> is the contents of the register specified by <b>SRC 1 Index</b>, and <b>SRC 2 Data</b> is the contents of the register specified by <b>SRC 2 Index</b>. 
<p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/RegFile/regfile2.png" /></center></dd><dt></dt><h3>Register File, Part 3 </h3><dd>At this point, the two 32-bit outputs are sent to the ALU (we'll discuss the ALU in more detail soon). The ALU does computations on these and produces a 32-bit result. This result is saved back into the destination register. The register file needs 32-bit data as input as a 5-bit index. We'll call these <b>DST Index</b> and <b>DST Data</b> for short. 
<p>The <b>DST Index</b> comes from the instruction itself, just as <b>SRC 1 Index</b> and <b>SRC 2 Index</b> did. In our example, that's the encoding of <b>$r10</b> (which is <b>01010</b>). 
</p><p>It turns out we need one more input, in addition to <b>DST Index</b> and <b>DST Data</b>. Even though this particular instruction updates a destination register, not every instruction does so. We want to control when a register value is updated in the register file. 
</p><p>This control signal is called <b>RegWrite</b> and it's only 1 bit. If <b>RegWrite = 1</b>, then a write is performed on the register specified by <b>DST Index</b>, using the 32-bit data given by <b>DST Data</b>. If <b>RegWrite = 0</b>, then no write is performed. Both <b>DST Index</b> and <b>DST Data</b> are ignored. 
</p><p>Which reminds me, we have to talk about a clock. The register file also has a clock. The diagram below is now complete. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/RegFile/regfile3.png" /></center><h4><i>Why no RegRead?</i></h4>You may wonder why there's no <b>RegRead</b> to control when the register file outputs <b>SRC 1 Data</b> and <b>SRC 2 Data</b>. 
<p>The reason is simple. <b>SRC 1 Data</b> and <b>SRC 2 Data</b> are sent to the outside world (i.e., to other parts of the CPU). Those parts can simply choose to ignore the data, if they don't need it. 
</p><p>However, when you are performing a write on a register using <b>DST Index</b> and <b>DST Data</b>, you are updating the register file. The register file can't very well ignore that. To give it the option to ignore it, we must include <b>RegWrite</b>. </p></dd><dt></dt><h3>Clocks </h3><dd>The register file should be thought of as partly using the clock and partly not. 
<p><b>SRC 1 Data</b> and <b>SRC 2 Data</b> are output with a small delay given a change in <b>SRC 1 Index</b> and <b>SRC 2 Index</b>. If you're curious about the implementation (or, more precisely, if you're curious about <i>an</i> implementation), look at the <b>MAR</b> from the previous set of notes. 
</p><p>You can see that it's hooked up to tri-state buffers. Once the tri-state buffers are enabled (which doesn't require a clock), the output is sent to the address bus. 
</p><p>Similarly, <b>SRC 1 Index</b> and <b>SRC 2 Index</b> enable two 32-bit tri-state buffers. In particular, they enable the tri-state buffers to the registers specified by <b>SRC 1 Index</b> and <b>SRC 2 Index</b>. 
</p><p>Again, this part does not need a clock. If <b>SRC 1 Index</b> and <b>SRC 2 Index</b> both change, then the tri-state buffers associated with the new registers are enabled (while the previous ones are disabled), and they are output after a small delay. 
</p><h3><i>Writing Requires a Clock</i></h3>However, when you want to write to a register, you are performing a parallel load on that register. This operation relies on a clock. We're going to assume that the register file, like <b>MAR</b> and <b>MDR</b>, is loaded on negative edges. This allows computations to be performed by the rest of the CPU before registers are loaded. 
</dd><dt></dt><h3>Summary </h3><dd>A <b>register file</b> is a black box that contains 32 32-bit registers. At any one time, you can specify up to two registers to "read" and one register to write, with the option to decide whether you want to write or not. 
<p>Reading a value from the register file does not require a clock. Once you specify the registers you want to read (i.e., <b>SRC 1 Index</b> and <b>SRC 2 Index</b>), then there's only a small delay before the data comes out of the register file via <b>SRC 1 Data</b> and <b>SRC 2 Data</b>. 
</p><p>Writing a value to the register file <i>does</i> require a clock. You can specify which register you want to write to (using <b>DST Index</b>), the data you want to write (using <b>DST Data</b>) and whether you really want to write to the register file or not (using <b>RegWrite</b>). This action takes place on the negative edge of the clocks. (Positive edges are used to transition in the finite state machine and set up control signals for ALU, MUX, tri-state buffers, etc). </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-24 09:25 <a href="http://www.cppblog.com/Winux32/archive/2007/01/24/17947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Virtual Bookshelf: What's on Your Shelf?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17932.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 11:09:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17932.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17932.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17932.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17932.html</trackback:ping><description><![CDATA[As you are working your way to a computer science degree, you start to collect books, or at least, you should start. Here's a list of books that you might want to have around. These aren't specifically related to computer organization, though. 
<p></p><ul><li><font size="+1"><b>The C++ Programming Language, Special 3rd Edition</b></font> by Bjarne Stroustrup. 
<p>Bjarne Stroustrup invented the original C++. Many people refer to the book, and though it certainly has its detractors. The book is not aimed for beginning programmers. Instead, it serves as a reference book to C++. You won't find data structures, nor software engineering in this book. 
</p><p>Still, most people who program in C++ own this book. 
</p><p></p></li><li><font size="+1"><b>C++ Primer</b></font> by Stanley Lippman, Josee Lajoie 
<p>For those who don't like Stroustrup, and even those who do, another very good reference book in C++. 
</p><p></p></li><li><font size="+1"><b>Effective C++: 50 Specific Ways to Improve Your Programs and Design</b></font> by Scott Meyers 
<p>Advice on how to improve you C++. What's nice about it is that it's a thin book, and you should be able to read it without taking too much time. Meyers has also written two follow-ups: More Effective C++ and Effective STL. 
</p><p></p></li><li><font size="+1"><b>Design Patterns</b></font> by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. 
<p>The authors are called the GoF (Gang of Four). This is supposedly <i>the</i> book on design patterns. Consider it a collection of ways to organize classes to deal with certain kinds of problems. The main gripe I have about the book is the application domain is a bit large (they talk about how to design a word processor). I would have preferred smaller examples, written in C++ and Java (it's mostly in C++). There are other books on Design Patterns, but none of them seem all that good, except for the following. 
</p><p></p></li><li><font size="+1"><b>Effective Java Programming Language Guide</b></font> by Joshua Bloch 
<p>This book is written like <i>Effective C++</i>. It is a series of tips on writing good Java code. However, it also has advice on design patterns (not a whole lot). You can probably carry over some advice to C++, while you're at it. 
</p><p></p></li><li><font size="+1"><b>C Programming: A Modern Approach</b></font> by K. N. King 
<p>This is the 106 textbook. While I have quibbles with this book for its pedagogy (it doesn't talk about tracing code, its treatment of nested loops is weak, it introduces arrays too late), it's a very good C reference book. King really knows his stuff, and he states things concisely. A great book if you want to brush up on your C. 
</p><p></p></li><li><font size="+1"><b>Introduction to Algorithms: Second Edition</b></font> by Thomas Cormen, Charles Leiserson, Ronald Rivest, and Clifford Stein. 
<p>Before this book, perhaps the classic algorithm book was by Aho, Hopcroft, and Ullman. That algorithms book was pretty dense, written as if it were a math book for math majors. 
</p><p>This book gave meaning to the "instant classic". Instant classics occur when someone writes a decent book so thick, no one else would actually write such a book again (although this hasn't prevented other authors from trying). 
</p><p>The proofs in the book are sometimes wordy, taking up a few pages when one page will do, but is generally friendlier than most algorithms books. If you would prefer a more story-like approach to algorithms, read <b>Algorithmics: The Spirit of Computing</b> by David Harel. You won't learn how to solve algorithms, but you should gain some appreciation of algorithms, nevertheless. 
</p><p></p></li><li><font size="+1"><b>Computer Organization and Design: The Hardware/Software Interface</b></font> by David Patterson and John Hennessy. 
<p>This book does some things well (MIPS assembly language) and some things poorly (digital logic design). At the very least, it acknowledges its weaknesses. You're probably better off with the original, <b>Computer Architecture: A Quantitative Approach</b> (3rd edition) by Patterson and Hennessy (the author's names are reversed), since it covers more advanced topics. 
</p><p></p></li><li><font size="+1"><b>Computer Systems: A Programmer's Perspective</b></font> by Randal Bryant and David O'Hallaron. 
<p>West Coast hardware guys vs. East Coast hardware guys. Patterson and Hennessy were the founders of the RISC movement from Berkeley and Stanford, respectively. Bryant and O'Hallaron are from CMU in Pittsburgh. 
</p><p>Like Patterson and Hennessy, this book does less digital logic than similar computer organization books. For some chapters, the writing is excellent. This book also covers some material that would normally be seen in compiler optimization, and talks about ways to make programs fast. Students learn the most if they can also do the labs associated with the book. 
</p><p>One drawback (IMO) is the use of the IA32 ISA (dubbed "y86" since it's a subset of x86). While x86 dominates the CPU market and MIPS is non-existent, MIPS is easier to understand and is a modern RISC CPU. Still, if you have to learn a CISC ISA, it might as well be x86 based. 
</p><p></p></li><li><font size="+1"><b>Modern C++ Design: Generic Programming and Design Patterns Applied</b></font> by Andrei Alexandrescu 
<p>OK, this isn't for the faint of heart. This kind of book is starting to approach expert level C++, and if you can learn the stuff in here, you're starting to be an ace C++ programmer. 
</p><p></p></li><li><font size="+1"><b>Code Complete: A Practical Handbook of Software Construction</b></font> by Steve McConnell 
<p>Lots of snippets of advice on how to code. Not specific to any language. You should be able to take something from it, no matter what you read. 
</p><p></p></li><li><font size="+1"><b>Types and Programming Languages</b></font> by Benjamin Pierce 
<p>OK, so not <i>everyone</i> should own this book, but if you were ever interested in type theory, this is the book to get. This explains the theory behind type-safe languages such as Java and ML. Of course, it talks about lambda calculus. You do have to like some math (say, math logic) to follow the book, but since most books on type theory are aimed at grad students, this book is the one to get because it should be readable by a reasonably mathematical undergraduate (that is, if you like math and intro algorithms, and 330, you should be able to read this book). 
</p><ul></ul></li></ul><img src ="http://www.cppblog.com/Winux32/aggbug/17932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 19:09 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 10-What's a Multiplexer?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17931.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 10:38:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17931.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17931.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17931.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17931.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17931.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Introduction </h3><dd>In the last set of notes, we talked about a combinational logic device abstractly. Now we're going to look at a specific example of a combinational logic circuit, perhaps one of the most useful ones we'll see: the multiplexer (or MUX, for short). 
<p>The word "multiplexer" probably doesn't mean much to you. If anything, it sounds like a place where you can go watch movies. A better name for a multiplexer might be <b>input selector. 
<p>A multiplexer picks one of several inputs and directs it to the output. We'll see this in more detail. </p><dt></dt><h3>A 2-1 MUX </h3><dd>Let's start off with a 2-1 MUX. A 2-1 MUX has two data inputs, which we'll call <b>x<sub>1</sub></b> and <b>x<sub>0</sub></b>. It has one output, which we'll call <b>z</b>. 
<p>We want to pick either <b>x<sub>1</sub></b> or <b>x<sub>0</sub></b> and direct its value to the output. 
</p><p>How do well tell the MUX which input we want? We need to have <i>control inputs</i>. 
</p><p>How many control inputs are needed? We have two possible inputs, and basically the idea is to <i>label</i> these two choices with as few bits as possible. We've already discussed how to label N items with as few bits as possible. 
</p><p>The answer is: <b>ceil( lg 2 ) = 1</b>. 
</p><p>Thus, we need a single bit for a control input. We'll call this bit, <b>c</b> (which is short for "control"). 
</p><p>The following chart describes the behavior of a 2-1 MUX. 
</p><p></p><center><table cellpadding="5" border="1"><tbody><tr><td bgcolor="pink"><b>c</b></td><td bgcolor="#aaffaa"><b>z</b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td><b>x<sub>0</sub></b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td><b>x<sub>1</sub></b></td></tr></tbody></table></center><p>When <b>c = 0</b>, <b>x<sub>0</sub></b> is directed to the output, <b>z</b>. When <b>c = 1</b>, <b>x<sub>1</sub></b> is directed to the output, <b>z</b>. Notice that we treat <b>c</b> as a 1-bit UB number, and that this number specifies the subscript of the input we want to direct to the output. 
</p><h4>Diagram of 2-1 MUX </h4><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Mux/2_1mux.png" /></center><p>The diagram above illustrates how the 2-1 MUX behaves when <b>c = 0</b> (see upper left diagram) and when <b>c = 1</b> (upper right. </p></dd><dt></dt><h3>A 4-1 MUX </h3><dd>Now we consider a 4-1 MUX. A 4-1 MUX has four data inputs, which we'll call <b>x<sub>3</sub></b>, <b>x<sub>0</sub></b>, <b>x<sub>1</sub></b> and <b>x<sub>0</sub></b>. A 4-1 MUX still has one output, which we'll call <b>z</b>. 
<p>We want to pick one of <b>x<sub>3</sub></b>, <b>x<sub>0</sub></b>, <b>x<sub>1</sub></b> or <b>x<sub>0</sub></b> and direct its value to the output. 
</p><p>How many control inputs are needed? We have four possible inputs, and we want to <i>label</i> these fourc choices with as few bits as possible. How many bits are needed? 
</p><p>The answer is: <b>ceil( lg 4 ) = 2</b>. 
</p><p>We call these two bits <b>c<sub>1..0</sub></b>. We're going to treat <b>c<sub>1..0</sub></b> as a 2-bit UB number. There are four possible bitstring patterns: 00, 01, 10, and 11. They correspond to the following values <b>0<sub>ten</sub></b>, <b>1<sub>ten</sub></b>, <b>2<sub>ten</sub></b>, and <b>3<sub>ten</sub></b>. In particular, these values are going to be the values of the subscripts of the data input. 
</p><p>For example, if <b>c<sub>1..0</sub> = 10</b>, then we want to select <b>x<sub>2</sub></b> to direct to the output since the representation <b>10<sub>two</sub></b> corresponds to the value <b>2<sub>ten</sub></b> using UB representation. 
</p><p>The following chart describes the behavior of a 4-1 MUX. 
</p><p></p><center><table cellpadding="5" border="1"><tbody><tr><td bgcolor="pink"><b>c<sub>1</sub></b></td><td bgcolor="pink"><b>c<sub>0</sub></b></td><td bgcolor="#aaffaa"><b>z</b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>x<sub>0</sub></b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>x<sub>1</sub></b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>x<sub>2</sub></b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>x<sub>3</sub></b></td></tr></tbody></table></center><p>When <b>c<sub>1..0</sub></b> = 00</p></dd></b>, then <b>z = x<sub>0</sub></b>. When <b>c<sub>1..0</sub></b> = 01, then <b>z = x<sub>1</sub></b>. When <b>c<sub>1..0</sub></b> = 10, then <b>z = x<sub>2</sub></b>. When <b>c<sub>1..0</sub></b> = 11, then <b>z = x<sub>3</sub></b>. 
</p><h4>Diagram of 4-1 MUX </h4><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Mux/4_1mux.png" /></center><p>The diagram above illustrates how the 4-1 MUX behaves when <b>c<sub>1..0</sub> = 00</b> (see upper left diagram), when <b>c<sub>1..0</sub> = 01</b> (upper right diagram), when <b>c<sub>1..0</sub> = 10</b> (lower left diagram), and when <b>c<sub>1..0</sub> = 11</b> (lower right diagram), 
</p><p>Notice that when you feed <b>10</b> to the control inputs, you are really feeding two bits of input to the 4-1 MUX, i.e., <b>c<sub>1</sub> = 1</b> and <b>c<sub>0</sub> = 0</b>. However, for brevity we write it as <b>c<sub>1..0</sub> = 10</b>. </p></dd><dt></dt><h3>A 3-1 MUX </h3><dd>Usually MUXes are of the form <b>2<sup>k</sup>-1</b> MUX where <b>k &gt;= 1</b>. That is, the number of inputs for a typical MUX is a power of 2. However, occasionally, you may wish to have number of inputs be some other choice. 
<p>What happens then? For example, supposed you want to have a 3-1 MUX. How many control bits are needed? 
</p><p>We use the same formula as before: <b>ceil( lg 3 ) = 2</b>. 
</p><p><b>lg 3</b> evaluates to a value that is greater than 1, but less than 2. When we take the ceiling of that value, we get 2. 
</p><p>With 2 controls bits, we can specify up to <i>four</i> different inputs. The problem? We only have <i>three</i> inputs. What do we do when the user tries to specify input <b>c<sub>1..0</sub> = 11</b>? This would normally specify that you want <b>z = x<sub>3</sub></b>, but with only 3 inputs, <b>z = x<sub>3</sub></b> doesn't exist. 
</p><p>The answer is simply not to care. Ideally, if a 3-1 MUX is being used in a circuit, the rest of the circuit does not set the control bits, <b>c<sub>1..0</sub> = 11</b>. 
</p><p>However, since we can't prevent that from happening, we simply let the actual designer of the 3-1 MUX pick any value for that. 
</p><p></p><center><table cellpadding="5" border="1"><tbody><tr><td bgcolor="pink"><b>c<sub>1</sub></b></td><td bgcolor="pink"><b>c<sub>0</sub></b></td><td bgcolor="#aaffaa"><b>z</b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>x<sub>0</sub></b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>x<sub>1</sub></b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>x<sub>2</sub></b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>don't care </b></td></tr></tbody></table></center><p>This solution of placing a don't care value for MUXes with <b>k</b> inputs, where <b>k</b> is not a power of 2, is fairly common. If you want, just set the value to <b>x<sub>0</sub></b>. </p></dd><dt></dt><h3>A 2-bit 2-1 MUX </h3><dd>Most information in a 32-bit CPU are grouped into 32 bits. Generally, you want to move 32 bits at a time. So, even a MUX is likely to choose from one of N 32-bit quantities. 
<p>The following is an implementation of a 2-bit 2-1 MUX. In this MUX, you can choose between <b>x<sub>1..0</sub></b> and <b>y<sub>1..0</sub></b> using a control bit <b>c</b>. You can implement this kind of MUX using 2 1-bit 2-1 MUXes. In general, you can create a k-bit m-1 MUX, using k 1-bit m-1 MUX, using a similar strategy as shown below. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Mux/2_bit2_1mux.png" /></center><p>As you can see there are two sets of data inputs: <b>x<sub>1</sub>x<sub>0</sub></b> (which we abbreviate as <b>x<sub>1..0</sub></b>) and <b>y<sub>1</sub>y<sub>0</sub></b> (which we abbreviate as <b>y<sub>1..0</sub></b>). There is one control bit since this is still a 2-1 MUX. There are two bits of output: <b>z<sub>1..0</sub></b>. Inside the black box is the implementation, which include two 1-bit 2-1 MUX. 
</p><p>We could have called this a 4-2 MUX, but it doesn't make it nearly as clear that you have 2 choices to pick from. 2-bit 2-1 MUX indicates that there are 2 choices. 
</p><h3>An Exercise </h3>To see if you understand how the MUXes were constructed, try implementing a 2-bit 4-1 MUX, then a 4-bit 4-1 MUX using 1-bit 4-1 MUXes. 
</dd><dt></dt><h3>A 1-4 DeMUX </h3><dd>If a multiplexer is an input selector that chooses from one of <b>N</b> inputs and directs it to the output, then a <i>demultiplexer</i> is an <i>output selector</i> which has a single input and directs it to one of <b>N</b> outputs. 
<p>Even though a DeMUX appears to be the opposite of a MUX (an <i>output</i> selector versus an <i>input</i> selector), surprisingly, it's not used nearly as often as MUXes. MUXes seem to find more uses than a DeMUXes. 
</p><p>Suppose you have a 1-4 DeMUX. You want to pick one of four possible outputs. How many control inputs do you need? Again, it's the same idea of labelling one of four items. You need <b>ceil( lg 4 ) = 2</b> bits. 
</p><p>The following is a diagram of a 1-4 DeMUX. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Mux/1_4demux.png" /></center></dd><dt></dt><h3>Chart for 1-4 DeMUX </h3><dd>This is the chart that describes the behavior of a 1-4 DeMUX. 
<p></p><center><table cellpadding="5" border="1"><tbody><tr><td bgcolor="pink"><b>c<sub>1</sub></b></td><td bgcolor="pink"><b>c<sub>0</sub></b></td><td bgcolor="#aaffaa"><b>z <sub>0</sub></b></td><td bgcolor="#aaffaa"><b>z <sub>1</sub></b></td><td bgcolor="#aaffaa"><b>z <sub>2</sub></b></td><td bgcolor="#aaffaa"><b>z <sub>3</sub></b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>x </b></td><td><b>0 </b></td><td><b>0 </b></td><td><b>0 </b></td></tr><tr><td bgcolor="yellow"><b>0 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>0 </b></td><td><b>x </b></td><td><b>0 </b></td><td><b>0 </b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>0 </b></td><td><b>0 </b></td><td><b>0 </b></td><td><b>x </b></td><td><b>0 </b></td></tr><tr><td bgcolor="yellow"><b>1 </b></td><td bgcolor="yellow"><b>1 </b></td><td><b>0 </b></td><td><b>0 </b></td><td><b>0 </b></td><td><b>x </b></td></tr></tbody></table></center><p>As you can see, <b>x</b> is directed to one of the outputs. The choice of which output it is directed to is basically the same as it is for the MUX. We treat <b>c<sub>1..0</sub></b> as a 2-bit UB number, which specifies the subscript of the output we want the input to be directed to. 
</p><p>What happens to the remaining outputs? For example, if we decide to direct <b>x</b> to <b>z<sub>2</sub></b>, what values should the other 3 outputs have? Our solution is to have all of the remaining outputs set to 0. 
</p><p>This means that a DeMUX can have, at most one output that is 1. The remaining outputs are 0. This may not always be the behavior you want, but it's easy enough to design a DeMUX such that the remaining outputs are, say, 1. </p></dd><dt></dt><h3>Summary </h3><dd>A MUX is an <i>input selector</i>. It allows you to select from 1 of N inputs and direct it to the output using <b>ceil( lg N )</b> control bits. 
<p>A MUX is also a combinational logic device meaning that once the input to the MUX changes, then after a small delay, the output changes. Unlike a register, a MUX does not use a clock to control it. 
</p><p>A MUX is very handy in a CPU because there are many occasions where you need to select one of several different inputs to some device. Usually, these MUXes are 32-bit m-1 MUX for some value of <b>m</b>. 
</p><p>A DeMUX is an <i>output selector</i>, letting you pick one of N outputs to direct an input to. </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 18:38 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 9-What's a Combinational Logic Device?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17928.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 10:15:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17928.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17928.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17928.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17928.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17928.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Introduction </h3><dd>Digital logic circuits can be divided into two categories: <b>combinational logic</b> and <b>sequential logic</b>. 
<p>Combinational logic devices implement Boolean functions. A Boolean function has <b>k</b> bits of input and <b>m</b> bits of output, where <b>k &gt;= 0</b> and <b>m &gt;= 1</b>. 
</p><p>Any combinational logic device can be constructed out of AND gates, OR gates, and NOT gates. However, they can also be completely constructed using only NAND gates, or using only NOR gates. 
</p><p>You can describe the behavior of a combinational logic device using a truth table. </p></dd><dt></dt><h3>Control vs. Data Inputs </h3><dd>We can often divide the inputs of a combinational logic device into two categories: <b>data</b> inputs and <b>control</b> inputs. 
<p>Control inputs let you control what the device does. For example, if you have a blender, there are often several buttons to let you decide how you want to chop the food. Or a washing machine has several choices you can pick depending on the kind of clothes you are going to wash. It lets you select temperature, time, and the amount of agitation. 
</p><p>If you have <b>N</b> choices for the different operations that a combinational logic device can perform, then you need <b>ceil( lg N )</b> control bits to specify the operation. This result should be familiar, because we discussed it in a previous set of notes. 
</p><p>Some combinational logic devices do not have control inputs. They only have data inputs. However, many of the ones we consider do have them. The combinational logic device doesn't really distinguish between data and control inputs. To the device, it's all just inputs. 
</p><p>However, as humans who use these devices, it's useful to think of these two categories. </p></dd><dt></dt><h3>Changing the Inputs </h3><dd>If you change the values of the inputs to a combinational logic device, there is some short, but finite delay before the output changes. The output can't change instantaneously. 
<p>Notice that this behavior is different from a register. A register is a sequential logic device, which can only change its value at a clock edge. A combinational logic device can change its outputs as soon as the inputs change (plus a little delay from input to output). 
</p><p>Again, it's useful to think that values are continuously being fed to a combinational logic device and the outputs change as the inputs change. 
</p><p>Here's another useful analogy. Suppose you have a flashlight that can shine red light or green light. There's a switch on the flashlight that allows you to switch between red and green. 
</p><p>Suppose you have a light sensor. If the light sensor detects green light, it plays the musical note of "A". If it detects red light, it plays the musical note of "C". If it detects no light, then it doesn't play anything. 
</p><p>So, you shine green light onto the sensor, and it begins to play the note "A". Then, you switch it to red light, and there is a small delay, before it starts to play the note "C". 
</p><p>Then, you switch it back to green light, and, after a tiny delay, it goes back to playing "A". 
</p><p>Finally, you turn the flashlight off, and after a small delay, it stops playing. Notice that as long as the flashlight was shining on the sensor, it played something, but when it was turned off, it stopped playing. The flashlight had to continuously emit red or green light for the sensor device to play a note. 
</p><p>This is one way to think about how circuits work. There is a continuous flow of current into the device. The current's voltage is either interpreted as 0 or 1, and can be changed. If the input changes, then after a small delay, the output current is updated to the new value. </p></dd><dt></dt><h3>Diagram of a Generic Combinational Logic Device </h3><dd><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Comb/comb.png" /></center><p>As you can see, there are <b>k</b> bits of data input, <b>n</b> bits of control inputs, and <b>m</b> bits of output. 
</p><p>When the inputs change, then there is a small delay before the output changes. We see this in the next section. </p></dd><dt></dt><h3>An Example with XOR </h3><dd>Suppose we have a <b>XOR<sub>2</sub></b> which is a 2-input XOR gate. 
<p>Initially, we have two inputs, <b>x</b> and <b>y</b>, whose value are both 0. The output <b>z</b> is 0, as well. Then we change <b>x</b> to 1, and the output <b>z</b>, after some delay becomes 1. Then, we change <b>y</b> to 1, and after some delay, the output <b>z</b> becomes 0. 
</p><p>Here's a timing diagram to illustrate the behavior. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Comb/timing.png" /></center><p>As you can see, at time (1), <b>x</b> changes to <b>1</b>. However, it takes until time (2) for <b>z</b> to change to 1. Then, at time (3), <b>y</b> changes to 1, but it takes until time (4) for <b>z</b> to change back to 0. 
</p><p>The amount of time for <b>z</b> to change is called the circuit delay, and we write it as "delta" T. This time is usually very short. Nevertheless, it's not zero. 
</p><p>Because it's not zero, it affects the way circuits are designed. The smaller the value of <b>delta T</b>, the quicker we can make the circuit. </p></dd><dt></dt><h3>Summary </h3><dd>Unlike a sequential logic device (such as a register), a combinational logic device does not use a clock. Once the input value changes, the output values of a combinational logic device changes, after a small circuit delay. Of course, sometimes the output value doesn't change at all even if the input changes. 
<p>For example, suppose you have an AND gate. If both inputs are 0, then one input is changed to 1, then the output is still 0. However. in those cases where the output changes, there is a delay. 
</p><p>A combinational logic device can be specified by using a truth table, and is an implementation of a Boolean function. Any Boolean function can be implemented using a combination of AND, OR, and NOT gates (or only using NAND gates, <i>or</i> only using NOR gates). </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17928.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 18:15 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17928.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 8-What's a Tri-state Buffer?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17927.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 09:55:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17927.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17927.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17927.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17927.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Pipes </h3><dd>Early on, we came up with an analogy for a wire. We said a wire is like a pipe that can either send red soda (which we said was 0), or green soda (which we said was 1), or no soda (which is <b>Z</b>, whicch is high impedance), or garbage, which occurs when two devices attempt to "pump soda" on the wire. 
<p>We claim that garbage would occur, even if two devices attempt to pump the same kind of soda (i.e., both red or both green). This probably doesn't happen in reality. That is, if two devices attempt to set the value of a wire to 1, the wire is most likely transmitting a 1 without problem. 
</p><p>Nevertheless, we want to avoid this situation. It should be the case that only one device writes a value to the wire, at any given time. There should be no reason for two devices writing to a wire or bus at the same time. Certainly, we expect devices to write to the wire at different times. The idea of a bus, after all, is that it is a shared medium of communication, to be used by all devices connected to the bus. </p></dd><dt></dt><h3>Controlling Registers </h3><dd>Also, recall from our discussion on registers, that a register is always generating output. Once a value gets loaded into a register (which only occurs at a positive clock edge, during a parallel load operation), the value inside the register is sent to the output. 
<p>The outputs of registers are going to be connected to busses, and often there may be more than one register connected to a bus. We want to be able to control when a register writes a value to a bus. 
</p><p>How can we do this? Let's think of our analogy. Suppose we have many small pipes hooked to a much larger pipe. For example, we might have 3 small pipes hooked up to a large pupe. 
</p><p>Suppose each small pipe is connected to a device which pumps soda. We want to make sure only one device is pumping soda into the large pipe. Unfortunately, each device is always pumping soda, which means all three devices are trying to pump soda. 
</p><p>If we can't turn off the device, how do we prevent the soda from being pumped into the large pipe? 
</p><p>One idea is to have some sort of device in the small pipe which can be opened or closed. When the device is closed, even though the device attempts to pump soda, it can't make it to the large pipe. 
</p><p>This device is usually called a <i>valve</i>. If the valve is open, soda can be pumped through. If the valve is closed, no soda can be pumped through. 
</p><p>Here's a diagram to illustrate the concept. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Tristate/valve.png" /></center></dd><dt></dt><h3>Introducing a Tri-State Buffer </h3><dd>There is an electronic equivalent to a valve. It's called a tri-state buffer. The following is a symbol for a tri-state buffer. 
<p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Tristate/tri.png" /></center><p>It looks very much like an inverter (a NOT gate) except it's missing a circle at the right side (where <b>z</b> is located). This tiny circle usually indicates that the device is inverting the input, <b>x</b>. 
</p><p>Unlike an inverter, a tri-state buffer has two inputs. It has a data input (labelled <b>x</b>) and a control input (labelled <b>c</b>). 
</p><p>When <b>c = 1</b>, the valve is open, and the output <b>z</b> is the same as the input <b>x</b>. Essentially, it lets the input value flow to the output. This input value can be 0, 1, Z, or ? (garbage). 
</p><p>When <b>c = 0</b>, the valve is closed, and the output <b>z = Z</b>, which means no electrical current (i.e., no 0's and 1's) is flowing through. 
</p><h4>Regular Buffers </h4>There are buffers which do not have a control input. Thus, the output is exactly the same as the input. It's the same as a tri-state buffer where <b>c</b> is always 1. Does that seem silly to you? The reason for such a device is to strengthen the signal. For example, when you make a phone call, the signal is sent over a wire, or perhaps a fiber optic cable. 
<p>Over distance, a signal begins to lose strength. There are devices called <i>repeaters</i> which are meant to boost the strength of the signal. That's essentially what a plain buffer is. 
</p><p>However, we're interested in tri-state buffers, primarily because they behave like valves. They allow us to control which devices can write to a bus. </p></dd><dt></dt><h3>Chart for Tri-State Buffer </h3><dd><center><table cellpadding="7" border="1"><tbody><tr align="middle"><td bgcolor="yellow">  <b>c</b>  </td><td bgcolor="pink">  <b>x</b>   </td><td bgcolor="#aaffaa">  <b>z</b>   </td></tr><tr align="middle"><td><b>0 </b></td><td><b>0 </b></td><td><b>Z </b></td></tr><tr align="middle"><td><b>0 </b></td><td><b>1 </b></td><td><b>Z </b></td></tr><tr align="middle"><td><b>0 </b></td><td><b>Z </b></td><td><b>Z </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>0 </b></td><td><b>0 </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>1 </b></td><td><b>1 </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>Z </b></td><td><b>Z </b></td></tr></tbody></table></center><p><b>x</b> is the data input. <b>c</b> is the control input, which turns on and off the valve. <b>z</b> is the output. <b>Z</b> (which is capitalized), means "no current", which, in our analogy, is "no soda" being pumped through. </p></dd><dt></dt><h3>A 32-bit Tri-State Buffer </h3><dd>Most of the times, we're not interested in controlling the output of one bit to one wire. We're interested in 32 bits to 32 wires. We treat the 32 bits as one grouping of data. 
<p>We'd like to be able to use a single bit to control when, say, a register is allowed to write its 32 bit contents to a bus. If this bit is 1, then all 32 bits are written to the bus. If the bit is 0, then none of the bits are sent to the bus. 
</p><p>This can be easily implemented using 32 tri-state buffers. 
</p><p>The example below shows how to implement a 4-bit tri-state buffer using 4 1-bit tri-state buffers. It's easy to extend this idea to 32 bits. 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Tristate/tri4.png" /></center><p>There is a bus containing 4 wires going into the "black box" (we get to see the inside of the black box) labelled <b>x<sub>3..0</sub></b>. 
</p><p>Inside the black box, we split the bus into individual wires labelled <b>x<sub>0</sub></b> through <b>x<sub>3</sub></b>. Each wire goes through a 1-bit tri-state buffer. 
</p><p>There's a single control bit <b>c</b> coming from the outside world, and this one bit is attached to each of the four tri-state buffers. So, either all four tri-state buffers let the input values go through or none of them go through. 
</p><p>As you can see, the implementation is pretty simple. </p></dd><dt></dt><h3>Summary </h3><dd>There are some hardware devices that always generate some output, such as registers. Many of these devices are often hooked to a bus, where only one device should write to at a time. Tri-state buffers allow us to control which device outputs its value to the bus, by allowing us to selectively control the control bit of the tri-state buffer. 
<p>Usually, we use 32-bit tri-state buffers, which have 32 data inputs, 32 outputs, but a single control bit. The implementation is shown above. </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 17:55 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 7-What's Memory?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17925.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 08:59:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17925.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17925.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17925.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17925.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>A Simple Model of a Computer </h3><dd>In order to understand a computer, we need to have a model of how it looks. A <i>model</i> is a simplification of reality. It keeps all the essential parts of the reality, and leaves out unimportant parts. 
<p>For example, a map models the roads in, say, a city. However, it doesn't tell you how much traffic is on each road, or where there are stop lights, or what offices or stores are near those roads. That information is either too difficult or too time-sensitive (i.e., it would get obsolete fast) to include in a map. 
</p><p>Our model of a computer is very simple, yet it has all the essential elements we need to understand these notes. 
</p><p>Here's an picture of our "computer". 
</p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Memory/comp.png" /></center><p>The CPU contains registers and an ALU. The memory contains data and instructions. The CPU is connected to the memory through two busses: a 32 bit data bus and a 32 bit address bus. </p></dd><dt></dt><h3>A Simple Model of Memory </h3><dd>We're going to treat memory as a large one-dimensional array. This array can have up to <b>2<sup>32</sup></b> elements. Each element stores one byte. 
<p>When you first learned about arrays, you learned that an array has an index, and it has contents at that index. It's possible to confuse the two. After all, the index and the contents at that index are often numbers. 
</p><p>We don't use the word <i>index</i> to refer to an element at a location. Instead, we use the word <i>address</i>. 
</p><p>Memory is often said to be <i>byte-addressable</i>, which means that each address stores one byte. We could also talk about <i>nybble-addressable</i> (each address stores one nybble, which is 4 bits), or perhaps a <i>word-addressable</i> memory (each address stores one word, which we define to be 32 bits). However, it's very rare to see anything besides byte-addressable memory. </p></dd><dt></dt><h3>How to Store a Word </h3><dd>Suppose you want to store a quantity larger than one byte in memory. What do you do? For example, you may want to store 32 bits. Many quantities in the CPU have 32 bits (which is 4 bytes). 
<p>Most people would agree that you break the quantity into 4 bytes, and store them at four consecutive addresses in memory. 
</p><p>In particular, suppose you had a 32-bit word denoted as <b>B<sub>31..0</sub></b>. You can divide this into four bytes: <b>B<sub>31..24</sub></b>, <b>B<sub>23..16</sub></b>, <b>B<sub>15..8</sub></b>, and <b>B<sub>7..0</sub></b>. We'll call <b>B<sub>31..24</sub></b> the most significant byte, or the high byte. We'll call <b>B<sub>7..9</sub></b> the least significant byte, or the low byte. 
</p><p>Let's say we store these four bytes at addresses 1000, 1001, 1002, and 1003. 
</p><p>However, there are two (common) ways to store four consecutive bytes. You can store high byte at the smallest address, i.e,, store <b>B<sub>31..24</sub></b> at address 1000 (and store <b>B<sub>23..16</sub></b> at address 1001, <b>B<sub>15..8</sub></b> at address 1002, and <b>B<sub>7..0</sub></b> at address 1003). This is called <i>big-endian</i>, because the big end (the high byte) is stored first. 
</p><p>Or you can store low byte at the smallest address, i.e,, store <b>B<sub>7..0</sub></b> at address 1000 (and store <b>B<sub>15..8</sub></b> at address 1001, <b>B<sub>23..16</sub></b> at address 1002, and <b>B<sub>31..24</sub></b> at address 1003). This is called <i>little-endian</i>, because the little end (the low byte) is stored first. 
</p><p>Even though a word takes up four addresses, we usually refer only to the smallest address when indicating the location in memory. So you simply have to be aware that you may be storing more than one byte, and thus more than one address in memory is being used. 
</p><p>Endianness affects any quantity larger than a byte. So halfwords (two bytes) have endianness, as do doublewords (eight bytes). </p></dd><dt></dt><h3>Word Alignment </h3><dd>For technical reasons, words are stored at word-aligned addresses. Recall that when we refer to an address of the word, it's the address of the first byte. For big-endian machines, the first byte is the high byte. For little-endian machines, the first byte is the low byte. The first byte is the byte at the smallest address. 
<p>A word-aligned address is an address that is divisible by 4. Equivalently, you can say it's an addresss that is a multiple of 4, or an address whose low two bits <b>A<sub>1..0</sub> = 00</b>. That is, it's low two bits are both 0. (See why that's the same as being divisible by 4). 
</p><p>Halfwords are half-word aligned. This means half-words must be stored at addresses divisible by 2. This is equivalent to saying the address of a half-word aligned quantity, when written in binary, must have its least significant bit set to 0. That is, <b>A<sub>0</sub> = 0</b>. 
</p><p>Doublewords are double-word aligned. This means double-words must be stored at addresses divisible by 8. This is equivalent to saying the address of a double-word aligned quantity, when written in binary, must have its low 3 bits set to 0. That is, <b>A<sub>2..0</sub> = 000</b>. 
</p><p>In general, if you have <b>2<sup>k</sup></b> bytes, it must be stored at address that is divisible by <b>2<sup>k</sup></b> and that bits <b>A<sub>k-1..0</sub> = 0<sup>k-1</sup></b>. 
</p><p>Some CPUs do not have word alignment, but nearly all RISC CPUs do, so it's important to understand the concept. </p></dd><dt></dt><h3>What Does the Memory Hold? </h3><dd>We can have up to <b>2<sup>32</sup></b> bytes in memory. That's potentially 4 gigabytes of memory! This is a lot. 
<p>What is memory used for? It is used to store information. In particular, it can store: 
</p><p></p><ul type="disc"><li><b>data</b> This can be integers, floating point numbers, MPEGS, JPEGs, or any variety of data formats. It can be the internal representation of objects, etc. 
<p></p></li><li><b>instructions</b> One of the surprising ideas in computers is the idea that instructions can also be stored in memory. A long time ago, people thought of computers with highly specific purposes (for example, computing trajectories of missiles), and didn't think of it as general purpose. By allowing instructions to be "soft", i.e., represented just like data, it can be manipulated like data too. 
<p></p></li><li><b>garbage</b> Not every address stores meaningful data. Some of it is merely 0's and 1's without meaning. </li></ul><p>In general, certain sections of memory are reserved for data, while other sections are reserved for instructions. Nevertheless, there's no inherent information stored in the bytes that indicate it's an instruction vs. data. 
</p><p>This has lead people to say "Information = Bits + Context". That is, bits do not have any meaning, except in certain contexts. Thus, if the CPU "thinks" there is an instruction at a certain address, then it will treat the binary value at that address as an instruction, even if it's not a truly meaningful instruction (i.e., it could be a valid instruction, but not within a meaningful program). 
</p><p>Thus, the CPU distinguishes between data, instructions, and garbage by context, not by any special tagging of the bytes to indicate what is stored. This means, in general, if you could inspect the bytes in memory, it might be difficult to tell if those bytes are data or instructions, or even if you could tell it was data, it would be hard to tell what kind of data it is. </p></dd><dt></dt><h3>Load/Store: Operations with Memory </h3><dd>The CPU needs to move the bytes in memory to the CPU so they can be handled more readily. For modern RISC machines, there are two instructions to move data to and from memory: <b>load</b> and <b>store</b>. Thus, RISC machines are often said to be <i>load-store</i> architectures. This is to contrast with CISC machines which often use memory addresses as operands in instructions that are not <b>load</b> nor <b>store</b>. 
<p>To <i>load</i> bytes means to copy some bytes from memory to a register located on the CPU. This is the same as reading from memory to the CPU. 
</p><p>To <i>store</i> bytes means to copy some bytes from a register in the CPU to a memory location specified by a memory address. This is the same as writing from the CPU to memory. </p></dd><dt></dt><h3>A More Detailed Model of Memory </h3><dd>While we view memory as a large array, we need to be more specific when it comes to how the CPU interacts with memory. 
<p>In particular, we're going to describe the <i>pins</i> associated with a memory chip. Pins are used for inputs and outputs of a chip. Some pins are for inputs (receiving information from the outside world). Some are for outputs (providing information to the outside world). Some are bidirectional (they do both). 
</p><p>First, we know that the CPU needs to access memory for either load or store. To do this, it needs to provide an address. So, we're going to assume memory has 32 bits of input for an address, which we label as <b>A<sub>31..0</sub></b>. 
</p><p>In reality, there are many memory chips that are parts of memory. A large amount of memory is built from many memory chips. However, as far as the CPU is concerned, it can pretend that there is one monolithic memory chip (because of the interface memory provides). We'll do the same as well. We'll pretend there is one large 4 gigabyte memory chip. 
</p><p>Secondly, we need to tell memory whether we intend to read or write to memory. In this case, read and write are from the perspective of the CPU. Thus, to read from memory, means to get data out of the memory (so it can be sent to the CPU). This can be seen as a write from the perspective of memory. To write to memory means to get data into memory. This can be seen as a read from the perspective of memory. 
</p><p>We use the pin <b>R/\W</b> which is read as "read, not write". When <b>R/\W = 1</b>, we perform a read. When <b>R/\W = 0</b>, we perform a write. Usually, when we write something like <b>\P</b> we mean that <b>P</b> is active when 0 is input (this is also called <i>active low</i>). This is in contrast to writing it as <b>P</b> which is active when <b>P</b> is 1 (this is also called <i>active high</i>). 
</p><p>However, we don't always want to read or write. Sometimes we wish to do neither. (If we had to choose, it's better to do a read, since this does not update memory. However, reading makes the data bus unusable by other devices). 
</p><p>Thus, we have another input pin called <b>CE</b> for <i>chip enable</i>. Sometimes this pin is called <i>chip select</i>. 
</p><p>Since we do not write <b>\CE</b>, we assume <b>CE</b> is active high. That is, memory is enabled when <b>CE = 1</b>. 
</p><p>If <b>CE = 0</b>, then memory is disabled, which means memory ignores <b>R/\W</b> and performs neither a read, nor a write. 
</p><p>Finally, we need pins for the data. We assume these pins are bidirectional. They serve as input, when a write operation is being performed by the CPU (input to the memory chip, that is). They serve as output, when a read operation is being performed. They're ignored when the chip enable is not active. 
</p><p>We'll call these pins <b>D<sub>31..0</sub></b>. 
</p><p>There's one more output pin from memory called <b>ACK</b>, which is short for "acknowledgement". It's not obvious why you need to have such a pin. It's purpose is to be involved in a protocol between memory and CPU for reading from or writing to memory. </p></dd><dt></dt><h3>A Diagram of Memory </h3><dd><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Memory/mem.png" /></center><p></p><h4>Legend of Pins </h4><ol><li><b>R/\W</b> (read/not write) This is a one bit input that comes from the CPU. The CPU tells memory that it wants to perform a read by setting <b>R/\W = 1</b>. It tells memory that it wants to perform a write by setting <b>R/\W = 0</b>. However, memory only recognizes this bit when <b>CE = 1</b>. 
<p></p></li><li><b>CE</b> (chip enable) When <b>CE = 1</b>, then the value of <b>R/\W</b> is processed by memory (and a read/write is performced). If <b>CE = 0</b>, memory neither reads nor writes. <b>CE</b> is 1 bit. 
<p></p></li><li><b>ACK</b> (acknowledgement) This is normally set to 0. When a read or write is completed, <b>ACK</b> is set to 1. This wire is sent to the CPU. It is reset back to 0 when <b>CE</b> is set to 0. <b>ACK</b> is 1 bit. 
<p></p></li><li><b>A<sub>31..0</sub></b> (address bus). The CPU (or possibly another I/O device) outputs the address to read or write. 
<p></p></li><li><b>D<sub>31..0</sub></b> (data bus). If the CPU is performing a read (i.e., a <i>load</i>), then memory writes data onto the data bus at the address specified by the address bus. The CPU copies the data from the data bus to the CPU. 
<p>If the CPU is performing a write (i.e., a <i>store</i>) then it writes the data onto data bus. Memory copies the value into the memory location specified by the address on the address bus. 
</p><p>In both reads and writes, the CPU puts the address onto the address bus. </p></li></ol></dd><dt></dt><h3>A Chart Describing Memory Operations </h3><dd><center><table cellpadding="4" border="1"><tbody><tr align="middle"><td bgcolor="yellow"><b>CE</b></td><td bgcolor="pink"><b>R/\W</b></td><td bgcolor="#aaffaa"><b>Operation</b></td></tr><tr align="middle"><td><b>0</b></td><td><b>0</b></td><td>No read nor write (since <b>CE</b> is not active) </td></tr><tr align="middle"><td><b>0</b></td><td><b>1</b></td><td>No read nor write (since <b>CE</b> is not active) </td></tr><tr align="middle"><td><b>1</b></td><td><b>0</b></td><td>Read data from memory (load) </td></tr><tr align="middle"><td><b>1</b></td><td><b>1</b></td><td>Write data to memory (store) </td></tr></tbody></table></center></dd><dt></dt><h3>How It's Hooked Up </h3><dd>As you can see, memory has pins that serve as inputs, outputs, and somtimes both. These pins are connected to wires and busses, which are also connected to the CPU. 
<p>As you might guess, the address pins <b>A<sub>31..0</sub></b> are hooked up the address bus (see the diagram of the computer at the top of this page). 
</p><p>The data pins <b>D<sub>31..0</sub></b> are hooked up to the data bus (see the diagram of the computer at the top of this page). 
</p><p>What about <b>R/\W</b> and <b>CE</b>? These signals come directly from the CPU. So, the CPU isn't just hooked up to the data bus and the address bus. Assume there's a control bus where signals are sent between CPU and memory. There's three wires on this bus between CPU and memory: <b>R/\W</b> and <b>CE</b> go from CPU to memory. <b>ACK</b> goes from the memory to the CPU. </p></dd><dt></dt><h3>How Fast Is Memory? </h3><dd>It might be strange to talk about the "speed" of memory. After all, is memory physically moving around? Of course not! Well, maybe some electrons are moving around. 
<p>Speed refers to the amount of time it takes to perform a read or write. Compared to performing those same operations on a register, reads and writes to memory are really, really, really slow. (Even slower still is accessing disk, which is incredibly slow). </p></dd><dt></dt><h3>Continuous Flow </h3><dd>Recall that information in hardware is sent along wires (or busses), and that these are continuously sending out 0's and 1's (and possibly Z, which means no output, or garbage). 
<p>For example, the CPU needs to keep asserting the value <b>CE = 1</b> until a read or write operation is completed. It must also continue to assert <b>R/\W</b> as well. The CPU must also assert the address to the address bus until the operation is complete. 
</p><p>If the CPU is doing a write, then it must assert the data on the data bus, until memory sends back <b>ACK = 1</b>. If the CPU is doing a read, memory must assert the data onto the data bus until <b>CE</b> is set to 0. 
</p><p>The two biggest hurdles to understanding hardware is that values must be asserted onto a wire or bus until the operation is complete (it's not like making a function call, where you have a discrete computation). The second concept is that "everything" in hardware can be performed in parallel. Programming teaches us to think sequentially, but hardware is usually done in parallel. 
</p><p>Think of hardware like a city, where there are many businesses carrying out their activities in parallel. Occasionally, for some businesses (like building a house), you may need to wait for someone else to do their job before you can do yours. 
</p><p>Similarly, in hardware, there are many devices doing things in parallel. Of course, they are all working together to run assembly language instructions. </p></dd><dt></dt><h3>Summary </h3><dd>We treat memory as a black box, which contains an array of values. Memory has some input pins (<b>A<sub>31..0</sub></b>, <b>CE</b>, <b>R/\W</b>), output pins (<b>ACK</b>) and bidirectional pins (<b>D<sub>31..0</sub></b>). 
<p>Think of this as an interface (just like a Java class interface). This is how the CPU views memory. The actual implementation may involve many memory chips hooked up in such a way to give the illusion that there is one monolithic chip. This goes to show you that hardware has abstractions, just as software does. 
</p><p>The amount of memory in the CPU is very limited (roughly 128 bytes, due to 32 32-bit registers), so most information is stored in memory. Memory stores data, instructions, and garbage. 
</p><p>While certain regions of memory are reserved for code and other regions for data, the CPU basically distinguishes between code and data by context. This means there is no "tagging" or "labelling" of bits in memory. Thus, if you could inspect the binary values in memory, you would (in general) be unable to tell what the binary values stood for. The CPU generally assumes certain addresses contain data and certain addresses contain code. If these assumptions are incorrect, errors occur. 
</p><p>The CPU accesses information from memory sending addresses and control signals to memory. It may either send or receive data depending on whether a read or write operation is being performed. 
</p><p>Accessing memory is very slow compared to accessing registers which reside directly on the CPU. Registers can be accessed in about 0.25 ns while memory can be accessed in about 100 ns. Thus memory is about 400 times as slow as registers. Despite the speed (or lack thereof) of memory, the CPU must access memory because the CPU has very little memory of its own. </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 16:59 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 6-What's an Instruction?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17924.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 07:42:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17924.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17924.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17924.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17924.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Background </h3><dd>You should know what UB and 2C representation is. You should also know about sign-extension. 
</dd><dt></dt><h3>ISA </h3><dd>When you started learning how to program, you were told that your program had to be compiled. That is, it had to be converted from a high-level language into a low-level language. For C and C++, the low-level language is basically machine code. 
<p>An ISA defines the machine and assembly code used by a CPU. 
</p><p>ISA stands for "Instruction Set Architecture". Effectively, the ISA is the programmer's view of the computer. 
</p><p>An ISA consists of: 
</p><p></p><ul type="disc"><li><b>The instruction set</b> This is the set of instructions supported. This is the part that's usually called the assembly language. 
</li><li><b>The register set</b> This is the set of registers you can use. (There are other <i>hidden</i> registers which you can't use directly. They are used indirectly, however). 
</li><li><b>The address space</b> This is the set of memory addresses that can be used by your program. </li></ul><p>The ISA is basically a hardware specification. It's the view of the hardware as seen by an assembly language programmer. 
</p><p>The ISP (instruction set processor) is an <i>implementation</i> of the ISA. There may be many implementations for a given ISA. For example, IA32 is the instruction set architecture for x86 processors. Intel has the Pentium and Celeron lines of CPUs that implement this ISA. AMD also has its own CPUs that implement the ISA. Each implementation is different, but they all run code written in IA32. </p></dd><dt></dt><h3>Why You Need to Know About Instructions </h3><dd>We study instruction sets because that's what CPUs process. They run one instruction after another. In order to understand how a computer works, you need to know what instructions are, and more importantly, how to write them. 
<p>There are two ways to write instructions. Either you can write them in assembly language, which is human-readable. Or you can write them in machine code, which is basically, 0's and 1's. CPUs process machine code, but humans usually program in assembly language. 
</p><p>You need to know both, in order to understand how a CPU works. </p></dd><dt></dt><h3>The MIPS ISA </h3><dd>There are two ways to write instructions. You can write it in assembly language, which is human readable, or you can write it in machine code, which is 0's and 1's. For MIPS32, each machine code instruction is a 32-bit bitstring. 
<p>The "32" in MIPS32 refers to the size of the registers (i.e., how many bits each register holds) and to the number of bits used in an address. There is also a MIPS64, which has 64 bit addresses and 64 bit registers. 
</p><p>The MIPS32 architecture contains 32 general purpose int registers. The registers are named <b>$r0, $r1, ..., $r31</b>. Each register can store 32 bits. Most of the times the registers either store signed or unsigned ints. However, sometimes they store addresses, and occasionally ASCII characters, etc. 
</p><p>MIPS also has 32 floating point registers, but we won't worry about them too much. 
</p><p>Unlike programming languages where you can declare as many variables as you want, you can't create any more registers. The number of registers doesn't change. 
</p><p>MIPS32 allows you to access data in memory using 32 bit addresses. In principle, you can access up to <b>2<sup>32</sup></b> different addresses, using 32 bits. In practice, some of those addresses may be invalid. For example, the CPU may simply not have that much memory (<b>2<sup>32</sup></b> addresses is 4 GB). Thus, you might be able to generate the 32-bit address, but there may be nothing stored at that address (an error usually occurs when you access an invalid address). 
</p><p>In MIPS, nearly all registers are general purpose. You can classify ISAs into those that use general purpose registers (i.e., instructions can refer to any register---all registers perform the same operations) or special purpose (certain instructions can only be used on specific, i.e., not all, registers). 
</p><p>However, there is at least one exception. <b>$r0</b> is not general purpose. It is hardwired to 0. No matter what you do to this register, it always has a value of 0. You might wonder why such a register is needed in MIPS. 
</p><p>The designers of MIPS used benchmarks (programs used to determine the performance of a CPU), which convinced them that having a register hardwired to 0 would improve the performance (speed) of the CPU as opposed to not having it. Not everyone agrees a register hardwired to 0 is essential, so not all ISAs have a zero register. </p></dd><dt></dt><h3>Assembly vs. Machine Code </h3><dd>CPUs process binary bitstrings. These bitstrings are really instructions, encoded in 0's and 1's. When people began to write programs for computers, they wrote it in binary. That is, programs were written in 0's and 1's. The code probably looked something like this: 
<p><font size="+2"><pre>0000 0000 0101 1000 0000 0000 0101 1000
1010 1101 0000 1011 1000 1100 1001 0110
</pre></font></p><p>This is called <i>machine code</i>. 
</p><p>As you might imagine, machine code was difficult to read and difficult to debug. The amount of time wasted trying to find whether you had accidentally written a 0 instead of a 1, lead to the invention of assembly language. 
</p><p>Assembly language is a somewhat more human-readable version of machine code. For example, assembly code might look something like: 
</p><p><font size="+2"><pre>add   $r2, $r3, $r4
addi  $r2, $r3, -10
</pre></font></p><p>While you may not understand the code above, you've certainly got a much better chance of figuring it out than the machine code equivalent. Each line of assembly code contains an instruction. Each instruction tells the computer one small task to accomplish. Instructions are the building blocks of programs. 
</p><p>CPUs can't handle assembly code directly. Instead, assembly code is translated to machine code. If this sounds like compiling, that's because it basically is comiling. However, people usually call the process of translating assembly to machine code <i>assembling</i>, instead of compiling. 
</p><p>You'll write code in assembly, and learn how to translate some instructions from assembly to machine code. It's very important that you understand the machine code, because that's what the CPU processes. Furthemore, by studying machine code, you get to see how information is encoded into 0's and 1's, and you get to see how the CPU uses these binary values to execute the instruction in hardware. </p></dd><dt></dt><h3>Encoding Registers </h3><dd>In the previous set of notes, we talked about how many bits you needed to create <b>N</b> different labels. We assume each label has <b>k</b> bits long. 
<p>You need <b>k = ceil( lg N )</b> bits to uniquely label <b>N</b> items. 
</p><p>MIPS32 has 32 integer registers. We want to label each register by a number, so instructions can refer to registers by number. Since MIPS has 32 registers, you need <b>ceil( lg 32 ) = 5</b> bits. 
</p><p>If we think of the 5 bit numbers as unsigned binary numbers, then the registers are numbered from 0 up to 31, inclusive. In fact, that's exactly how MIPS numbers its registers. Registers are numbered from <b>$r0</b> up to <b>$r31</b>. The binary equivalent are numbered from <b>00000</b> to <b>11111</b>. 
</p><p>In assembly language, you'd write <b>$r6</b>. In machine code, you'd write the same register as: <b>00110</b>. In assembly language, you'd write <b>$r30</b>. In machine code, you'd write <b>11110</b>. 
</p><p>This is important because we're going to use register encoding in the machine language instructions for MIPS. Recall that machine code is a 32-bit bitstring. When we refer to registers within the instruction, it's going to be using the 5 bit binary numbers written in UB (unsigned binary). </p></dd><dt></dt><h3>What is an instruction? </h3><dd>An assembly language instruction is basically a function call. Like C functions, assembly language instructions have a fixed number of arguments. You can't add or remove the number of arguments. 
<p>Like C functions, arguments of assembly language instructions have type. Or at least, something that resembles type. Basically, there are 4 kinds of "types" for MIPS. 
</p><p></p><ul type="disc"><li><b>Registers</b> (<b>$r0, $r1,..., $r31</b>) 
<p></p></li><li><b>Immediates</b> Constants, such as, <b>10</b>, <b>-20</b>, etc. Sometimes written in hexadecimal, e.g., <b>0x3a</b>. 
<p></p></li><li><b>Register Offset</b> This is a constant and a register, written as <b>-10($r3)</b> or <b>214($r4)</b>. That is, you write the immediate (constant) value, then a left parenthesis, then a register, then a right parenthesis. 
<p>The computation is performed by adding the contents of the register to the offset, usually resulting in a 32 bit address. Thus, <b>-10($r3)</b> is -10 added to the contents of register 3. This result is "temporary" and register 3 is not modified (just like <b>x + y</b> in a programming language merely adds <b>x</b> to <b>y</b>, but the sum does not change <b>x</b> or <b>y</b></p><p></p></li><li><b>Labels</b> There are identifiers to locations in memory. Generally, you write labels in uppercase letters and underscores, such as <b>FOR_LOOP</b>. </li></ul><p>For the most part, we'll only consider registers and immediate values. 
</p><p>Let's consider two examples of instructions and their operands: 
</p><p></p><ul type="disc"><li><b>add $r2, $r3, $r4</b> This instruction adds the contents of register 3 and register 4, and places the result in register. It's basically <b>R[2] = R[3] + R[4]</b>, if you pretend that the registers form an array. 
<p></p></li><li><b>addi $r2, $r3, -10</b> This instruction adds the contents of register 3 to -10 and places the result in register 2. It's basically <b>R[2] = R[3] - 10</b></li></ul><p>The first instruction is an <b>add</b> instruction. <b>add</b> requires exactly 3 operands (arguments). Each operand <i>must</i> be a valid register. The operand <i>can not</i> be anything besides a register. In particular, you can not create expressions such as: <b><font size="+2"><pre><font color="red"># WRONG! Operands can't be expressions</font>
add $r2, $r3, (add $r4, $r5, $r6) 
</pre></font></b>The second instruction is an <b>addi</b> instruction. <b>addi</b> must also have three operands. The first two operands must be registers, while the third one must be an integer between <b>-2<sup>15</sup></b> to <b>2<sup>15</sup> - 1</b>, inclusive. 
</p><p>There is a reason for this restriction in value, which we will discuss momentarily. 
</p><p>Unlike higher level programming languages, you can't create new registers. You're forced to use the ones available. You can't create new instructions either. You must use the ones provided in the instruction set. </p></dd><dt></dt><h3>Machine Code </h3><dd>A machine language instruction ususally consists of: 
<p></p><ul type="disc"><li><b>opcode</b> This is a binary representation of the instruction. For example, an add instruction has an opcode of <b>000 000</b>. 
</li><li><b>operands</b> Operands means the same thing as arguments. It's older terminology usually associated with assembly/machine code instructions. </li></ul><p>MIPS divides instructions into three formats. Instructions are either <b>R-type</b> (register type), <b>I-type</b> (immediate type), or <b>J-type</b> (jump type). The types refer to the format, <i>not</i> to its purpose. (For example, branch instructions are <b>I-type</b>, because of its format, even if it would seem like it should be <b>J-type</b>). 
</p><p>Here are the layouts of the three kinds of instructions. 
</p><h3>R-type Instruction </h3><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="pink"><b>Opcode</b></td><td bgcolor="#aaffaa"><b>Register s</b></td><td bgcolor="#ffaaaa"><b>Register t</b></td><td bgcolor="yellow"><b>Register d</b></td><td bgcolor="orange"><b>Shift Amt</b></td><td bgcolor="cyan"><b>Function</b></td></tr><tr align="middle"><td><b>B<sub>31..26</sub></b></td><td><b>B<sub>25..21</sub></b></td><td><b>B<sub>20..16</sub></b></td><td><b>B<sub>15..11</sub></b></td><td><b>B<sub>11..6</sub></b></td><td><b>B<sub>5..0</sub></b></td></tr><tr align="middle"><td><font size="+2"><b><tt>ooo ooo</tt></b></font></td><td><font size="+2"><b><tt>sssss</tt></b></font></td><td><font size="+2"><b><tt>ttttt</tt></b></font></td><td><font size="+2"><b><tt>ddddd</tt></b></font></td><td><font size="+2"><b><tt>aaaaa</tt></b></font></td><td><font size="+2"><b><tt>ffffff</tt></b></font></td></tr></tbody></table></center><p></p><ul type="disc"><li>R-type instructions are short for "register type" instructions. 
</li><li>Bits <b>B<sub>31..26</sub></b> are used for the opcode. For R-type instructions, the opcode is almost always <b>000 000</b>. Normally, this makes no sense, because every instruction should have a unique opcode. However, bits <b>B<sub>5..0</sub></b> (the function part) uses 6 bits to specify the instruction. Only R-type instruction uses a function. 
</li><li>Bits <b>B<sub>25..21</sub></b> specify a 5-bit UB encoding for the first source register. 
</li><li>Bits <b>B<sub>20..16</sub></b> specify a 5-bit UB encoding for the second source register. 
</li><li>Bits <b>B<sub>15..11</sub></b> specify a 5-bit UB encoding for the destination register. This specifies which register stores the result of the operation. 
</li><li>Bits <b>B<sub>11..6</sub></b> specify the shift amount. This is usually <b>00000</b>, except for shift instructions. 
</li><li>Bits <b>B<sub>5..0</sub></b> specify a 6-bit function. Each R-type instruction has a unique 6 bit value. For example, <b>add</b> has a 6-bit value that's different from <b>sub</b>. <b>add</b> and <b>sub</b> are two different instructions. </li></ul><h3>I-type Instruction </h3><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="pink"><b>Opcode</b></td><td bgcolor="#aaffaa"><b>Register s</b></td><td bgcolor="#ffaaaa"><b>Register t</b></td><td bgcolor="cyan"><b>Immediate</b></td></tr><tr align="middle"><td><b>B<sub>31..26</sub></b></td><td><b>B<sub>25..21</sub></b></td><td><b>B<sub>20..16</sub></b></td><td><b>B<sub>15..0</sub></b></td></tr><tr align="middle"><td><font size="+2"><b><tt>ooo ooo</tt></b></font></td><td><font size="+2"><b><tt>sssss</tt></b></font></td><td><font size="+2"><b><tt>ttttt</tt></b></font></td><td><font size="+2"><b><tt>iiii iiii iiii iiii</tt></b></font></td></tr></tbody></table></center><p></p><ul type="disc"><li>I-type instructions are short for "immediate type" instructions. 
</li><li>Bits <b>B<sub>31..26</sub></b> are used for the opcode. Unlike R-type instructions, the 6-bit value is NOT <b>000 000</b>. There is no function code for I-type instructions. 
</li><li>Bits <b>B<sub>25..21</sub></b> specify a 5-bit UB encoding for the source register. 
</li><li>Bits <b>B<sub>20..16</sub></b> specify a 5-bit UB encoding for the destination register. Although this is called register <b>t</b>, instead of register <b>d</b>, it is treated as the destination register for <b>I-type</b> instructions. 
</li><li>Bits <b>B<sub>15..0</sub></b> is the 16-bit immediate value. This may be a 16-bit UB number or a 16-bit 2C number. Notice that the immediate value is encoded directly into the instruction. </li></ul><h3>J-type Instruction </h3><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="pink"><b>Opcode</b></td><td bgcolor="#aaffaa"><b>Target</b></td></tr><tr align="middle"><td><b>B<sub>31..26</sub></b></td><td><b>B<sub>25..0</sub></b></td></tr><tr></tr><tr align="middle"><td><font size="+2"><b><tt>ooo ooo</tt></b></font></td><td><font size="+2"><b><tt>tt tttt tttt tttt tttt tttt tttt</tt></b></font></td></tr></tbody></table></center><p></p><ul type="disc"><li>J-type instructions are short for "jump type" instructions. 
</li><li>Bits <b>B<sub>31..26</sub></b> are used for the opcode. Unlike R-type instructions, the 6-bit value is NOT <b>000 000</b>. There is no function code for J-type instructions. 
</li><li>Bits <b>B<sub>25..0</sub></b> are used for the offset. This is usually used to generate an address. </li></ul><p>Notice that the J-type instruction has no source or destination registers. </p></dd><dt></dt><h3>add, an R-type instruction </h3><dd>The general format for an <b>add</b> instruction is: <b><font size="+2"><pre>add $rd, $rs, $rt
</pre></font></b><b>$rd</b>, <b>$rs</b>, and <b>$rt</b> are <i>not</i> real registers. They are merely place holders. For example, if we write <b>add $r2, $r3, $r4</b>, then <i>for this particular example</i>, <b>$rd = $r2</b>, <b>$rs = $r3</b>, and <b>$rt = $r4</b>. 
<p>In assembly language, the instructions are written with the destination register (i.e. <b>register d</b>), then the first source register, (i.e. <b>register s</b>) then the second source register (i.e. <b>register t</b>). 
</p><p><b>Note:</b> This is NOT the same order as it is written in machine code. In assembly, it's destination, source 1, source 2. In MIPS machine code, it's written source 1, source 2, destination. 
</p><p>Don't ask me why the MIPS folks did it that way. They just did. 
</p><p>Let's translate the following instruction into MIPS assembly. <b><font size="+2"><pre>add $r2, $r3, $r4
</pre></font></b></p><p>For <b>add</b>, the opcode is <b>000 000</b>. The function code is <b>100 000</b>. Since the shift amount isn't used, it's set to <b>00000</b>. 
</p><p>We encode <b>$r2</b> as <b>00010</b>, <b>$r3</b> as <b>00011</b>, and <b>$r4</b> as <b>00100</b>. 
</p><p>This is how the machine code equivalent looks: 
</p><p></p><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="pink"><b>Opcode</b></td><td bgcolor="#aaffaa"><b>Register s</b></td><td bgcolor="#ffaaaa"><b>Register t</b></td><td bgcolor="yellow"><b>Register d</b></td><td bgcolor="orange"><b>Shift Amt</b></td><td bgcolor="cyan"><b>Function</b></td></tr><tr align="middle"><td><b>B<sub>31..26</sub></b></td><td><b>B<sub>25..21</sub></b></td><td><b>B<sub>20..16</sub></b></td><td><b>B<sub>15..11</sub></b></td><td><b>B<sub>11..6</sub></b></td><td><b>B<sub>5..0</sub></b></td></tr><tr align="middle"><td>  </td><td bgcolor="yellow"><b>$r3</b></td><td bgcolor="yellow"><b>$r4</b></td><td bgcolor="yellow"><b>$r2</b></td><td>  </td><td>  </td></tr><tr align="middle"><td><font size="+2"><b><tt>000 000</tt></b></font></td><td><font size="+2"><b><tt>00011</tt></b></font></td><td><font size="+2"><b><tt>00100</tt></b></font></td><td><font size="+2"><b><tt>00010</tt></b></font></td><td><font size="+2"><b><tt>00000</tt></b></font></td><td><font size="+2"><b><tt>100 000</tt></b></font></td></tr></tbody></table></center><p>Again, notice that bits <b>B<sub>25..21</sub></b> is source 1 (i.e., <b>$r3</b>), then <b>B<sub>20..16</sub></b> is source 2 (i.e., <b>$r4</b>), then <b>B<sub>15..11</sub></b> is the destination register (i.e., <b>$r2</b>). 
</p><p>It's important that you learn how to translate a few instructions, because the CPU manipulates the binary version of this, <i>not</i> the assembly version. In particular, pay attention to how the registers are encoded, and just as importantly, which bits refer to which registers. </p></dd><dt></dt><h3>addi, an I-type instruction </h3><dd><b>addi</b> stands for <i>add immediate</i>. It's an I-type instruction. 
<p>The general format for an <b>addi</b> instruction is: <b><font size="+2"><pre>addi $rt, $rs, IMMED
</pre></font></b>For I-type instructions, <b>$rt</b> is the destination register (not <b>$rs</b>). <b>$rs</b> is still the first source register. For <b>addi</b>, the immediate value is written in base 10 (or possibly, hexadecimal), but it eventually gets translated to 2C. 
</p><p>Let's look at a specific example. <b><font size="+2"><pre>addi $r3, $r10, -3
</pre></font></b></p><p>This instruction adds the contents of register 10, to the value -3, and stores the result in register 3. 
</p><p>The opcode for <b>addi</b> is <b>001 000</b>. In 2C, you write <b>-3<sub>ten</sub></b> as <b>1111 1111 1111 1101</b>. 
</p><p>This is how the instruction is encoded. 
</p><p></p><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="pink"><b>Opcode</b></td><td bgcolor="#aaffaa"><b>Register s</b></td><td bgcolor="#ffaaaa"><b>Register t</b></td><td bgcolor="cyan"><b>Immediate</b></td></tr><tr align="middle"><td><b>B<sub>31..26</sub></b></td><td><b>B<sub>25..21</sub></b></td><td><b>B<sub>20..16</sub></b></td><td><b>B<sub>15..0</sub></b></td></tr><tr align="middle"><td>  </td><td bgcolor="yellow"><b>$r10</b></td><td bgcolor="yellow"><b>$r3</b></td><td bgcolor="lightblue"><b>-10</b>, represented in 2C </td></tr><tr align="middle"><td><font size="+2"><b><tt>001 000</tt></b></font></td><td><font size="+2"><b><tt>01010</tt></b></font></td><td><font size="+2"><b><tt>00011</tt></b></font></td><td><font size="+2"><b><tt>1111 1111 1111 1101</tt></b></font></td></tr></tbody></table></center><p>Again, notice that in the assembly code <b>$r3</b> (i.e., the destination register) appears first, while in the machine code <b>$r3</b> appears second. Also, notice that the immediate value is written in 16 bits, two's complement. 
</p><p>Now that you see why it's written in 16 bits, 2C, you see why the immediate value can only be between <b>-2<sup>-15</sup></b> through <b>2<sup>15</sup> - 1</b>. This is the range of valid values for 16 bit 2C. 
</p><p>The assembler must translate base 10 representation to 2C representation when translating <b>addi</b> from assembly to machine code. 
</p><p>Some instructions encode the immediate in 2C, while other instructions encode it in UB. 
</p><p></p></dd><dt></dt><h3>Summary </h3><dd>This section on instructions is not trying to teach you how to program in MIPS assembly. Instead, it's to briefly introduce you to what an instruction is, and how it is encoded. 
<p>While it's useful to know how to program in MIPS assembly, it's isn't essential to understand how a CPU works. To understand how a CPU works, at least, initially, all you need to know is what an instruction looks like in binary, and what that individual instruction is supposed to do. </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 15:42 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 4-What's a Register?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17919.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 06:39:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17919.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17919.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17919.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17919.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Registers </h3><dd>A basic CPU contains registers, an ALU (to be explained later), busses, and some combinational logic devices like multiplexers (to be explained later). 
<p>Registers are basically very fast memory. However, CPUs can only hold a limited number of registers. There are several reasons for it, ranging from how fast a CPU can be with too many registers, to the more important issue of how to specify which register you want to work with. </p><p>In the CPU we're building, we'll assume each register can store 32 bits. However, in our examples, we'll use 4 bits, only because it's easier to draw with 4 bits than 32. </p><p>Unlike programming languages, registers don't really have a type. Registers can store ASCII characters, memory addresses, signed integers, unsigned integers, etc. A register stores a 32 bit bitstring, and what that bitstring represents depends on the assembly language instructions that manipulate it. </p><p>One reason we talked about a clock is because a register is a clocked device. We'll explain more in the next section. </p></dd><dt></dt><h3>Parallel Load Register </h3><dd>A 4-bit parallel load register is a device with 4 bits of data inputs, one control bit, and 4 bits of output. 
<p>Here's a diagram of a parallel load register. </p><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Register/register.png" /></center><p>The register is the outer box. It has four bits of data inputs labelled <b>b<sub>3..0</sub></b>. It has four bits of output labelled <b>z<sub>3..0</sub></b>. It has a single control bit telling the parallel load register what to do. It has a clock input that tells it when to do it. </p><p>Inside the parallel load register, we see what appears to be an array. However, unlike the arrays you see in a programming language, the array is numbered from right to left. The rightmost element is indexed 0, while the leftmost box is indexed 3. </p><p>In reality, registers don't store "arrays", but to make the explanation easier to understand, just think of it as an array. </p><p>The following is a chart indicating how to use the control bit (labeled as <b>c</b>) to tell the parallel load register what to do. </p><p></p><center><table cellpadding="5" border="1"><tbody><tr align="middle"><td bgcolor="yellow"><b>Clock</b></td><td bgcolor="pink"><b>Control</b></td><td bgcolor="#aaffaa"><b>Operation</b></td></tr><tr align="middle"><td><b>Pos. Edge</b></td><td><b>c = 1</b></td><td><b>Parallel Load</b> (i.e., <b>z<sub>3..0</sub> = b<sub>3..0</sub></b>) </td></tr><tr align="middle"><td><b>Pos. Edge</b></td><td><b>c = 0</b></td><td><b>Hold</b> (i.e., <b>z<sub>3..0</sub></b> unchanged) </td></tr><tr align="middle"><td><font color="red"><b>NOT Pos. Edge</b></font></td><td><font color="red"><b>c = don't care</b></font></td><td><font color="red"><b>Hold</b> (i.e., <b>z<sub>3..0</sub></b> unchanged) </font></td></tr></tbody></table></center><p>A parallel load registers has two operations. It can <b>hold</b>. It can <b>parallel load</b>. </p><p></p><ul type="disc"><li><b>hold</b> The register keeps the same value in the array. It ignores the input values <b>b<sub>3..0</sub></b>. 
</li><li><b>parallel load</b> The register reads in the input values, <b>b<sub>3..0</sub></b>, and overwrites the values in the array. Thus, if <b>b<sub>3..0</sub> = 0000</b> and the current value in the register is <b>z<sub>3..0</sub> = 0110</b>, then parallel loading the input would cause the register's content to become <b>0110</b>, and the old values of the register would disappear. </li></ul><p>The reason it is called a <i>parallel load</i> is because the bits are loaded in parallel. The other way to load bits is one at a time, i.e., sequentially. This is what happens when you copy an array. It is copied one element at a time. </p><p>The control bit, <b>c</b>, is used to tell the register whether to hold or to parallel load. If <b>c = 0</b>, the register holds. If the <b>c = 1</b>, the register parallel loads. <i>However, this is only done when the clock signal is at a positive edge</i>. </p><p>If you look at the third row of the chart above, the register <i>also</i> holds its value. When the clock signal is not at a positive edge, the register's value remains the same. It is <i>holding</i> its value. </p></dd><dt></dt><h3>Remember, It's Continuous </h3><dd>If you think like a programmer, you think discretely. You think of arguments being passed. 
<p>However, when you deal with hardware, you need to think continously (and discretely too). In general, the register is always receiving some value for <b>c</b>. Again, think of a pipe being sent into the register. </p><p>There's always some red or green soda flowing in. That is, there's always a 0 or 1 being sent to the register using the <b>c</b> control input. </p><p>Most of the time, this control input is being ignored. However, when a positive edge occurs, the control input is "read" by the register (to determine which operation to perform), and either a parallel load or hold occurs. </p></dd><dt></dt><h3>Why Hold? </h3><dd>You might wonder why registers have <i>two</i> operations. In particular, you might wonder why it's necessary to have a "hold" operation. After all, most of the time, the register is holding. Why wouldn't we want to parallel load at each clock edge? 
<p>Think of a register as a variable in a programming language. Do we assign to a variable all the time? No. We just assign to the variable when it needs to be assigned. Otherwise, variables would be changing all the time. </p><p>We don't always want a register to read the value all the time for the same reason we don't always want a variable to update all the time. Sometimes, we just want to keep the value of the register unchanged. </p><p>Here's another analogy. Many years ago, there were milk men who would deliver bottles (yes!) of milk to your house. They would come to your house once a day. However, depending on how fast you drink milk, or whether you're on vacation, you might not want to have milk delivered to you each day. </p><p>A system can be worked out between you and the milkman. If you've drunk all the milk, then you can put the empty bottle outside your door. The milkman sees an empty bottle, picks it up, and puts down a new bottle of milk. </p><p>On the other hand, if you haven't completed the milk, you don't leave the bottle outside. When the milkman drops by, he doesn't see a bottle of milk outside. So, he doesn't drop a new bottle of milk. </p><p>The milkman comes by once a day, which is similar to a positive edge occuring once a period. The milkman has two choices. Drop a new bottle of milk, or don't. If you didn't have this policy, then the milkman would keep dropping off more and more bottles of milk, and it would all go bad. So, there's some justification for not wanting milk to be dropped off each day. </p><p>What if you wanted milk to be delievered more often? Like twice a day, instead of once a day? This is analogous to speeding up the clock, and usually we don't have too much control over how fast the clock runs. Generally, you have the clock set at one rate, and that's that. </p></dd><dt></dt><h3>It's Always Outputting a Value! </h3><dd>Whatever value is in the register, it's continously being output to the outside world. Thus, once you load a parallel load register, <b>z<sub>3..0</sub></b> is set to the value just loaded, and this is sent continuously. 
<p>You just have to get used to the idea that a register is always outputting a value. The reason this doesn't cause a problem is because the rest of the CPU doesn't have to actually <i>read</i> the value from the register. Other devices can selectively ignore or read the values of the registers at selected times. </p></dd><dt></dt><h3>Why Use a Clock? </h3><dd>Why does a register need a clock? Why don't we just update the register whenever we feel like it? The main reason has to do with what registers are used for. 
<p>A register outputs a value. This value is needed by other devices in the CPU. For example, we may want to add the value of this register to the value of another register. A device called the ALU can perform this addition. </p><p>However, this addition isn't infinitely fast. Even though it's quick, it's not instantaneous. We must wait for the computation to complete. At that point, the result of the computation can be stored. This result is typically store in a register, possibly the same register that produced the value! </p><p>So, the clock is primarily used to allow the devices that need to perform computations the time it needs to do so, before updating the registers. </p></dd><dt></dt><h3>How Does a Register Compare to Memory? </h3><dd>Modern day PCs have clock rates around 3 GHz. This is the rate of the clock on the CPU. In principle, the CPU can execute one instruction per clock cycle. In reality, this happens only if the data is in the registers already. 
<p>If you need to access memory (and you'll need to do this), you'll find memory is much, much, much slower to access than registers. Memory is perhaps 400 times as slow to access than registers. </p><p>To give you an idea of how much slower that is, suppose someone tells you they are going to come back in a minute. If they come back 400 times as slow, it will take them nearly 7 hours to return. </p><p>Clearly, you want to use registers when you can, because they are much faster than memory. </p><p>However, there is a problem. CPUs can only hold a limited number of registers. For the CPU we're going to consider, we have 32 32-bit registers. That's 128 bytes. </p><p>Typical RAMs on a PC have somewhere between 128 MB up to 1 G. This is at least 100,000 times more memory than registers. However, all that memory comes at a price. It's slow to access. </p><p>This is one of the facts about memory. The faster you want memory, the more it costs, and the less of it you can have. To think about why this might occur, let's use an analogy. Think of a city. Suppose it has 100 streets (with traffic lights) going north-south, and 100 streets going east-west. Imagine how long it might take to travel from one corner to the other. </p><p>Now imagine that you only have two streets going north-south, and two streets going east-west. It's much faster to travel in this small town, because there are far fewer streets, which you can place quite close together. </p><p>Similarly, the more registers you have, the more space it takes up on the CPU, and the more time it takes to access them merely because of the physical space it takes up. When you're trying to run a CPU as fast as possible, these things become important. </p></dd><dt></dt><h3>Summary </h3><dd>A parallel load register is a sequential device. This means, it uses a clock. Specifically, a parallel load register can only change its value when the clock signal is at a positive edge. When the clock signal is not at a positive edge, the register holds its value. 
<p>You can tell a register whether to parallel load or to hold a value by setting the value of <b>c</b> the control bit to 1 or 0, respectively. </p><p>However, this bit is only <i>read</i> at the positive clock edge. If you do not have the value of <b>c</b> set to the value you want <i>when the positive edge occurs</i></p><p>(Actually you need to have the value a short time before the edge occurs, and this value must persis to a short time after the edge occurs. The actual amount of time needed depends on the register itself, and is usually part of the technical specifications for the register) </p><p></p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 14:39 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 0-Road Map</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17918.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 06:28:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17918.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17918.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17918.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17918.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17918.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Introduction </h3><dd>The goal of any computer organization course, in my mind, is to give you the understanding of how a computer works. 
<p>In particular, I want to show you how to <i>build</i> a computer. This isn't a real computer, but it's not exactly fake either. A real computer requires many features to make it run fast, to interact with the keyboard, the mouse, the Internet, and so forth. All of those peripherals are very important when it comes to using a computer, and yet, they are really only secondary when it comes to understanding how a computer fundamentally works. </p><p>The computer we'll build is not one you can buy from a store, or from someplace online. You'll never play a game, or watch a video, or write and compile a program on this computer. </p><p>The purpose is to "build" a very rudimentary computer, and to make you believe that this computer could possibly work. Many details are left out. For example, we don't worry about very low level details. Silicon and semiconductor physics are not the point of this exercise. </p><p>We'll work at a more abstract level, concerning ourselves with registers, wires, combinational and sequential logic devices. While these may not make any sense to you know, they should become clearer later on. </p><p>We're not going to worry about how to make a computer run fast either. So our system doesn't include any caches, or pipelines. Nevertheless, by understanding the computer we build, you should have enough understanding to see how a more efficient computer can be built. </p><p>Our goal is to build a CPU that can run a small subset MIPS32 ISA. Why MIPS32? Of all ISAs, MIPS32 is very simple. Simple doesn't mean bad. In fact, simple, in this case, means it can be efficient. It's also great for instruction purposes because it's easier to understand than IA32 (the instruction set for x86). </p><p>We pick one ISA because this makes life simple. I could talk about half a dozen different ISAs, but that's like discussing half a dozen different programming languages. In the end, you know 6 programming languages badly, instead of one programming language well. By concetrating on one example, you learn how it works, and then you have something to compare it to when you learn other ISAs. </p></dd><dt></dt><h3>What is a Computer? </h3><dd>For us, a computer is going to consist of two devices: a CPU (central processing unit) and memory. These two devices are connected by a bus. 
<p>The CPU consists of several parts. </p><ul type="disc"><li><b>registers</b><p>Registers are very fast memory on the CPU. The CPU we're considering consists of 32 32-bit registers. We'll label them $r0 through $r31. </p></li><li><b>ALU</b></li></ul></dd><dt></dt><h3>What Does a Computer Do? </h3><dd>A computer's purpose is to run programs. A program is a large number of machine code instructions (written in binary). 
<p>Instructions are part of an ISA (instruction set architecture). An ISA tells you a valid set of instructions. The actual CPU runs those instructions. Think of an ISA as a kind of specification and the actual CPU as the implementation of the specifications. </p><p>The individual steps for running a single instructions is: </p><ul type="disc"><li><b>Fetch an instrution</b><p>We assume all programs are stored in memory. We get an instruction, one at a time, and copy it from memory to the CPU. This instruction is copied to a special register called the <i>instruction register</i>, or IR, for short. </p><p>A typical ISA instruction is <b>add $r2, $r3, $r4</b> which adds the contents of register 3 to the contents of register 4, and stores the result into register 2 (overwriting the previous contents of register 2). </p><p>Note that this instruction is written in pseudo-English, much like C++ code is written in pseudo-English. The CPU processes a binary translation of this instruction. The actual instruction is really a 32-bit bitstring which stands for the add instruction. </p><p></p></li><li><b>Decode an instrution/Operand Fetch</b><p>Once the instruction is in the CPU, the CPU has to figure out what instruction was fetched. Based on the binary pattern of the instruction, the CPU begins to fetch operands. </p><p>Think of an instruction as a function. The operands are the arguments to the function. For the most part, the operands are stored in registers, so the CPU must get the data from the registers so it can be processed. </p><p></p></li><li><b>Execute instruction using ALU</b><p>The ALU (arithmetic-logic unit) is a combinational logic device that performs operations based on some control inputs. For example, an ALU can add, subtract, do bitwise operations, and so forth. You tell the ALU what to do by setting the control bits correctly. If you change the control bits, the operation of the ALU also changes. </p><p>The ALU has two 32-bit inputs. The inputs of the ALU can come from anywhere, but in the CPU we're talking about, it comes from two registers from the register file. </p><p>For example, the contents of $r3 and $r4 can be fed in as inputs into the ALU. The ALU also has control inputs to tell it what to do. The CPU can set the control inputs so the ALU performs, say, addition, on its inputs. </p><p>The ALU has a 32-bit output, which is the result of performing the operation on the input. </p><p></p></li><li><b>Memory Access (for loads and stores)</b><p>The only instructions that interact with memory are <b>load</b> and <b>store</b>. This occurs at this step. This step is skipped for other instructions. However, load and stores are important enough to mention them at this step. We'll see why it has to be at this step. </p><p></p></li><li><b>Write Back to Register File</b><p>The result of the ALU is stored at some register specified by the instruction. For example, in the instruction <b>add $r2, $r3, $r4</b>, the result is stored in the first register, which is <b>$r2</b></p><p></p></li><li><b>Update PC</b><p>The PC (program counter) stores the address of the next instruction to be fetched. Normally this is the address of the old instruction plus 4. </p></li></ul>These steps are repeated over and over until the program concludes. </dd></dl><dt></dt><h3>Understanding the Pieces </h3><dd>Initially, our goal is to understand the various parts of the computer. In particular: 
<ul type="disc"><li>hidden registers: PC (program counter) and IR (instruction register) plus a few more registers. 
</li><li><b>the register file</b> this device contains the user-visible registers, i.e., registers $r0 through $r31. 
</li><li><b>memory</b> this is where the instructions and data are stored 
</li><li><b>ALU</b> this performs arithmetic or logical operations on data stored in the register. 
</li><li><b>various parts</b> We'll also use wires, other registers, multiplexers, and a few other devices. </li></ul><p>We begin by understanding the following parts: </p><ul><li>What a wire is 
</li><li>What a bus is 
</li><li>What a clock is 
</li><li>What a register is 
</li><li>What a register file is 
</li><li>What an ALU is </li></ul>We'll talk about how to connect the various parts together and how these parts can execute instructions. 
</dd><dt></dt><h3>Review Questions </h3><dd><ul type="disc"><li>What is a computer? 
</li><li>What are registers? 
</li><li>What is an ALU? 
</li><li>What is memory? </li></ul></dd><img src ="http://www.cppblog.com/Winux32/aggbug/17918.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 14:28 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17918.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 3-What's a Clock?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17917.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 06:20:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17917.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17917.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17917.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17917.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17917.html</trackback:ping><description><![CDATA[
		<center>
				<h1>What's a Clock? </h1>
		</center>© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Background </h3><dd>When you buy a computer, one of the first things you probably look for is the speed of the computer. These days, it's not unusual to here rates as fast as 3 GHz. 
<p>But what is 3 Ghz referring to? This is referring to the <i>clock rate</i>. </p><p>The clock on a computer is not the same as the clock on the wall, which is used to tell time. A computer clock is more like a metronome, which keeps the beat for musicians to play music. </p></dd><dt></dt><h3>A Plot of a Clock </h3><dd>One way to understand a clock is to look at a plot of its behavior. 
<p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Clock/clock.png" /></center><p>A clock changes its value from 0 to 1 every period. We use the letter <b>T</b> to designate the period. This signal repeats over and over again. Perhaps you remember, from a course in calculus, about sine waves. This wave repeats once per period. The difference between a sine wave and a clock is that a sine wave is curved. It gradually increases than decreases. </p><p>A clock's signal is squarish in shape. </p><p>Related to the period of the clock is the <i>frequency</i>. Frequency is defined as <b>1/T</b>, and has units of <b>s<sup>-1</sup></b>. </p><p>When you hear clock rates, it's usually given by its frequencies. Thus, 2 Ghz means <b>2 x 10<sup>9</sup></b> cycles per second. A <i>cycle</i> is a signal for a single period. The period for this clock is <b>1/2 x 10<sup>9</sup></b> which is <b>5 x 10<sup>-10</sup></b> seconds, which is half a nanosecond, which is a really, really short period of time. </p><p>To give you an idea of how short this time is. Imagine that everyone in the world sang exactly one note, and exactly one person sings at a time. Suppose each note lasts one nanosecond. It would take 6 seconds to complete (assuming 6 billion people in the world). </p></dd><dt></dt><h3>A More Realistic Clock </h3><dd>A clock can't really instantaneously go from 0 to 1 and back to 0. A more realistic diagram looks like: 
<p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Clock/clock2.png" /></center><p>As you can see the clock signal has a positive slope from 0 to 1 and a negative slope from 1 to 0. This slope has been exaggerated so you can see it better. Normally, it wouldn't be quite so angled. </p></dd><dt></dt><h3>Features of a Clock </h3><dd><p></p><center><img src="http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Overall/Figs/Clock/clock3.png" /></center><p>There are a few key features of a clock: </p><p></p><ul type="disc"><li><b>period</b> This is the time it takes for a clock signal to repeat. Its unit of measurement is seconds. The symbol for the period is <b>T</b>. 
</li><li><b>frequency</b> Frequency is <b>1/T</b>. The unit of measurement is <b>s<sup>-1</sup></b>, which is inverse seconds. This is also sometimes called <b>Hertz</b> (abbreviated <b>Hz</b>). Sometimes people say "cycles per second" instead of <b>Hz</b> or <b>s<sup>-1</sup></b>. They all mean the same. When people refer to the "speed" of a CPU, they are usually talking about the clock frequency. 
</li><li><b>positive edge</b> When the signal transitions from 0 to 1. It's circled above. 
</li><li><b>negative edge</b> When the signal transitions from 1 to 0. It's circled above. </li></ul><p>Each positive clock edge appears once per clock period. Each negative clock edge appears once per clock period. </p></dd><dt></dt><h3>Is It Always 50-50? </h3><dd>In the clock diagrams above, the amount of time the clock is at 1 appears to be <b>T/2</b> (i.e., half the period). The amount of time the clock is at 0 also appears to be <b>T/2</b>. (There is a little time when it transitions from 0 to 1 or from 1 to 0, but let's assume this is a fairly small fraction of <b>T</b>). 
<p>Must a clock always do this? The answer is no. We could have a clock where it stays 1 for <b>3T/4</b> (three quarters of a period) and 0 for <b>T/4</b> (one quarter of a period), or any fraction <b>x</b> and <b>T - x</b> where <b>x &lt; T</b>. </p><p>If you're only using the positive edge, then it doesn't matter how long the signal stays at 1 or 0, since you only use the edge. However, if you want to use <i>both</i> positive and negative edges, then you're going to have to consider when you want the edges to occur. </p></dd><dt></dt><h3>A Simple Exercise </h3><dd>In order to get a feel for how a clock signal behaves, put your finger at the beginning of the clock signal in the diagram above. At this point, the signal should have a value of 0. 
<p>Begin to move your finger to the right, but trace out the signal. Your finger should move from 0 to 1, and back again. </p><p>If you happen to trace over the positive edge once a second, and you're steadily moving to the right (not going faster or slower) then the period is 1 second, and the frequency is 1 Hz. </p><p>Tracing the signal with your hand gives you a better "feel" for how a continuous signal behaves. Usually, computer science majors have a more difficult time with this (unless you really like calculus or are in engineering) because we deal with quantities that are discrete, rather than continuous. </p><p>At any point in time, someone can ask you the current value of the signal. </p><p>If we use the "pipe" analogy, we can think of this signal alternating between pumping red soda (for 0) and green soda (for 1). </p></dd><dt></dt><h3>What's a Clock Used For? </h3><dd>We use a clock to synchronize the events of a CPU. Devices in a CPU can be categorized as sequential circuits or combinational circuits. <b>Sequential logic</b> devices use a clock. Basically, sequential logic devices can only change outputs once a period, usually during a positive or a negative edge. We'll assume that a sequential device can only change outputs on positive clock edges. 
<p>To give you an analogy, imagine a music conductor tapping a beat with a baton (a stick) at regular intervals. Suppose you are playing a piano, and you're told to play a new note each time he taps his baton. Thus, how fast the conductor taps the baton controls how often you play notes. </p><p>Similarly, the rate at which the positive clock edge appears controls how fast a sequential logic device can change outputs. </p><p>It turns out that by using a clock, we can design a CPU more easily than if we don't use a clock. This is primary reason to use a clock. </p></dd><dt></dt><h3>Can't We Make It Faster? </h3><dd>If a CPU will run faster with a faster clock, then why not run it faster? The problem is that it takes time for signals to move around in a circuit. You can reduce this time in several ways. The main way is simply to make the circuit smaller. When the circuit is smaller, signals have less distance to travel, and therefore everything can happen more quickly. </dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17917.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 14:20 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17917.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 2-What's a Bus?</title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17916.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 06:19:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17916.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17916.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17916.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17916.html</trackback:ping><description><![CDATA[
		<center>
				<h1>What's a Bus? </h1>
		</center>© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>It's a Bunch of Wires </h3><dd>One wire allows you to transmit a bit. However, most of the times, we need to transmit 32 bits. So, we want to have 32 wires. It's useful to think of these 32 wires as a group. 
<p>To refer to the wires, we may write <b>B<sub>31..0</sub></b>. Each wire is referred to by a subscript. Thus, <b>B<sub>i</sub></b> refers to wire <b>i</b>. </p><p><b>B<sub>max..min</sub></b> refers to the wires from <b>B<sub>max</sub></b> to <b>B<sub>min</sub></b>, inclusive. </p><p>Sometimes it's useful to talk about saying what values are on the bus. However, 32 bits is a lot to write, so it's convenient to write using 8 hex digits (which is equivalent to 32 bits). </p><p>This can be written like <b>B<sub>31..0</sub> = 0x10001000</b>. In this case <b>B<sub>31</sub> = 0</b>, <b>B<sub>30</sub> = 0</b><b>B<sub>29</sub> = 0</b>, <b>B<sub>28</sub> = 1</b> . Recall that every hex digit can be rewritten as 4 bits. </p><p>As with the wire, we want at most one device writing a 32 bit value to the bus. However, any number of devices can read from the bus. </p><p>We expect, over time, that different devices will take turn who writes to the bus, and that values will change. </p><p>Realize that even though a device is writing to a bus, other devices don't have to read the value off the bus. Devices can choose to ignore the values on the bus. </p><p>This makes it sound like the devices act independently of one another, but it's more like an orchestra. There are many parts, but they are being orchestrated to act together. An orchestra has many instruments, but their purpose is to play parts of a whole song. That's how you should view the parts of a computer. </p><p>The role of the bus is to allow devices to communicate with another. </p></dd><dt></dt><h3>Is a Bus a Good Idea? </h3><dd>You may have noticed that the bus seems like a poor way for more than one device to communicate. Only one device can write to the bus at a time. Wouldn't it be more efficient to have a direct connection between any pair of devices? 
<p>That may be true, but there are some problems. First, the number of direct connections is <b>O(n<sup>2</sup>)</b>. In particular, it's <b>[n X (n-1)]/ 2</b> connections. </p><p>That's a lot of connections. If you have 4 devices, you have 6 connections. However, you could have just a single bus to connect all four devices. </p><p>The bigger problem is that hardware is hardware. A device has some number of inputs and outputs, and those are fixed in number. Out of necessity, you have to use a bus or some device which does not require a device to need more inputs or outputs. </p></dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 14:19 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to "Build" a Computer 1-What's a Wire? </title><link>http://www.cppblog.com/Winux32/archive/2007/01/23/17915.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 23 Jan 2007 06:17:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/23/17915.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17915.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/23/17915.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17915.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17915.html</trackback:ping><description><![CDATA[© 2003 by Charles C. Lin. All rights reserved. 
<dl><dt></dt><h3>Wires </h3><dd>You can transmit a single bit on a wire. The purpose of a wire is to allow information to be transmitted. 
<p>It's useful to think of the wire like a pipe which you can send soda. Let's pretend a device can send two kinds of soda. If a device pumps red soda, then the wire is transmitting a 0. If a device pumps green soda, the wire is transmitting a 1. </p><p>A device can also pump no soda at all. In this case, the wire is at high impedance, which means it has neither value 0 or 1 (or perhaps more precisely, it has a random value of 0 or 1, which changes depending on when it is read). </p><p>When a device is pumping soda into the pipe, it can only pump red or green soda. No other device is allowed to pump soda onto the same wire. If some other device attempts to pump soda, then the wire will contain a garbage value. We assume there is a garbage value even if two devices are pumping soda of the same color. </p><p>The device that is pumping the soda is said to <i>write</i> a a value to the wire. We want to guarantee that there is, at most, single writer (there may be none). </p><p>Devices may "read" the wire as well. The device can "sample" the soda, and determine if it's red or green. If the device attempts to read the value of a pipe when it is empty, or if the device attempts to read the value when two or more devices attempt to pump soda, then we assume the value read is random. That is, it can either be a 0 or a 1, but we don't know which, and this value can change. </p><p>In order for us to make a stable system, we want devices reading when a pipe contains soda pumped by a single device. </p><p>More than one device can read from the wire, but at most one device can write to the wire. </p></dd><dt></dt><h3>Why the Soda Analogy? </h3><dd>You probably think it's weird to view a wire like a pipe containing soda. However, it gives us some insight into the working of a wire. 
<p>When you learn to program, you often think of values in discrete units. For example, suppose you want to run the statement: <b>z = foo( x + y )</b>. You think of <b>x + y</b> being computed, then this value sent to <b>foo</b>, then <b>foo</b> computing a return value, and this return value being stored in <b>z</b>. </p><p>Each event occurs in a discrete step. </p><p>However, it's better to think of a wire like water being sent to your home, or like electricity flowing down the wires. It's constantly flowing. This creates a more accurate image of what's happening in a circuit. </p><p>In reality, electrons are floating at some potential of either 0 or 5 volts (though these days, it's sometimes 3.3 volts) where 0 volts represents the bit 0, and 5 volts represents the value 1. If no voltage is asserted on the wire, the the voltage is ambiguous and essentially "floats". </p><p>These electrons are flowing through the wire, and devices can measure the potential of the wire to determine if there is a 0 or 1 on the wire. </p><p>We want to avoid two devices trying to assert (i.e. "write") voltages on the wires. </p></dd><dt></dt><h3>Specifying Behavior </h3><dd>It's useful to specify the behavior of the wire, using two devices attempting to write a value to a wire. Each device can do one of three things: write a 0, write a 1, or not write at all. When a device does not write a value, we'll use the letter Z, which is the symbol for "high impedance" (i.e., no output). 
<p>The following chart describes the behavior. </p><p></p><center><table cellpadding="3" border="1"><tbody><tr><td bgcolor="pink"><b>DeviceOne</b></td><td bgcolor="pink"><b>DeviceTwo</b></td><td bgcolor="#aaffaa"><b>Wire Value</b></td></tr><tr align="middle"><td><b>0 </b></td><td><b>0 </b></td><td><b>? </b></td></tr><tr align="middle"><td><b>0 </b></td><td><b>1 </b></td><td><b>? </b></td></tr><tr align="middle"><td><b>0 </b></td><td><b>Z </b></td><td><b>0 </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>0 </b></td><td><b>? </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>1 </b></td><td><b>? </b></td></tr><tr align="middle"><td><b>1 </b></td><td><b>Z </b></td><td><b>1 </b></td></tr><tr align="middle"><td><b>Z </b></td><td><b>0 </b></td><td><b>0 </b></td></tr><tr align="middle"><td><b>Z </b></td><td><b>1 </b></td><td><b>1 </b></td></tr><tr align="middle"><td><b>Z </b></td><td><b>Z </b></td><td><b>Z </b></td></tr></tbody></table></center><p>The output is one of four values: 0, 1, Z, and ?. 0 and 1 should be obvious. </p><p><b>?</b> occurs when two devices attempt to write to the wire at the same time. When a device reads from the bus it reads a value that's either 0 or 1, so it's unknown. We want to avoid having two devices write at the same time. </p><p><b>Z</b> means that no device is writing to the wire. Reading a value from the wire also results in a value that's 0 or 1, but it's not known which. We want to avoid having a device read the wire when no device is writing to a wire. </p></dd><dt></dt><h3>Other Issues </h3><dd>In reality, we've avoided a few issues. In particular, we haven't discussed how fast we can change values on the wire. This can affect how fast the CPU works, but since this is not <i>such</i> an important issue, we won't discuss it much. </dd></dl><img src ="http://www.cppblog.com/Winux32/aggbug/17915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-23 14:17 <a href="http://www.cppblog.com/Winux32/archive/2007/01/23/17915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax技术概述与现状应用zz</title><link>http://www.cppblog.com/Winux32/archive/2007/01/17/17725.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Wed, 17 Jan 2007 08:25:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/17/17725.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17725.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/17/17725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17725.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17725.html</trackback:ping><description><![CDATA[
		<div class="storyTitle">Ajax技术概述与现状应用 </div>
		<div class="noDisplay">=========================================================== </div>
		<div class="storyInfo">作者: java(http://java.itpub.net)<br />发表于: 2006.08.17 10:54<br />分类: 新技术热点 <br />出处: http://java.itpub.net/post/20968/194605<br />--------------------------------------------------------------- <br /></div>
		<div class="storytext">AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML)，是指一种创建交互式网页应用的网页开发技术。<br />AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML)，是指一种创建交互式网页应用的网页开发技术。 
<p>　　Ajax技术是目前在浏览器中通过JavaScript脚本可以使用的所有技术的集合。Ajax并没有创造出某种具体的新技术，它所使用的所有技术都是在很多年前就已经存在了，然而Ajax以一种崭新的方式来使用所有的这些技术，使得古老的B/S方式的Web开发焕发了新的活力，迎来了第二个春天。</p><p>　　具体来说，Ajax基于以下的技术:</p><ul><li>　　XHTML:对应W3C的XHTML规范，目前是XHTML1.0。 
</li><li>　　CSS:对应W3C的CSS规范，目前是CSS2.0 
</li><li>　　DOM:这里的DOM主要是指HTML DOM，XML DOM包括在下面的XML中 
</li><li>　　JavaScript:对应于ECMA的ECMAScript规范 
</li><li>　　XML:对应W3C的XML DOM、XSLT、XPath等等规范 
</li><li>　　XMLHttpRequest:对应WhatWG的Web Applications1.0规范(http://whatwg.org/specs/web-apps/current-work/)的一部分</li></ul><p>　　可以看出，除了XMLHttpRequest以外，所有的技术都是目前已经广泛使用，得到了广泛理解的基于Web标准的技术。而XMLHttpRequest虽然尚未被W3C采纳，其实已经是一个事实上的标准。几乎所有主流的浏览器，例如IE、Firefox、Netscape、Opera、Safari全部都支持这个技术。所以Ajax就是目前做Web开发最符合标准的技术。上述的所有技术都已经可以在浏览器中使用，因此用户不需要安装任何额外的软件(只需要一个浏览器，例如IE)，就可以运行任何符合标准的Ajax应用。这对于Ajax技术的普及、降低部署维护的成本是非常重要的。</p><p>　　此外，随着浏览器的发展，更多的技术还会被添加进Ajax的技术体系之中。例如，目前Firefox浏览器的最新版本已经可以直接支持矢量图形格式SVG。Firefox已经可以支持JavaScript 2.0(对应ECMAScript 4.0规范)中的E4X(JavaScript的XML扩展)。Firefox、Opera、和Safari浏览器还可以支持Canvas(也是Web Applications1.0规范的一部分)，网络上已经有人开发出了使用Canvas技术制作的3D射击游戏的演示版。但是因为这些技术目前还没有得到市场占有率最高的IE浏览器的支持，因此目前只能被应用于一些有限的场合(例如，在企业/机关内部，可以要求用户只使用Firefox浏览器)。</p><p>　　Ajax技术之中，最核心的技术就是XMLHttpRequest，它最初的名称叫做XMLHTTP，是微软公司为了满足开发者的需要，1999年在IE5.0浏览器中率先推出的。后来这个技术被上述的规范命名为XMLHttpRequest。它正是Ajax技术之所以与众不同的地方。简而言之，XMLHttpRequest为运行于浏览器中的JavaScript脚本提供了一种在页面之内与服务器通信的手段。页面内的JavaScript可以在不刷新页面的情况下从服务器获取数据，或者向服务器提交数据。而在这个技术出现之前，浏览器与服务器通信的唯一方式就是通过HTML表单的提交，这一般都会带来一次全页面的刷新。</p><p>　　XMLHttpRequest的出现为Web开发提供了一种全新的可能性，甚至整个改变了人们对于Web应用由什么来组成的看法。在这个技术出现之前，由于技术上的限制，人们认为Web应用就是由一系列连续切换的页面组成的。因此整个Web应用被划分成了大量的页面，其中大部分是一些很小的页面。用户大部分的交互都需要切换并刷新整个页面，而在这个过程中(下一个页面完全显示出来之前)，用户只能傻等，什么都做不了。这就是我们所习以为常的Web应用，10年以前就是这个样子。然而XMLHttpRequest技术的出现使得我们可以打破这种笨拙的开发模式，以一种全新的方式来做Web开发，为用户提供更好的交互体验。大量的探索者(自豪的说，也包括笔者在内)以XMLHttpRequest技术为基础，将一些古老的Web技术重新包装整合。经过了多年的不懈努力，终于在2005年开花结果。在这一年，出现了一个新的术语Ajax，来描述这样一类的技术和开发方式。</p><p>　　与传统的Web开发不同，Ajax并不是以一种基于静态页面的方式来看待Web应用的。从Ajax的角度看来，Web应用仅由少量的页面组成，其中每个页面其实是一个更小型的Ajax应用。而一些简单的Ajax应用，例如一个简单的RSS阅读器，甚至只有一个页面。每个页面上面都包括有一些使用JavaScript开发的Ajax组件。这些组件使用XMLHttpRequest对象以异步的方式与服务器通信，从服务器获取需要的数据后使用DOM API来更新页面中的一部分内容。因此Ajax应用与传统的Web应用的区别主要在3个地方:</p><p>　　1. 不刷新整个页面，在页面内与服务器通信。</p><p>　　2. 使用异步方式与服务器通信，不需要打断用户的操作，具有更加迅速的的响应能力。</p><p>　　3. 应用仅由少量页面组成。大部分交互在页面之内完成，不需要切换整个页面。</p><p>　　由此可见，Ajax使得Web应用更加动态，带来了更高的智能，并且提供了表现能力丰富的Ajax UI组件。这样一类新型的Web应用叫做RIA(Rich Internet Application)应用。除了Ajax，还包括有Flash等技术。</p><p>　　与1990年代末的DHTML相比，Ajax更加强调符合真正的Web标准的开发方式。Ajax对于现有基于Web标准的技术的利用程度比DHTML高出了很多。而DHTML声名狼藉，最终失败的最大原因就是在于不重视基于真正的Web标准来做开发。</p><p>　　DHTML其实是浏览器大战的时代微软和Netscape为了吸引眼球而制造的一个名词，并没有得到W3C的认可。并且经常被开发人员滥用，制造出一大堆不符合真正的Web标准的JavaScript脚本和HTML标记，常常只能运行在某种特定的浏览器中(主要是IE)。</p><p>　　DHTML总是过于注重各种花哨的视觉效果，而Ajax最关注的问题则是真正改善Web应用可用性，这正是Ajax技术诞生的使命，甚至也正是JavaScript脚本语言诞生的使命。跨浏览器自然是Web应用可用性的重要组成部分，只有基于真正的Web标准来做开发，才有可能跨浏览器为用户提供一致的交互体验。而跨浏览器仅仅是基于真正的Web标准做开发的一个原因。另外一个原因是，唯有这样，才能充分地利用Web标准发展的成果(例如上述的SVG、E4X等符合标准的技术)，并且建造出向后兼容的Web应用。向后兼容的意思就是我们今天建造的Web应用，当明天用户都使用浏览器的新版本(例如IE 7.0)之后，不必再加以修改就能直接运行在这些新版本之上。这样可以降低Web应用的维护成本，并且可以真正达到改善可用性，使用户获得更好的交互体验的目标(想想看，假设用户将自己的浏览器升级为IE 7.0，并且访问一个她过去经常去的网站，突然发现网站的某个功能失效了，她会有什么感觉?)。做过多年Web开发的开发者都知道，以前专门为IE5.0开发的Web应用，尤其是使用了很多JavaScript的应用，不加以修改和重新测试就运行在IE6.0上几乎是不可能的。在这里就是没有做到向后兼容。Ajax技术会使得这些问题都不再存在。</p><p>　　Ajax技术有两个推动力，Web标准的成熟和软件交互设计和可用性理论的成熟。在软件的可用性方面，除了一些通用的软件可用性和交互设计理论之外(这方面的经典著作包括《面向使用的软件设计》、《About Face 2.0》中文版等等)，Web应用的可用性(Web usability)也是国外非常热门的一个研究领域，主要侧重于研究如何提高Web应用的可用性。美国在这个领域有着非常深入的研究，并且对于一些公共机构网站的可用性还有相关的法律条款来约束(Section508，508条款，于2001年6月21日成为美国的法律，直接影响了联邦部门和一些代理机构，还有为他们服务的网页设计师。这条法律也适用于政府投资项目和任何采用了该法律的州)。对于这些网站，如果无法达到条款上的一些可用性要求，网站经营者就违法了。如果是开发公司无法达到这些要求，就别指望从联邦政府手中拿到这些项目。</p><p>　　为了对如何提高Web应用的可用性做出指导，W3C在20世纪90年代建立了Web Accessibility Initiative(WAI)，致力于为网站建造者提供实现可访问性(与可用性同义)的方法和策略(http://www.w3.org/WAI/GL/)Web可用性方面的经典著作包括《网站重构》。</p><p>　　综上所述，可以认为Ajax就是Web标准和Web应用的可用性理论的集大成者。它极大地改善了Web应用的可用性和用户的交互体验，最终得到了用户和市场的广泛任何。所以可以说，Ajax就是用户和市场的选择。</p><p>　　目前Ajax已经成为了Web应用的主流开发技术，大量的业界巨头已经采纳并且在大力推动这个技术的发展。最近的动态包括:</p><p>　　1. IBM、Oracle、Yahoo!、BEA、RedHat、Novell等页界领先的公司启动了Open Ajax项目。致力于为Ajax开发建造先进强大的的开发工具。IBM在2月底已经发布了Open Ajax项目的Ajax Toolkit Framework(ATF)1.0，是一个基于Eclipse IDE的Ajax开发工具。</p><p>　　2. 微软开发了自己的Ajax框架Altas，不过主要是和服务器端他们自己的ASP.NET框架配合工作。</p><p>　　3. Sun虽然行动迟缓，但是也将Ajax技术列入了J2EE的blueprint(蓝图)中，作为J2EE技术的有益的补充。</p><p>　　除了上述这些公司之外，Google公司不可不提，因为正是他们率先采用Ajax技术建造出了一大堆非常出色的应用，才将Ajax技术引到了聚光灯下。Google公司建造的Ajax应用包括Google Maps、GMail、Google Suggest等等，其中公认最优秀最复杂的Ajax应用是Google Maps。由于完全基于Ajax技术来建造Google Maps的界面，Google Maps提供了远远超越其竞争对手的地图服务的交互体验。如果说Google后台的地图技术并不存在巨大优势的话，那么Ajax技术和优秀的交互设计成为了他们压倒竞争对手的最后一根稻草。最终使得Google Maps脱颖而出，获得了用户的青睐。</p><p>　　我们可以对比一下微软前后的两个地图服务就可以看出差别。</p><p>　　微软公司所提供的旧的地图服务:http://terraserver.microsoft.com。是传统Web应用的代表，性能很差而且极其难用。</p><p>　　微软公司所推出了新的地图服务:http://local.live.com/。新的地图服务包括这个网站上的很多其他服务完全基于Ajax技术来建造，获得了极好的可用性。这个地图可以看作是在Google推出了Google Maps服务之后，微软公司痛定思痛的产物，在很多地方模仿了Google Maps。</p><p>　　Ajax的典型应用除了Google Maps，还有微软的Windows Live、Yahoo!的Flickr等等。此外国内新浪的blog也使用了一些Ajax的技术。</p></div>
<img src ="http://www.cppblog.com/Winux32/aggbug/17725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-17 16:25 <a href="http://www.cppblog.com/Winux32/archive/2007/01/17/17725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PC演义(1971-1980)</title><link>http://www.cppblog.com/Winux32/archive/2007/01/16/17687.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 16 Jan 2007 08:16:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/16/17687.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17687.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/16/17687.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17687.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17687.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top" width="39%">
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td width="193" bgcolor="#003300">
																		<font class="SongBoldFFFFFF" color="#ffffff">
																				<b>第三部分：PC演义</b>
																		</font>
																</td>
														</tr>
														<tr>
																<td class="biao" width="193" bgcolor="#b6c5b9">　　计算机最终要走进千家万户，这个大趋势注定了PC必将在历史的某一时刻出现。身为产业霸主的蓝色巨人不辱使命，为全世界贡献了这一伟大的革命性产品。最终，PC从一种纯粹的技术产品衍生出了一种精神层面的涵义，这就是：开放。 
<p>　　IBM PC的开放架构引来了无数的模仿者，产业的腾飞也使PC厂商的竞争从技术层面更多地延展到了商业层面。参与第一台IBM PC开发工作的布拉德利博士说：“模仿是对创造者的最好的称赞。不是一两个人，也不是一两家公司，而是全社会，造就了PC产业的辉煌。”</p><p>　　开放意味着奉献，意味着把自己的思想与别人共享，但同时也就意味着牺牲一部分利益。然而，开放因此也成为一种境界。正是因为如此，PC才得以不朽，英雄才得以显得伟大，巨人才得以更加强大。<br /></p></td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="33"> </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" width="193" bgcolor="#b6c5b9">
																		<p>
																				<a name="1971">
																				</a>
																				<span class="biao">
																						<strong>1971<br />微处理器时代的开端</strong>
																				</span>
																		</p>
																		<p class="biao">微处理器的问世，是微电子领域有史以来最重要的发明之一，微处理器时代的到来预示着微型计算机将获得广泛的应用，更多计算机的出现将对人类社会产生翻天覆地的影响。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="382"> </td>
														</tr>
														<tr>
																<td width="23" height="125">
																		<p> </p>
																</td>
																<td valign="top" width="193" bgcolor="#b6c5b9" height="125">
																		<p>
																				<a name="1972">
																				</a>
																				<span class="biao">
																						<strong>1972-1975<br />微处理器实现N-MOS突破</strong>
																				</span>
																		</p>
																		<p class="biao">从Intel 8008开始，微处理器已经能够每次处理一个完整的字节。8位微处理器Intel 8080标志着微处理器的发展进入第二代，为微型计算机的诞生做好了最后的准备，微机已然呼之欲出。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1099">  </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9">
																		<p>
																				<a name="1975">
																				</a>
																				<span class="biao">
																						<strong>1975<br />Altair启动微机时代</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">MITS制造的第一台微型计算机Altair 8800，标志着微机时代正式到来。</span>
																		</p>
																		<p class="biao">两个年轻人创立Microsoft</p>
																		<p class="biao">崭露头角的微型机，即将带动整个产业的腾飞，年轻的Microsoft正是软件公司的神话。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1210">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="1976">
																				</a>
																				<span class="biao">
																						<strong>1976<br />“两个Steve”创立Apple</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">Apple计算机公司迅速成为微型机时代的骄子，写下了计算机史上的一段神话。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1417">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="1977">
																				</a>
																				<span class="biao">
																						<strong>1977<br />Apple II闪亮登场</strong>
																				</span>
																		</p>
																		<p>
																				<span class="biao">Apple推出经典机型Apple II，这是历史上最重要的微型计算机之一，微机由此开始步入其发展史上的第一个黄金时代，并形成了可观的产业规模。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1349">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="1978">
																				</a>
																				<span class="biao">
																						<strong>1978-1979<br />微处理器迈向16位总线</strong>
																				</span>
																		</p>
																		<p>
																				<span class="biao">16位总线的Intel 8086微处理器，标志着第三代微处理器问世。1年后推出的准16位微处理器Intel 8088，为整机的设计提供了更大的灵活性。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1069">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="1980">
																				</a>
																				<span class="biao">
																						<strong>1980<br />Microsoft的秘密交易</strong>
																				</span>
																		</p>
																		<p>
																				<span class="biao">1980年10月，Microsoft买下了一个不完善的操作系统并对其进行了修改，从而把握了一次绝佳的发展机遇：为正在开发中的IBM PC提供操作系统。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
								<td valign="top" width="61%">
										<table cellspacing="0" cellpadding="5" width="333" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="50"> </td>
														</tr>
														<tr>
																<td width="29" rowspan="2">
																		<p> </p>
																</td>
																<td valign="top" width="284">
																		<img height="116" src="http://www.elinkage.com.cn/PC20_historical/3-01.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>霍夫和Intel 4004</b>
																				<br />1971年1月，Intel公司的霍夫研制成功世界上第一块4位微处理器芯片Intel 4004，标志着第一代微处理器问世，微处理器和微机时代从此开始。<br />因发明微处理器，霍夫被英国《经济学家》杂志列为“二战以来最有影响力的7位科学家”之一。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="150" src="http://www.elinkage.com.cn/PC20_historical/3-02.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />1971年11月，Intel推出MCS-4微型计算机系统（包括4001 ROM芯片、4002 RAM芯片、4003移位寄存器芯片和4004微处理器），其中4004（上图）包含2300个晶体管，尺寸规格为3mm×4mm，计算性能远远超过当年的ENIAC，最初售价为200美元。 </p>
																		<p>
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29" height="228"> </td>
																<td class="biao" valign="top" width="284" height="228">
																		<img height="225" src="http://www.elinkage.com.cn/PC20_historical/3-03.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>“只有偏执狂才能生存”</b>
																				<br />Intel公司成立于1968年，格鲁夫（左）、诺依斯（中）和摩尔（右）是微电子业界的梦幻组合。 </p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="124" src="http://www.elinkage.com.cn/PC20_historical/3-04.gif" width="167" />
																				<img height="124" src="http://www.elinkage.com.cn/PC20_historical/3-05.gif" width="96" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>早期的鼠标</b>
																				<br />恩格尔巴特发明的鼠标最初并不是应用在微机上，而是用于网络工作站。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="113" src="http://www.elinkage.com.cn/PC20_historical/3-06.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Intel 8008</b>
																				<br />1972年4月，霍夫等人开发出第一个8位微处理器Intel 8008。由于8008采用的是P沟道MOS微处理器，因此仍属第一代微处理器。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="113" src="http://www.elinkage.com.cn/PC20_historical/3-07.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>第二代微处理器</b>
																				<br />1973年8月，霍夫等人研制出8位微处理器Intel 8080，以N沟道MOS电路取代了P沟道，第二代微处理器就此诞生。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="105" src="http://www.elinkage.com.cn/PC20_historical/3-08.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />主频2MHz的8080芯片运算速度比8008快10倍，可存取64KB存储器，使用了基于6微米技术的6000个晶体管，处理速度为0.64MIPS。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="158"> </td>
																<td class="biao" valign="top" width="284" height="158">
																		<img height="153" src="http://www.elinkage.com.cn/PC20_historical/3-09.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>摩尔定律</b>
																				<br />摩尔预言，晶体管的密度每过18个月就会翻一番，这就是著名的摩尔定律。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="169" src="http://www.elinkage.com.cn/PC20_historical/3-10.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Zilog公司于1976年开发的Z80微处理器，广泛用于微型计算机和工业自动控制设备。当时，Zilog、Motorola和Intel在微处理器领域三足鼎立。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="166"> </td>
																<td class="biao" valign="top" width="284" height="166">
																		<hr size="1" />
																		<img height="146" src="http://www.elinkage.com.cn/PC20_historical/3-11.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>第一台微型计算机：Altair 8800</b>
																				<br />1975年4月，MITS发布第一个通用型Altair 8800，售价375美元，带有1KB存储器。这是世界上第一台微型计算机。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="146"> </td>
																<td class="biao" valign="top" width="284" height="146">
																		<img height="142" src="http://www.elinkage.com.cn/PC20_historical/3-12.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29" height="23"> </td>
																<td class="biao" valign="top" width="284" height="23">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />埃德·罗伯茨把Altair定位在青年电脑迷市场。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="171" src="http://www.elinkage.com.cn/PC20_historical/3-13.gif" width="230" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />1975年1月出版的《大众电子》，刊出了一篇MITS介绍其Altair 8800计算机的文章，Altair出现在杂志的封面，实际上这只是一个空壳的模型而不是真正的机器。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="91" src="http://www.elinkage.com.cn/PC20_historical/3-14.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Paul Allen和Bill Gates在三周内为Altair开发出BASIC语言，MITS成为两个未来富翁的第一个客户。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="121"> </td>
																<td class="biao" valign="top" width="284" height="121">
																		<p>
																				<img height="136" src="http://www.elinkage.com.cn/PC20_historical/3-15.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />当Bill Gates崭露头角时，昔日校友正在哈佛上二年级。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="137" src="http://www.elinkage.com.cn/PC20_historical/3-16.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />“让每个家庭每张桌子上都放一台电脑。”</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<p>
																				<img height="167" src="http://www.elinkage.com.cn/PC20_historical/3-17.gif" width="200" />
																		</p>
																		<p>
																				<img height="37" src="http://www.elinkage.com.cn/PC20_historical/3-18.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Apple Ⅰ</b>
																				<br />1976年3月，Steve Wozniak和Steve Jobs开发出微型计算机Apple I，4月1日愚人节这天，两个Steve成立了Apple计算机公司。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="153" src="http://www.elinkage.com.cn/PC20_historical/3-19.gif" width="230" />
																		</p>
																		<p>
																				<img height="144" src="http://www.elinkage.com.cn/PC20_historical/3-20.gif" width="240" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Steve Jobs(右)和Steve Wozniak（左）展示Apple I的主板，这台机器一直被Apple的支持者看作是一件艺术品。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="157" src="http://www.elinkage.com.cn/PC20_historical/3-21.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />两个Steve在Jobs的车库里制造出了一个传奇故事。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="150" src="http://www.elinkage.com.cn/PC20_historical/3-22.gif" width="200" />
																		</p>
																		<p>
																				<img height="188" src="http://www.elinkage.com.cn/PC20_historical/3-23.gif" width="250" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>“来咬一只苹果”</b>
																				<br />Apple微型机一问世就引起人们的极大兴趣，其广告词是“来咬一只苹果”。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<p>
																				<img height="131" src="http://www.elinkage.com.cn/PC20_historical/3-24.gif" width="200" />
																		</p>
																		<p>
																				<img height="211" src="http://www.elinkage.com.cn/PC20_historical/3-25.gif" width="200" />
																		</p>
																		<p>
																				<img height="160" src="http://www.elinkage.com.cn/PC20_historical/3-26.gif" width="200" />
																		</p>
																		<p>
																				<img height="135" src="http://www.elinkage.com.cn/PC20_historical/3-27.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Apple II问世</b>
																				<br />Apple II是第一个带有彩色图形的个人计算机，售价为1300美元。Apple II及其系列改进机型风靡一时，这使Apple成为微型机时代最成功的计算机公司。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="139"> </td>
																<td class="biao" valign="top" width="284" height="139">
																		<img height="180" src="http://www.elinkage.com.cn/PC20_historical/3-28.gif" width="156" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />1978年Apple股票上市，3周内市值达到17.9亿美元，超过福特汽车。1981年Apple进入《财富》500强，叛逆青年Jobs成为《时代》周刊的封面人物。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="130" src="http://www.elinkage.com.cn/PC20_historical/3-29.gif" width="200" />
																		<img height="134" src="http://www.elinkage.com.cn/PC20_historical/3-30.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>红极一时</b>
																				<br />Apple的广告铺天盖地，订单也接踵而来。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="123" src="http://www.elinkage.com.cn/PC20_historical/3-31.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Intel 8086</b>
																				<br />1978年6月，Intel推出4.77MHz的8086微处理器，标志着第三代微处理器问世。它采用16位寄存器、16位数据总线和29000个3微米技术的晶体管，售价360美元。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="188" src="http://www.elinkage.com.cn/PC20_historical/3-32.gif" width="250" />
																		</p>
																		<p>
																				<img height="236" src="http://www.elinkage.com.cn/PC20_historical/3-33.gif" width="230" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Intel 8088</b>
																				<br />1年之后，Intel推出4.77MHz的准16位微处理器8088。它在内部以16位运行，但支持8位数据总线，采用现有的8位设备控制芯片，包含29000个3微米技术的晶体管，可访问1MB内存地址，速度为0.33MIPS。同年9月，Motorola推出M68000 16位微处理器，它因采用了68000个晶体管而得名。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="217"> </td>
																<td class="biao" valign="top" width="284" height="217">
																		<img height="214" src="http://www.elinkage.com.cn/PC20_historical/3-34.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>WordStar</b>
																				<br />字处理程序WordStar是当时很受欢迎的应用软件，后来也广泛用于DOS平台。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="170" src="http://www.elinkage.com.cn/PC20_historical/3-35.gif" width="240" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />
																				<b>Microsoft的秘密交易</b>
																				<br />1980年10月，Microsoft把握了一次绝佳的发展机遇。IBM在秘密进行代号为“跳棋计划”的开发项目（第一台IBM PC）过程中，向Microsoft提出采购一套操作系统。Paul Allen抓住机会与Seattle Computer Products的Tim Patterson签约，向其支付了不到10万美元，获得了其DOS操作系统的版权并进行了一些修改，从而做成了与这个神秘客户（IBM）的大买卖。</p>
																		<p>
																				<b>DOS</b>
																				<br />今天的Windows系列操作系统仍然兼容DOS，这个系统对于老一代电脑用户来说再熟悉不过了。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="178" src="http://www.elinkage.com.cn/PC20_historical/3-36.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Tim Patterson开发的QDOS不太完善，他自己称之为“Quick&amp;Dirty OS”，即“快速而肮脏的操作系统”。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="114" src="http://www.elinkage.com.cn/PC20_historical/3-37.gif" width="185" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Paul Allen早就显示出了非凡的商业嗅觉和生意手腕。 </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/Winux32/aggbug/17687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-16 16:16 <a href="http://www.cppblog.com/Winux32/archive/2007/01/16/17687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PC演义之PC前传zz</title><link>http://www.cppblog.com/Winux32/archive/2007/01/16/17686.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 16 Jan 2007 07:38:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/16/17686.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17686.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/16/17686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17686.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17686.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top" width="39%">
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td width="193" bgcolor="#003300">
																		<font class="SongBoldFFFFFF" color="#ffffff">
																				<b>第二部分：PC前传</b>
																		</font>
																</td>
														</tr>
														<tr>
																<td class="biao" width="193" bgcolor="#b6c5b9">　　作为能够模拟人类思维的高级计算工具，电子计算机有着严谨的数学理论基础和精密的体系结构。1946年问世的ENIAC堪称二十世纪人类最伟大的发明，它标志着现代电子计算机时代的到来。但在ENIAC问世之前，无数杰出的科学家为之付出了艰苦的努力，有一些人的名字是应当被永远铭记的：图林、阿塔纳索夫、冯·诺伊曼……</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1850"> </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9">
																		<p>
																				<a name="1">
																				</a>
																				<span class="biao">
																						<strong>1946<br />ENIAC永载史册</strong>
																				</span>
																		</p>
																		<p class="biao">世界上第一台通用数字电子计算机ENIAC的问世，宣告了人类从此进入电子计算机时代。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1593"> </td>
														</tr>
														<tr>
																<td width="23" height="125">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="125">
																		<p>
																				<a name="2">
																				</a>
																				<span class="biao">
																						<strong>1946-1959<br />第一代电子管计算机的兴盛</strong>
																				</span>
																		</p>
																		<p class="biao">在ENIAC研制成功后，相继出现了一批电子管计算机，主要用于科学计算。采用电子管作为逻辑元件是第一代计算机的标志，在这一时期，IBM公司的IBM 701击败竞争对手UNIVAC，一举奠定了蓝色巨人在计算机产业界的领袖地位。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1352">  </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9">
																		<p>
																				<a name="3">
																				</a>
																				<span class="biao">
																						<strong>1959-1964<br />晶体管造就第二代计算机</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">晶体管的发明，为半导体和微电子产业的发展指明了方向。采用晶体管代替电子管成为第二代计算机的标志。除了科学计算，计算机也开始被用于企业商务。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1548">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="4">
																				</a>
																				<span class="biao">
																						<strong>1964-1970<br />集成电路使第三代计算机脱胎换骨</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">集成电路的问世催生了微电子产业，采用集成电路作为逻辑元件成为第三代计算机的最重要特征。此外，系列兼容和采用微程序设计也是第三代计算机的重要特点，作为第三代计算机的杰出代表，IBM S/360为IBM带来了极大成功，“IBM”几乎成为计算机的代名词。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="881">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="5">
																				</a>
																				<span class="biao">
																						<strong>1970~<br />第四代计算机</strong>
																				</span>
																		</p>
																		<p>
																				<span class="biao">随着集成电路的迅速发展，采用大规模和超大规模集成电路的第四代计算机，计算性能飞速提高，应用范围渗透到社会的每个角落，计算机对社会生产的重要性日益凸显。随着微处理器的问世和发展，微型计算机开始普及，计算机逐渐走进普通人家。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
								<td valign="top" width="61%">
										<table cellspacing="0" cellpadding="5" width="333" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="50"> </td>
														</tr>
														<tr>
																<td width="29" rowspan="2">
																		<p> </p>
																</td>
																<td valign="top" width="284">
																		<img height="121" src="http://www.elinkage.com.cn/PC20_historical/2-01.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />逻辑代数</b>
																				<br />早在1847和1854年，英国数学家布尔发表了两部重要著作《逻辑的数学分析》和《思维规律的研究》，创立了逻辑代数。逻辑代数系统采用二进制，是现代电子计算机的数学和逻辑基础。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="105" src="http://www.elinkage.com.cn/PC20_historical/2-02.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />计算机三原则</b>
																				<br />1939年，阿塔纳索夫提出计算机三原则；采用二进制进行运算；采用电子技术来实现控制和运算；采用把计算功能和存储功能相分离的结构。1939年，阿塔纳索夫还设计并试制数字电子计算机的样机“ABC机”，但未能完工。</p>
																		<p>阿塔纳索夫关于电子计算机的设计方案启发了ENIAC开发小组的莫克利，并直接影响到ENIAC的诞生。1972年美国法院判决ENIAC的专利权无效，阿塔纳索夫拥有作为第一个电子计算机方案提出者的优先权。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="131" src="http://www.elinkage.com.cn/PC20_historical/2-03.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<b>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />图林机：</b>
																		<br />现代通用数字计算机的数学模型<br />1936年，24岁的英国数学家图林发表著名论文《论可计算数及其在密码问题的应用》，提出了“理想计算机”，后人称之为“图林机”。图林通过数学证明得出理论上存在“通用图林机”，这为可计算性的概念提供了严格的数学定义，图林机成为现代通用数字计算机的数学模型，它证明通用数字计算机是可以制造出来的。 
<p>图林发表于1940年的另一篇著名论文《计算机能思考吗？》，对计算机的人工智能进行了探索，并设计了著名的“图林测验”。1954年图林英年早逝，年仅42岁。</p><p> </p></td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="124" src="http://www.elinkage.com.cn/PC20_historical/2-04.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />维纳的现代计算机设计五原则</b>
																				<br />1940年，美国科学家维纳阐述了自己对现代计算机的五点设计原则：数字式而不是模拟式；以电子元件构成并尽量减少机械装置；采用二进制而不是十进制；内部存放计算表；内部存储数据。</p>
																		<p>维纳在1948年完成了著作《控制论》，这不仅使维纳成为控制论的创始人，而且对计算机后来的发展和人工智能的研究产生了深刻的影响。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="146" src="http://www.elinkage.com.cn/PC20_historical/2-05.gif" width="100" />
																				<img height="112" src="http://www.elinkage.com.cn/PC20_historical/2-06.gif" width="150" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />现代电子计算机之父</b>
																				<br />1944~1945年间，美籍匈牙利科学家冯·诺伊曼在第一台现代计算机ENIAC尚未问世时注意到其弱点，并提出一个新机型EDVAC的设计方案，其中提到了两个设想：采用二进制和“存储程序”。这两个设想对于现代计算机至关重要，也使冯·诺伊曼成为“现代电子计算机之父”，冯·诺伊曼机体系延续至今。</p>
																		<p>
																				<br />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="127" src="http://www.elinkage.com.cn/PC20_historical/2-07.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />计算机开关电路</b>
																				<br />1938年，信息论的创始人、美国科学家仙农发表论文《继电器和开关电路的符号分析》，首次阐述了如何将布尔代数运用于逻辑电路，奠定了现代电子计算机开关电路的理论基础。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="185" src="http://www.elinkage.com.cn/PC20_historical/2-08.gif" width="230" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />ENIAC</b>
																				<br />1946年2月15日，世界上第一台通用数字电子计算机ENIAC研制成功，承担开发任务的“莫尔小组”由四位科学家和工程师埃克特、莫克利、戈尔斯坦、博克斯组成，总工程师埃克特当时年仅24岁。</p>
																		<p>ENIAC：长30.48米，宽1米，占地面积170平方米，30个操作台，约相当于10件普通房间的大小，重达30吨，耗电量150千瓦，造价48万美元。它使用18000个电子管，70000个电阻，10000个电容，1500个继电器，6000多个开关，每秒执行5000次加法或400次乘法，是继电器计算机的1000倍、手工计算的20万倍。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="175" src="http://www.elinkage.com.cn/PC20_historical/2-09.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />埃克特（右）和莫克利（左）因共同研制成功ENIAC而名垂青史。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="247" src="http://www.elinkage.com.cn/PC20_historical/2-10.gif" width="200" />
																		<img height="83" src="http://www.elinkage.com.cn/PC20_historical/2-11.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />“西蒙，给他们这笔经费。”</b>
																				<br />ENIAC的诞生背景极富戏剧性。1942年8月，莫克利的报告《高速电子管计算装置的使用》引起了美国军方的注意，这实际上是第一台电子计算机的设计方案。1943年4月9日，美军上校西蒙向科学顾问、数学家维伯伦博士介绍了这一报告，维伯伦沉思片刻，只说了一句话：“西蒙，给他们这笔经费。”ENIAC和现代计算机的命运就这样决定了。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="130" src="http://www.elinkage.com.cn/PC20_historical/2-12.gif" width="200" />
																		</p>
																		<p>
																				<img height="165" src="http://www.elinkage.com.cn/PC20_historical/2-13.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />ENIAC的开发经费几经追加，达到48万美元，相当于现在的1000万美元以上。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="218" src="http://www.elinkage.com.cn/PC20_historical/2-14.gif" width="230" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />UNIVAC</b>
																				<br />UNIVAC由埃克特和莫克利研制成功，这也是第一个进行批量生产的计算机。1951年，电脑开始走出实验室服务于社会与公众。</p>
																		<p>1952年，UNIVAC因准确地预测美国总统大选结果而名声大噪。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="158" src="http://www.elinkage.com.cn/PC20_historical/2-15.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />EDVAC</b>
																				<br />1950问世的第一台并行计算机EDVAC，首次实现了冯·诺依曼体系的两个重要设想：存储程序和采用二进制。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="202" src="http://www.elinkage.com.cn/PC20_historical/2-16.gif" width="230" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />王安的发明</b>
																				<br />1951年，中国移民王安发明了磁芯存储器，IBM于1956年购买了这项技术专利。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="121"> </td>
																<td class="biao" valign="top" width="284" height="121">
																		<p>
																				<img height="130" src="http://www.elinkage.com.cn/PC20_historical/2-17.gif" width="100" />
																				<img height="130" src="http://www.elinkage.com.cn/PC20_historical/2-18.gif" width="120" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />FORTRAN</b>
																				<br />1956年，IBM公司的巴克斯研制成功第一个高级程序语言FORTRAN，它被广泛用于科学计算。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="158" src="http://www.elinkage.com.cn/PC20_historical/2-19.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />大型机战争</b>
																				<br />IBM公司1952年推出的IBM 701在商战中击败UNIVAC，不仅使IBM实现了全面的转型，更奠定了IBM的产业霸主地位。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="207" src="http://www.elinkage.com.cn/PC20_historical/2-20.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />1947年，贝尔实验室的肖克莱、巴丁、布拉顿发明点触型晶体管；1950年又发明了面结型晶体管。相比电子管，晶体管体积小、重量轻、寿命长、发热少、功耗低，电子线路的结构大大改观，运算速度则大幅度提高。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="94" src="http://www.elinkage.com.cn/PC20_historical/2-21.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />肖克莱（左）、巴丁（中）、布拉顿（右）于1956年共同获得诺贝尔物理学奖。</p>
																		<p>发明晶体管的肖克莱在加利福尼亚创立了当地第一家半导体公司，这一地区后来被称为硅谷。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="95" src="http://www.elinkage.com.cn/PC20_historical/2-22.gif" width="120" />
																		<img height="95" src="http://www.elinkage.com.cn/PC20_historical/2-23.gif" width="142" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />Stretch（左）和LARC（右）在商业上都不成功，但在设计中采用了大量新思想，为开发第三代计算机打下了良好的基础。</p>
																		<p>
																				<b>Stretch计划和LARC计划</b>
																				<br />1955，在美国原子能委员会的支持下，IBM和生产UNIVAC的兰德公司分别开始实施 Stretch计划和LARC计划，希望设计更快速的计算机。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="188" src="http://www.elinkage.com.cn/PC20_historical/2-24.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />第二代计算机</b>
																				<br />美国贝尔实验室于1954年研制成功第一台使用晶体管的第二代计算机TRADIC。相比采用定点运算的第一代计算机，第二代计算机普遍增加了浮点运算，计算能力实现了一次飞跃。</p>
																		<p>IBM公司于1958年制成的1401及后续的1410/1440系列计算机，是第二代计算机中的代表，用户在当时可以以每月2500美元的价格租用IBM 1401。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="214" src="http://www.elinkage.com.cn/PC20_historical/2-25.gif" width="150" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />计算机商务处理的开始</b>
																				<br />第二代计算机除了大量用于科学计算，还逐渐被工商企业用来进行商务处理，高级语言FORTRAN和COBOL因此也得到了广泛应用。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="165"> </td>
																<td class="biao" valign="top" width="284" height="165">
																		<hr size="1" />
																		<img height="134" src="http://www.elinkage.com.cn/PC20_historical/2-26.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />第一个半导体集成电路</b>
																				<br />1958年，美国物理学家基尔比和诺伊斯同时发明集成电路。</p>
																		<p>1958年，TI（德州仪器）公司制成第一个半导体集成电路，它是一个助听器。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="130" src="http://www.elinkage.com.cn/PC20_historical/2-27.gif" width="177" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />1969年，法庭判决基尔比(左)和诺伊斯（右）为集成电路的共同发明人，集成电路的专利权属于基尔比，集成电路内部连接技术的专利属于诺伊斯，他们都因此成为微电子学创始人并获得巴伦坦奖章。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="143" src="http://www.elinkage.com.cn/PC20_historical/2-28.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />“蓝色巨人”</b>
																				<br />IBM于1964年研制出计算机历史上最成功的机型之一IBM S/360。IBM由于S/360的成功，进一步巩固了自己在业界的地位，“蓝色巨人”IBM几乎成为计算机的代名词。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="100" src="http://www.elinkage.com.cn/PC20_historical/2-29.gif" width="150" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />S/360极强的通用性适用于各方面的用户，它具有“360度”全方位的特点，并因此得名。开发S/360被称为“世纪豪赌”，IBM为此投入了50亿美元的研发费用，远远超过制造原子弹的“曼哈顿计划”的20亿美元。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="184" src="http://www.elinkage.com.cn/PC20_historical/2-30.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />“三代半计算机”</b>
																				<br />1970年，IBM推出IBM S/370系列机，采用大规模集成电路取代磁芯进行存储，以小规模集成电路作为逻辑元件，被称为三代半计算机。</p>
																		<p>S/370采用了虚拟存储器技术，首次实行软硬件价格分离策略，从而明确了软件的价值。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="129" src="http://www.elinkage.com.cn/PC20_historical/2-31.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />第四代计算机</b>
																				<br />从1970年至今的计算机基本上都属于第四代计算机，它们都采用大规模和超大规模集成电路。随着技术的进展，计算机开始分化成通用大型机、巨型机、小型机和微型机。</p>
																		<p>笔记本电脑是第四代计算机的新贵</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="160" src="http://www.elinkage.com.cn/PC20_historical/2-32.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />DEC：小型机骄子</b>
																				<br />从60年代起到80年代后期，DEC依靠小型机PDP和VAX系列成长为世界第二大电脑公司，但在1998年被Compaq收购。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="232" src="http://www.elinkage.com.cn/PC20_historical/2-33.gif" width="260" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<b>
																						<img height="15" src="http://www.elinkage.com.cn/PC20_historical/arrow_up.gif" width="15" />IBM独步天下</b>
																				<br />由于策略得当，IBM在70年代延续了早期的辉煌，继续在计算机产业界独步天下。许多厂商无法与IBM全面抗衡，就采取了PCM（接插兼容制造商，Plug Compatible Manufacturers）的策略，发展与IBM计算机兼容的硬件接插设备。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/Winux32/aggbug/17686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-16 15:38 <a href="http://www.cppblog.com/Winux32/archive/2007/01/16/17686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PC演义之计算溯源zz</title><link>http://www.cppblog.com/Winux32/archive/2007/01/16/17685.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 16 Jan 2007 07:22:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2007/01/16/17685.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/17685.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2007/01/16/17685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/17685.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/17685.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top" width="39%">
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td width="193" bgcolor="#003300">
																		<font class="SongBoldFFFFFF" color="#ffffff">
																				<b>第一部分：计算溯源</b>
																		</font>
																</td>
														</tr>
														<tr>
																<td class="biao" width="193" bgcolor="#b6c5b9">　　在漫长的人类进化和文明发展过程中，人类的大脑逐渐具有了一种特殊的本领，这就是把直观的形象变成抽象的数字，进行抽象思维活动。正是由于能够在“象”和“数”之间互相转换，人类才真正具备了认识世界的能力。 
<p>　　在数的概念出现之后，就开始出现了数的计算。计算需要借助一定的工具来进行，人类最初的计算工具就是人类的双手，掰指头算数就是最早的计算方法。一个人天生有十个指头，因此十进制就成为人们最熟悉的进制计数法。</p><p>　　由于双手的局限性，人类开始学习用小木棍、石子等身外之物作为计算工具。在拉丁语中，“计算”的单词Calculus，其本意就是用于计算的小石子。随着文明的进步，人类学会了使用越来越多、越来越复杂的计算工具，计算方法也越来越高级。</p></td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="305"> </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9">
																		<p>
																				<a name="1">
																				</a>
																				<span class="biao">
																						<strong>17世纪以前<br />中国人的智慧之光</strong>
																				</span>
																		</p>
																		<p class="biao">计算工具的源头可以上溯至2000多年前的春秋战国时代，古代中国人发明的算筹是世界上最早的计算工具。在大约六、七百年前，中国人发明了更为方便的算盘，并一直沿用至今。许多人认为算盘是最早的数字计算机，而珠算口诀则是最早的体系化的算法。 </p>
																</td>
														</tr>
												</tbody>
										</table>
										<table height="1558" cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1379"> </td>
														</tr>
														<tr>
																<td width="23" height="125">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="125">
																		<p>
																				<a name="2">
																				</a>
																				<span class="biao">
																						<strong>16世纪-17世纪早期<br />西方的灵感</strong>
																				</span>
																		</p>
																		<p class="biao">计算尺的出现，开创了模拟计算的先河。从冈特开始，人们发明了多种类型的计算尺。直到20世纪中叶，计算尺才逐渐被袖珍计算器取代。</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="930">  </td>
														</tr>
														<tr>
																<td width="23">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9">
																		<p>
																				<a name="3">
																				</a>
																				<span class="biao">
																						<strong>17世纪中期-19世纪中期<br />先驱的探索：机械式计算机</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">从17世纪到19世纪长达两百多年的时间里，一批杰出的科学家相继进行了机械式计算机的研制，其中的代表人物有帕斯卡、莱布尼茨和巴贝奇。这一时期的计算机虽然构造和性能还非常简单，但是其中体现的许多原理和思想已经开始接近现代计算机。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1657">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="4">
																				</a>
																				<span class="biao">
																						<strong>19世纪后期<br />从机械到电的飞跃</strong>
																				</span>
																				<br />
																		</p>
																		<p>
																				<span class="biao">制表机采用电气控制技术取代纯机械装置，这是计算机发展中的第一次质变。以穿孔卡片记录数据，体现了现代软件的思想萌芽。制表机公司的成立，标志着计算机作为一个产业初具雏形。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1161">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="5">
																				</a>
																				<span class="biao">
																						<strong>20世纪早期<br />电子文明的曙光</strong>
																				</span>
																				<b>
																						<br />
																				</b>
																		</p>
																		<p>
																				<span class="biao">电子二极管和三极管在20世纪头几年相继问世。真空电子二极管的发明使人类打开了电子文明的大门，而电子三极管的发明及其放大原理的发现，标志着人类科技史进入了一个新的时代：电子时代。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
										<table cellspacing="0" cellpadding="10" width="237" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="1187">  </td>
														</tr>
														<tr>
																<td width="23" height="137">
																		<p> </p>
																</td>
																<td valign="top" bgcolor="#b6c5b9" height="137">
																		<p>
																				<a name="6">
																				</a>
																				<span class="biao">
																						<strong>20世纪三、四十年代<br />冲击最后的技术壁垒</strong>
																				</span>
																				<b>
																						<br />
																				</b>
																		</p>
																		<p>
																				<span class="biao">在这一时期，各国科学家对采用继电器的机电式计算机进行了大量的研制工作，为现代计算机的最终诞生积累了极为重要的经验。计算机也开始取得实质性应用价值，被用于军事、科学计算等领域。</span>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
								<td valign="top" width="61%">
										<table cellspacing="0" cellpadding="5" width="333" border="0">
												<tbody>
														<tr>
																<td colspan="2" height="50"> </td>
														</tr>
														<tr>
																<td width="29" rowspan="2">
																		<p> </p>
																</td>
																<td valign="top" width="284" height="144">
																		<img height="136" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-01.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />公元前3000年的古埃及人用结绳来记录土地面积和收获的谷物。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="165"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="186" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-02.gif" width="150" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />进制计数法有许多种，人们最常用的是十进制，而古代玛雅人则使用二十进制。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="255" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-03.gif" width="110" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />公元前2000年的美索不达米亚人用泥板计数，这块泥板上的楔形文字代表25。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="214" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-04.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>最古老的计算工具：算筹</b>
																				<br />我国春秋时期出现的算筹是世界上最古老的计算工具。计算的时候摆成纵式和横式两种数字，按照纵横相间的原则表示任何自然数，从而进行加、减、乘、除、开方以及其它的代数计算。负数出现后，算筹分红黑两种，红筹表示正数，黑筹表示负数。这种运算工具和运算方法，在当时世界上是独一无二的。 </p>
																		<p>据《汉书·律历志》记载：算筹是圆形竹棍，它长23.86厘米、横截面直径是0.23厘米。到公元六、七世纪的隋朝，算筹长度缩短，圆棍改成方的或扁的。根据文献记载，算筹除竹筹外，还有木筹、铁筹、玉筹和牙筹。 </p>
																		<p>
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="141" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-05.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>中国人发明算盘</b>
																				<br />随着计算技术的发展，在求解一些更复杂的数学问题时，算筹显得越来越不方便了。于是在大约六、七百年前，中国人发明了算盘，它结合了十进制计数法和一整套计算口诀并一直沿用至今，被许多人看作是最早的数字计算机。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="144"> </td>
																<td class="biao" valign="top" width="284" height="144">
																		<img height="141" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-06.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>算筹与圆周率</b>
																				<br />算筹为人类文明做出过巨大贡献，我国古代著名的数学家祖冲之，就是借助算筹计算出圆周率的值介于3.1415926和3.1415927之间；中国古代的天文学家也运用算筹，总结出了精密的天文历法。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="74" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-07.gif" width="200" />
																		<img height="62" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-08.gif" width="200" />
																		<img height="62" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-09.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>算盘的变化</b>
																				<br />明朝以后，算盘在世界各地流传开来，并出现了许多变种</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="62" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-10.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />我们熟悉的常用语“三下五除二”、“七上八下”等，就是起源于珠算口诀，这是最早的体系化算法。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="135"> </td>
																<td class="biao" valign="top" width="284" height="135">
																		<hr size="1" />
																		<img height="114" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-11.gif" width="100" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>达·芬奇</b>
																				<br />欧洲文艺复兴时期的伟人达·芬奇是一位旷世奇才，他在科学方面的造诣丝毫不亚于其艺术成就，他很早就提出过计算工具的设想。后人在达·芬奇的手稿中，发现了关于机械式计算工具设计方案的记录。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="99" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-12.gif" width="200" />
																				<img height="74" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-13.gif" width="200" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />后人根据达芬奇的手稿仿制出了机械式计算器。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="111" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-14.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>冈特计算尺</b>
																				<br />1621年，英国人冈特发明计算尺，这是世界上最早的模拟计算工具。17世纪的文献详细记载了冈特发明这种计算工具的过程。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="160" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-15.gif" width="132" />
																				<img height="98" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-16.gif" width="131" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>希克尔德的创意</b>
																				<br />德国科学家希克尔德被许多人认为是世界上真正的第一台计算机的发明人，后人在他的手稿中发现了他对计算机的设计草图和详尽的文字描述，并在1960年根据其方案成功仿制了一台机械式计算机。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="103" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-17.gif" width="152" />
																		<img height="103" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-18.gif" width="116" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>帕斯卡加法机</b>
																				<br />1642年，法国数学家、物理学家和思想家帕斯卡发明加法机，这是人类历史上第一台机械式计算机，其原理对后来的计算机械产生了持久的影响。</p>
																		<p>帕斯卡从加法机的成功中得出结论：人的某些思维过程与机械过程没有差别，因此可以设想用机械模拟人的思维活动。</p>
																		<p>1971年瑞士人沃斯把自己发明的高级语言命名为Pascal，以表达对帕斯卡的敬意。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="121"> </td>
																<td class="biao" valign="top" width="284" height="121">
																		<p>
																				<img height="93" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-19.gif" width="185" />
																				<img height="109" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-20.gif" width="81" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>莱布尼兹乘法机</b>
																				<br />1673年，德国数学家莱布尼兹发明乘法机，这是第一台可以运行完整的四则运算的计算机。莱布尼兹同时还提出了“可以用机械代替人进行繁琐重复的计算工作”的伟大思想，这一思想至今鼓舞着人们探求新的计算机。</p>
																		<p>莱布尼兹因独立发明微积分而与牛顿齐名，并被《不列颠百科全书》列为“西方文明最伟大的人之一”。<br />据记载，莱布尼兹曾把自己的乘法机复制品送给康熙皇帝。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="205" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-21.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>八卦</b>
																				<br />莱布尼兹认为，中国的八卦是最早的二进制计数法。在八卦图的启迪下，莱布尼兹系统地提出了二进制运算法则。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="219" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-22.gif" width="200" />
																		</p>
																		<p>
																				<img height="164" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-23.gif" width="103" />
																				<img height="164" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-24.gif" width="143" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>巴贝奇差分机</b>
																				<br />1822年，英国数学家巴贝奇发明差分机，专门用于航海和天文计算。这是最早采用寄存器来存储数据的计算机，体现了早期程序设计思想的萌芽。<br />第一台差分机从设计到制造完成，花费了整整十年。它可以处理3个5位数，计算精度达到6位小数。 </p>
																		<p>巴贝奇是一位伟大的天才，他因为远远超前于他的时代而注定要成为一位悲剧伟人。</p>
																		<p>巴贝奇分析机采用了三个具有现代意义的装置：保存数据的寄存器（齿轮式装置）；从寄存器取出数据进行运算的装置，并且机器的乘法以累次加法来实现；控制操作顺序、选择所需处理的数据以及输出结果的装置。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="137" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-25.gif" width="100" />
																		<img height="236" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-26.gif" width="132" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />赫尔曼·霍勒斯博士发明穿孔卡片，这是电脑软件的雏形。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="303" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-27.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>赫尔曼·霍勒斯制表机</b>
																				<br />1888年，美国人赫尔曼·霍勒斯发明了制表机，它采用穿孔卡片进行数据处理，并用电气控制技术取代了纯机械装置。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="136" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-28.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />1890年，美国人口普查全部采用了霍勒斯制表机。在1900年美国人口普查中，由于采用了制表机，全部统计处理工作只用了1年零7个月时间。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="157"> </td>
																<td class="biao" valign="top" width="284" height="157">
																		<p>
																				<img height="153" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-29.gif" width="100" />
																				<img height="91" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-30.gif" width="79" />
																				<img height="72" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-31.gif" width="87" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>从CTR到IBM</b>
																				<br />霍勒斯于1896年创立了制表机公司，1911年该公司并入CTR（计算制表记录）公司，这就是著名的IBM公司的前身。1924年，托马斯·沃森一世把CTR更名为IBM。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="370"> </td>
																<td class="biao" valign="top" width="284" height="370">
																		<hr size="1" />
																		<img height="141" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-32.gif" width="100" />
																		<img height="141" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-33.gif" width="127" />
																		<p>
																				<img height="201" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-34.gif" width="150" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>二极管</b>
																				<br />1904年，英国人弗莱明发明真空电子二极管。电子管的诞生，是人类电子文明的起点。</p>
																		<p>弗莱明真空二极管的发明得益于爱迪生发现的“爱迪生效应”。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="156" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-35.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>三极管</b>
																				<br />1906年，美国人德弗雷斯特发明电子三极管，并在研究中发现，三极管可以通过级联使放大倍数大增，这使得三极管的实用价值大大提高，从而促成了无线电通信技术的迅速发展。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="172" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-36.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />三极管的发明最初居然被指控为商业诈骗，并被法官判定为一个“毫无价值的玻璃管”。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="96" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-37.gif" width="156" />
																				<img height="159" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-38.gif" width="112" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />德弗雷斯特因发明三极管而被称为“无线电之父”。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29" height="152"> </td>
																<td class="biao" valign="top" width="284">
																		<hr size="1" />
																		<img height="129" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-39.gif" width="180" />
																		<img height="129" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-40.gif" width="86" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>朱斯的Z系列计算机</b>
																				<br />1938年，德国科学家朱斯制造出Z-1计算机，这是第一台采用二进制的计算机。在接下来的四年中，朱斯先后研制出采用继电器的Z-2、Z-3和Z-4。</p>
																		<p>Z-3使用了2600个继电器，它在1944年美军对柏林进行的空袭中被炸毁。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<img height="116" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-41.gif" width="200" />
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />
																				<b>“巨人”计算机</b>
																				<br />1943年，英国科学家研制成功第一台“巨人”计算机，专门用于破译德军密码。“巨人”算不上真正的数字电子计算机，但在继电器计算机与现代电子计算机之间起到了桥梁作用。</p>
																		<p>第一台“巨人”有1500个电子管，5个处理器并行工作，每个处理器每秒处理5000个字母。二战期间共有10台“巨人”在英军服役，平均每小时破译11份德军情报。</p>
																		<p> </p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="121" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-42.gif" width="100" />
																				<img height="121" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/1-43.gif" width="151" />
																		</p>
																</td>
														</tr>
														<tr>
																<td width="29"> </td>
																<td class="biao" valign="top" width="284">
																		<p>
																				<img height="15" src="file:///C:/Documents%20and%20Settings/dzu/My%20Documents/PC20th_files/arrow_up.gif" width="15" />艾肯研制MARK-1的灵感来自一个世纪以前巴贝奇留下的思想精华。</p>
																		<p>艾肯的MARK—I<br />1944年，美国科学家艾肯在IBM的支持下，研制成功机电式计算机MARK-I。这是世界上最早的通用型自动机电式计算机之一，它取消了齿轮传动装置，以穿孔纸带传送指令。</p>
																		<p>MARK-1外壳用钢和玻璃制成，长15米，高2.4米，自重31.5吨，使用了15万个元件和800公里电线，每分钟进行200次运算。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/Winux32/aggbug/17685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2007-01-16 15:22 <a href="http://www.cppblog.com/Winux32/archive/2007/01/16/17685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>名词解释：什么是RSS？[转载]</title><link>http://www.cppblog.com/Winux32/archive/2006/12/26/16860.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 26 Dec 2006 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2006/12/26/16860.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/16860.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2006/12/26/16860.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/16860.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/16860.html</trackback:ping><description><![CDATA[讨论与Blog相关的技术，不可不谈的就是RSS，这个缩写在英文中可以有几个源头，并被不同的技术团体做不同的解释。既可以是“Rich Site Summary”，或“RDF Site Summary”，也可以是“Really Simple Syndication”。为什么有这么多含义呢？这还要从RSS的一段今天也没有理清的关系说起。 
<p>　　今天肯定有人还记得IE 4刚刚推出来的时候有一个有趣的功能，那就是新闻频道。这个新闻频道的功能与Netscape推出的新闻频道是很相似的(当时Netscape还是市场上领先的浏览器)。为此Netscape 定义了一套描述新闻频道的语言，这就是RSS，只不过Netscape自当时起每况愈下，所以最终也没有发布一个正式的RSS规范(只发布了一个0.9版本)。而微软也在当时推出了支持自己IE的CDF(Channel Definition Format)数据规格，与RSS非常接近。微软试图用新闻频道的功能把“推”(Push)技术变成一个应用主流，并与Netscape抗衡。不过出乎预测的是，“推”技术自始至终没有找到合适的商业模型，而且伴随着其他各类网络特性的出现，也日益无法显现自身的优势。新闻频道在浏览器中的地位最终日暮西山，最后也在IE的后续版本中消失了。 </p><p>　　新闻频道的确进入了低谷，但是RSS并没有被业界人士所抛弃。过去两年，Blog从一个专业群体开始，逐步成为了网络上最热门的新话题。而RSS成为了描述Blog主题和更新信息的最基本方法。于是RSS这项技术被著名Blogger/Geek戴夫·温那(Dave Winner)的公司UserLand所接手，继续开发新的版本，以适应新的网络应用需要。新的网络应用就是Blog，因为戴夫·温那的努力，RSS升级到了0.91版，然后达到了0.92版，随后在各种Blog工具中得到了应用，并被众多的专业新闻站点所支持。在广泛的应用过程中，众多的专业人士认识到需要组织起来，把RSS发展成为一个通用的规范，并进一步标准化。一个联合小组根据W3C新一代的语义网技术RDF对RSS进行了重新定义，发布了RSS 1.0，并把RSS定义为“RDF Site Summary”。这项工作并没有与戴夫·温那进行有效的沟通，而戴夫则坚持在自己设想的方向上进一步开发RSS的后续版本，也并不承认RSS 1.0的有效性。RSS由此开始分化形成了RSS 0.9x/2.0和RSS 1.0两个阵营，也由此引起了在专业人群中的广泛争论。 </p><p>　　因为争论的存在，一直到今天，RSS 1.0还没有成为标准化组织的真正标准。而戴夫·温那却在2002年9月独自把RSS升级到了2.0版本，其中的定义完全是全新的模式，并没有任何RSS 1.0的影子。这引发了网络上进一步争议，究竟让一个越来越普及的数据格式成为一个开放的标准，还是被一家公司所定义和控制，成为了争议的焦点。戴夫·温那并没有为自己辩解，他的观点是RSS还需要进一步发展，需要专业人士更明确的定义，不过恐怕这种轻描淡写不能消除人们对RSS“被一家商业公司独占”的担心。 </p><p>　　前面的铺垫对用户来说也许没有什么太大的意义，可能更多人关心如何在自己的Blog增加RSS输出，这样可以让很多新闻聚合工具(例如CNBlog刚刚推荐的NewzCrawler)很容易找到你并自动获得你在Blog中的更新内容。 </p><p>　　它是什么：站点用来和其他站点之间共享内容的简易方式(也叫聚合内容)。 RSS使肵ML作为彼此共享内容的标准方式。 </p><p>　　它代表什么：Really Simple Syndication (或RDF Site Summary，RDF站点摘要) </p><p>　　例如：一些免费的软件能够让你阅读那些RSS使能的站点，比如 NewsIsFree 和 Amphetadesk。 </p><p>　　它有什么用处：让别人容易的发现你已经更新了你的站点，让人们很容易的追踪他们阅读的所有weblogs。 </p><p>　　原文出处：博客中国</p><img src ="http://www.cppblog.com/Winux32/aggbug/16860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2006-12-26 10:12 <a href="http://www.cppblog.com/Winux32/archive/2006/12/26/16860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2007年互联网发展趋势预测：RSS将成为主流[转载]</title><link>http://www.cppblog.com/Winux32/archive/2006/12/26/16859.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 26 Dec 2006 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2006/12/26/16859.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/16859.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2006/12/26/16859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/16859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/16859.html</trackback:ping><description><![CDATA[2006.12.25  来自：北方网<br /><font face="Arial">2006年是<font color="#ff0000">社交网站</font>高速发展的一年，2007年又将会怎样呢？下面是理查德·麦克马努斯(Richard MacManus)、伊卜拉希姆·埃兹(Ebrahim Ezzy)、埃姆雷·索古鲁(Emre Sokull u)、阿列克斯·埃斯科尔德(Alex Iskold)、以及鲁迪·德维利(Rudy De Waele)等<font color="#009900">互联网专家</font>的看法：<br />　　<u><font color="#0066ff">RSS，结构数据</font></u>：<br />　　-RSS将于2007年迅速发展，并成为主流。RSS测试版(Ajax版本)推出之后，不仅将获得微软下一代操作系统Vista的支持，还将完全整合在Yahoo Mail之中。我们预计Google也将于2007年进行一些RSS试验，特别是分类广告服务Goolge Base，因为它已经采用了类似于RSS的Gata。除此之外，2007年将会出现更多基于RSS的创新服务，例如Techmeme RSS广告。<br />　　-结构数据将成为2007年的主要潮流之一。这一点不容置疑，但值得关注的是，微格式(microformats)未来的命运将会怎样呢？微格式是网络社区针对结构数据制定的开放标准，但目前看来，Google正在推广自己的结构数据标准，而完全无视微格式的存在。尽管微软和雅虎已经表达了对微格式的支持，但这能够阻止Google吗？<br />　　- Widgets将继续保持强劲的上升势头。2006年，得益于博客和MySpace等社交网站的兴起，Widgets的发展势头十分迅猛，这一趋势有望延续到2007年。未来将会出现更多类似于MyBlogLog的个人网站，但Widgets也将用于电子商务和多媒体。<br />　　<u><font color="#0066ff">企业应用</font></u>：<br />　　-网络Office将更加普及。Google和微软在这一领域的竞争特别值得关注，与此同时，一些新兴公司(Zoho、Zimbra以及ThinkFree等等)将继续推出创新产品，大公司可能会对它们开展收购。<br />　　-企业应用定制化的潮流将以网络办公应用和协作系统的形式，渗透到企业IT的各个领域。可以帮助企业提高生产效率、降低运营支出的虚拟解决方案将受到广泛欢迎，当然也可能会引发争议(例如，企业博客可能会泄漏敏感信息)。<br />　　<u><font color="#0066ff">网络开发</font></u>：<br />　　-富互联网应用(RIA)将成为2007年的重要力量(网络/桌面混合应用是今年的主题)。Adobe的Apollo平台将于2007年正式推出，微软也不会袖手旁观，将推出Windows Presentation Foundation。同样在这一领域，Laszlo及其开放源代码OpenLaszlo平台也将吸引不少人的关注。2007年，将会有更多同时利用桌面和网络优势的新应用出现，它们可以提供基于浏览器的应用所无法实现的功能。<br />　　-Google将继续推动基于浏览器的应用向前发展。众所周知，Ajax有一定的局限性。因此，很多人开始考虑用其它技术取代Ajax。与此同时，2007年将出现更多使用矢量图形(VML/SVG)结合AJAX的应用。<br />　　-语义网络产品将于2007年出现。毫无疑问，在RadarNetworks和Metaweb等公司的推动下，语义网络的时代即将到来。<br />　　-亚马逊有望于2007年推出更多重量级网络服务，为将来开发基于亚马逊网络服务的操作系统打下基础。我们认为，Google等其它公司也可能会开发大量类似的网络服务。例如，Google可能会开发一款新服务，力争赶超亚马逊的S3-EC2服务。而不论Google去哪里，微软总是如影随形。<br />　　<u><font color="#0066ff">搜索和网络广告</font></u><br />　　-网络广告市场将发生巨大的变化。Google AdSense将面临激烈的竞争，主要来自于微软的MSN AdCenter，以及雅虎的广告平台。<br />　　-将会有新网络广告模式出现。在现有网络广告模式中，无论是按点击付费(CPC)，还是按业绩付费(PPC)，都存在着一定的局限性，因此市场需要一种更好的模式出现。我们预计2007年将会出现新广告模式。<br />　　-搜索2.0和垂直搜索引擎将取得长足进步。当然，这并不意味着Google将走向衰退，该公司必然会发起反击。Google Code和Google Health就是对垂直搜索的回应。值得注意的是，Google正在朝语义搜索引擎的方向发展。例如，如果你在Google搜索引擎中输入一家公司的名称，返回的第一个搜索结果不仅包括这家公司的主页，还有从该网站提取的一些语义信息。从SearchMash(Google的测试搜索网站)来看，Google还计划推出更多功能。<br />　　<font color="#0066ff"><u>微软与Google之争</u></font><br />　　-得益于Vista的普及，以及正式版服务的推出(例如Windows Live Mail将取代Hotmail)，微软Windows Live服务将于2007年飞速发展。<br />　　-WebOS/GoogleOS：为了更好地应对来自Vsita和Windows Live的威胁，Google可能会推出某种形式的GoogleOS。这一预测也许存在争议，但从理论上讲，如果Vista的默认服务(Live.com)给Google带来巨大的压力，后者可能会针对Linux进行优化。<br />　　-开放源代码桌面将于2007年继续稳步发展。红帽和Novell都将推出新版本Linux。如果Linux中加入更多3D效果、KDE4和ALGLX技术，市场竞争力将大大提高。但是，Linux能同Vista，以及即将推出的网络操作系统分庭抗礼吗？<br />　　<font color="#0066ff"><u>浏览器</u></font>：<br />　　-第二次浏览器大战。2007年，IE7同FireFox(也许要联合Flock、Opera和Maxthon)在浏览器市场的竞争将更加激烈。也许我们将看到Google推出自己的浏览器，或者继续以Firefox为主。后一种方案的可能性更大，因为如果Google在操作系统和浏览器市场同微软直接冲突，将面临巨大的风险。<br />　　- WebKits将于2007年迅速普及。Adobe的Apollo平台就基于WebKit，这项技术可以确保不同浏览器的Safari兼容性。我们认为，Linux/KDE中的Konqueror浏览器将“抛弃”KHTML引擎，转而采用WebKit。因此，我们预计Safari兼容性将于2007年得到大幅度提升。<br />　　<u><font color="#0066ff">多媒体</font></u>：<br />　　-得益于Brightcove等新产品的推出，以及Google视频服务(YouTube/Google Video)的发展，互联网电视将于2007年取得长足进步。我们预计将会有更多交互式电视(例如iTV)出现。<br />　　-IPTV技术将于2007年迅速普及，Bittorrent将在网络视频领域扮演非常重要的角色。<br />　　-P2P：在Azureus和BitTorrent的带动下，P2P领域已经获得了约3000万美元投资，为2007年的发展打下了坚实的基础。毫无疑问，2007年对于P2P而言将是成功的一年。未来将有更多基于P2P界面的网站出现，我们可以更加容易地使用P2P。Bittorrent已经成为很多连接软件的一个重要组成部分，例如IPTV客户端DemocracyPlayer就内置了bittorrent。Bittorrent将于2007年同更多新应用整合在一起。<br />　　-虚拟世界：随着越来越多用户和企业的介入，SecondLife将成为营销、推广和社交网络的一个重要平台。我们认为，SecondLife将继续向全球扩张。目前，我们可以在大多数超市买到Habbo和Secondlife卡，这一趋势将蔓延至世界其它地区。简而言之，虚拟世界将于2007年成为真实世界的一部分。<br />　　-虚拟货币：Paypal为我们提供了电子支付的商业模式，未来我们还将看到更多虚拟货币，包括SecondLife LindeX和Microsoft points等等。<br />　　<u><font color="#0066ff">消费应用</font></u>：<br />　　-网络 房地产市场将于2007年飞速发展。<br />　　-免费消费网络应用仍然需要寻找商业模式。<br />　　-由于社交网络2006年增长势头迅猛，我们担心用户花费大量时间在互联网上，可能会给他们的社交生活带来负面影响，而这种影响将于2007年体现出来。社交网络难道是一种反社交工具吗？与此同时，社交网络将变得更加开发，数据便携将成为现实，尽管MySpace对此不感兴趣。<br />　　<u><font color="#0066ff">国际互联网</font></u>：<br />　　-国际互联网最终将在主流媒体中获得应有的地位。中国互联网市场吸引了各方面的高度关注，但分析师认为，这一市场仍然处于早期阶段，总产值相对而言还不大。<br />　　-“每个孩子一台笔记本计划”：这一计划引发了业界的广泛争议，但无论如何，它将推动瘦客户端和Linux成为主流。以网络Office为例，它对无力负担微软Office软件的用户具有不小的吸引力。<br />　　-宽带将继续发展：法国的光纤连接(Fiber Connections)就是一个很好的例子，全球将会出现更多旨在提高互联网连接速度的类似项目。从某种意义上讲，宽带革命孕育了Web2.0、Google和Web应用，因此宽带未来的发展趋势非常值得关注。<br />　　<u><font color="#0066ff">手机互联网</font></u>：<br />　　-VoIP将成为真正的热门领域。Skype和其它大量新兴公司将在这一领域展开竞争，并可能会给传统电信行业带来巨大的冲击。<br />　　-手机互联网有望成为2007年的一件大事，这在中国、韩国和日本毫无疑问，在美国、新西兰和澳大利亚等国家也有可能。受此影响，Smartpox等在线/离线移动技术可能会在西方普及(这些技术已经在亚洲广泛应用)。<br />　　-手机将于2007年成为一个更大的开发和广告平台。<br />　　- 网络电话市场值得关注，例如有传闻称 苹果将推出iPhone，Google将推出Google Phone。<br />　　鲁迪·德维利还特别列出了2007年手机互联网的十大发展趋势：<br />　　-资费将降至更多人能接受的水平。<br />　　-手机中将出现更多用户生成内容；将有更多用户使用手机访问Web/Mobile 2.0服务，例如播客和RSS种子等。<br />　　-主要媒体公司将进入移动领域：MySpace、YouTube、MTV、以及很多媒体公司都将进入移动领域，从而用户可以通过手机上传图片和视频，以及创建或消费内容。<br />　　-移动搜索：主要搜索服务公司将在移动搜索市场展开激烈的争夺。<br />　　-手机广告：这一市场将以惊人的速度增长。<br />　　-QR码将进入零售市场。<br />　　-移动图像识别将用于营销。<br />　　-手机内存卡将更多地用于交换音乐/视频文件。<br />　　-多网络下载热点将进入城市，从而用户可以通过wi-fi、wimax、蓝牙和NFC等多种技术实现手机下载和互联网接入。<br />　　-“Smart Client”解决方案将迅速兴起，主要用于内容和应用功能在移动设备上的整合。</font><img src ="http://www.cppblog.com/Winux32/aggbug/16859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2006-12-26 10:11 <a href="http://www.cppblog.com/Winux32/archive/2006/12/26/16859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java开发技术十年的回顾与展望[转载]</title><link>http://www.cppblog.com/Winux32/archive/2006/12/26/16853.html</link><dc:creator>Charles</dc:creator><author>Charles</author><pubDate>Tue, 26 Dec 2006 01:02:00 GMT</pubDate><guid>http://www.cppblog.com/Winux32/archive/2006/12/26/16853.html</guid><wfw:comment>http://www.cppblog.com/Winux32/comments/16853.html</wfw:comment><comments>http://www.cppblog.com/Winux32/archive/2006/12/26/16853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Winux32/comments/commentRss/16853.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Winux32/services/trackbacks/16853.html</trackback:ping><description><![CDATA[2006.12.19  来自：luap<br />从JDK诞生到现在已经有11年的时间了。沧海桑田一瞬间。转眼11年过去了，JDK已经发布了<font color="#ff0000">6个版本</font>。在这11年里诞生了无数和Java相关的技术和标准。现在让我们进入时间隧道，重新回到1995年，再来回顾一下Java的发展轨迹和历史变迁。 <br /><br />　　<strong>一、 JDK前传</strong><br /><br />　　在这个世界上，熟悉Java历史的人非常多，如果要问一个人Java是从哪年诞生的，也许大多数人都会回答是1995年（这个非常好记，因为微软的Windows95也是在这一年发布的）。但事实上Java早在上个世纪90年代初就开始酝酿了。 <br /><br />　　1991年4月，Sun公司的James Gosling领导的绿色计划(Green Project)开始着力发展一种分布式系统结构，使其能够在各种消费性电子产品上运行。而Green项目组的成员一开始使用C++语言来完成这个项目，由于Green项目组的成员都具有C++背景，所以他们首先把目光锁定了C++编译器，Gosling首先改写了C++编译器，但很快他就感到C++的很多不足，需要研发一种新的语言Java来替代它，一杯飘香的咖啡成为了它的标志。 <br /><br />　　在17 个月后，整个系统完成了，这个系统是更注重机顶盒式的操作系统，不过在当时市场不成熟的情况下，他们的项目没有获得成功，但Java语言却得到了Sun总裁McNealy的赏识。 <br />　<br />　　直至 1994年下半年，由于Internet的迅猛发展和环球信息网 WWW的快速增长，<font color="#ff0000">第一个全球信息网络浏览器Mosaic</font>诞生了；此时，工业界对适合在网络异构环境下使用的语言有一种非常急迫的需求；Games Gosling决定改变绿色计划的发展方向，他们对Oak进行了小规模的改造，就这样，<font color="#ff0000">Java在1995年的3月23日诞生</font>了！Java的诞生标志着互联网时代的开始，它能够被应用在全球信息网络的平台上编写互动性及强的Applet程序，而1995年的Applet无疑能给人们无穷的视觉和脑力震荡。我们姑且将Java的这段历史称为Java前传吧。 <br /><br />　　其实Java的诞生颇有那么一股“有心栽花花不开，无心插柳柳成阴”的味道。就象当年Unix和它的前身MULTICS系统一样。<br /><br /><br /><img onclick="if(this.width&gt;screen.width-461) window.open('../../.././1123517557/Fid_46/46_4677.jpg');" alt="" src="http://bbs.lupaworld.com/1123517557/Fid_46/46_4677.jpg" onload="if(this.width&gt;screen.width-460)this.width=screen.width-460;" border="0" /><br /><br />　　图1 Java创始人 James Gosling博士<br /><br />　　<strong>二、JDK的幼年时期(1995～1998)</strong><br /><br />　　Sun继Green项目后又经过了几年的研究，终于在1995年5月23日在SunWorld'95上正式发布Java和HotJava浏览器。在同年，有很多公司先后获得了Java许可证，如Netscape在1995年8月，Oracle在1995年10月分别获得了Java许可证。Sun在1995年发布第一个Java版本后，于1996年1月宣布成立新的业务部门──JavaSoft部，这个部分主要负责开发、销售并支持基于Java技术的产品，由AlanBaratz先生任总裁。 <br /><br />　　在1995年Sun虽然推出了Java，但这只是一种语言，而要想开发复杂的应用程序，必须要有一个的强大的开发库支持还行。因此，Sun在1996年1月23日发布了JDK1.0。这个版本包括了两部分：<font color="#ff0000">运行环境（即JRE）和开发环境(即JDK)。</font>在运行环境中包括了核心API、集成API，用户界面API，发布技术，Java虚拟机(JVM)五个部分。而开发环境还包括了编译Java程序的编译器（即javac）。在JDK1.0时代，JDK除了AWT（一种用于开发图形用户界面的API）外，其它的库并不完整。 <br /><br />　　Sun在推出JDK1.0后，紧跟着，Sun在1997年2月18日发布了JDK1.1。JDK1.1相对于JDK1.0最大的改进就是为JVM增加了<font color="#ff0000">JIT(即时编译)</font>编译器。JIT和传统的编译器不同，传统的编译器是编译一条，运行完后再将其扔掉，而JIT会将经常用到的指令保存在内容中，在下次调用时就不需要再编译了。这样JDK在效率上有了非常大的提升。 <br /><br />　　Sun在推出JDK1.1后，接着又推出了数个JDK1.x版本。自从Sun推出Java后，JDK的下载量不断彪升，在1997年，JDK的下载量突破了220,000，而在1998年，JDK的下载量已经超过了2,000,000。 <br /><br />　　虽然在1998年之前，Java被众多的软件企业所采用，但由于当时硬件环境和JVM的技术原因，它的应用却很有限。当时Java主要只使用在前端的Applet以及一些移动设备中。然而这并不等于Java的应用只限于这些领域。在<font color="#ff0000">1998年</font>是Java开始迅猛发展的一年。在这一年中Sun发布了<font color="#ff0000">JSP/Servlet</font>、EJB规范以及将Java分成了<font color="#ff0000">J2EE、J2SE和J2ME</font>。标志着Java已经吹响了向企业、桌面和移动3个领域进军的号角。<br /><br />　　<strong>三、JDK的青少年时期(1998～2004)</strong><br /><br />　　到1998年，Java已经走过了3个年头。从JDK1.0到JDK1.1.8。JDK1.x经过了9个小版本的发展，已经初具规模。至此，它已经走出了摇篮，可以去独闯世界了。 <br /><br />　　在1998年12月4日。Sun发布了Java的历史上最重要的一个JDK版本：JDK1.2。这个版本标志着Java已经进入Java2时代。这个时期也是Java飞速发展的时期。 <br /><br />　　在Java2时代Sun对Java进行了很多革命性的变化 ，而这些革命性的变化一直沿用到现在，对Java的发展形成了深远的影响。 <br /><br />　　JDK1.2自从被分成了J2EE、J2SE和J2ME三大块，得到了市场的强烈反响。不仅如此，JDK1.2还对它的API分成了三大类。 <br /><br />　　核心API <br />　　由Sun公司制定的基本的API，所有的Java平台都应该提供。这就是我们平常所说的Java核心类库。 <br /><br />　　可选API <br />　　这是Sun为JDK提供的扩充API，这些API因平台的不同而不同。 <br />?<br />　　特殊API <br />　　用于满足特殊要求的API。如用于JCA和JCE的第三方加密类库。 <br /><br />　　Java2除了上述的一些改进外，还增加了很多新的特性。其中最吸引眼球的当属Swing了。<font color="#ff0000">Swing</font>是Java的另一个图形库。它不但有各式各样先进的组件，而且连组件风格都可抽换。在Swing出现后，很快就抢了AWT的风头。但Swing并不是为取代AWT而存在的，事实上Swing是建立在AWT之上的。就象<font color="#ff0000">JFace</font>是建立在<font color="#ff0000">SWT</font>之上一样。另外Java2还在多线程、集合类和非同步类上做了大量的改进。 <br /><br />　　从JDK1.2开始，Sun以平均2年一个版本的速度推出新的JDK。在<font color="#ff0000">2000</font>年5月8日。Sun对JDK1.2进行了重大升级。推出了<font color="#ff0000">JDK1.3</font>。 <br /><br />　　Sun在JDK1.3中同样进行了大量的改进，主要表现在一些类库上（如数学运算、新的Timer API等）、在JNDI接口方面增加了一些DNS的支持、增加了JNI的支持，这使得Java可以访问本地资源了、支持XML以及使用新的Hotspot虚拟机代替了传统的虚拟机。 <br /><br />　　在JDK1.3时代，相应的应用程序服务器也得到了广泛的应用，如第一个稳定版本Tomcat3.x在这一时期得到了广泛的应用，WebLogic等商业<font color="#ff0000">应用服务器</font>也渐渐被接受。 <br /><br />　　时间如水、生命如歌。转眼到了<font color="#ff0000">2002年</font>。Sun在这一年的2月13日发布了<font color="#ff0000">JDK历史上最为成熟的版本：JDK1.4</font>。在进入21世纪以来，曾经在.NET平台和Java平台之间发生了一次声势浩大的孰优孰劣的论战，Java的主要问题就是性能。 <br /><br />　　因此，这次Sun将主要精力放到了Java的性能上。在JDK1.4中，Sun放言要对Hotspot虚拟机的锁机制进行了改进，使JDK1.4的性能有了质的飞跃。同时由于Compaq、Fujitsu、 SAS、 Symbian、 IBM等公司的参与，使JDK1.4成为发展最快的一个JDK版本。到JDK1.4为止，我们已经可以使用Java实现大多数的应用了。<br /><br />　　<strong>四、JDK的壮年时期(2004～至今)</strong><br /><br />　　虽然从JDK1.4开始，Java的性能有了显著的提高，但Java又面临着另一个问题，那就是复杂。 <br /><br />　　虽然Java是纯面向对象语言，但它对一些高级的语言特性（如泛型、增强的for语句）并不支持。而且和Java相关的技术，如EJB2.x，也由于它们的复杂而很少有人问津。也许是Sun意识到了这一点。因此，在<font color="#ff0000">2004年</font>10月，Sun发布了我们期待已久的版本：<font color="#ff0000">JDK1.5</font>，同时，Sun将<font color="#ff0000">JDK1.5改名为J2SE5.0</font>。和JDK1.4不同，<font color="#009900">JDK1.4的主题是性能，而J2SE5.0的主题是易用</font>。Sun之所以将版本号1.5改为5.0，就是预示着J2SE5.0较以前的J2SE版本有着很大的改过。 <br /><br />　　Sun不仅为J2SE5.0增加了诸如泛型、增强的for语句、可变数目参数、注释(Annotations)、自动拆箱（unboxing）和装箱等功能，同时，也更新的企业级规范，如通过注释等新特性改善了EJB的复杂性，并推出了EJB3.0规范。同时又针对JSP的前端界面设计而推出了JSF。这个JSF类似于ASP.NET的服务端控件。通过它可以很快地建立起复杂的JSP界面。 <br /><br />　　到今年年底Sun也再接再厉地推出了J2SE6.0的测试版，预计在2007年初将推出它的正式版。 <br /><br />　　正象J2SE6.0的开发代号“野马（Mustang）”一样，我们已经隐约听到了野马的嘶鸣。据Sun发言人透露，J2SE6.0不仅在性能、易用性方面得到了前所未有的提高，而且还提供了如脚本、全新的API（Swing和AWT等API已经被更新）的支持。而且J2SE6.0是专为Vista而设计的，它在Vista上将会拥有更好的性能。在推出J2SE6.0的同时，J2SE7.0项目也已经启动。 <br /><br />　　在Java发展的十几年的时间里，经历了无数的风风雨雨。现在Java已经成为一种相当成熟的语言了。在这10年的发展中，Java平台吸引了数百万的开发者，在网络计算遍及全球的今天，更是有20亿台设备使用了Java技术。作为Java技术的基础，J2SE功不可没，让我们期望J2SE伴随Java平台一路走好！<br /><br />　　<strong>五、JDK各版的发布时间表 </strong><br /><br />  到现在为止我们已经重新走了一遍Java的历史轨迹。在这一部分，为了有一个总体的认识，让我们来看一看Java发展的时间表。 （版本号 名称 中文名 发布日期） <br /><br />JDK 1.1.4 <br />Sparkler <br />宝石 <br />1997-09-12 <br /><br />JDK 1.1.5 <br />Pumpkin <br />南瓜 <br />1997-12-13 <br /><br />JDK 1.1.6 <br />Abigail <br />阿比盖尔--女子名 <br />1998-04-24 <br /><br />JDK 1.1.7 <br />Brutus<br />布鲁图--古罗马政治家和将军 <br />1998-09-28 <br /><br />JDK 1.1.8 <br />Chelsea <br />切尔西--城市名 <br />1999-04-08 <br /><br />J2SE 1.2 <br />Playground <br />运动场 <br />1998-12-04 <br /><br />J2SE 1.2.1 <br />none<br />无<br />1999-03-30 <br /><br />J2SE 1.2.2 <br />Cricket<br />蟋蟀<br />1999-07-08 <br /><br />J2SE 1.3 <br />Kestrel <br />美洲红隼 <br />2000-05-08 <br /><br />J2SE 1.3.1 <br />Ladybird <br />瓢虫 <br />2001-05-17 <br /><br />J2SE 1.4.0 <br />Merlin <br />灰背隼 <br />2002-02-13 <br /><br />J2SE 1.4.1 <br />grasshopper <br />蚱蜢 <br />2002-09-16 <br /><br />J2SE 1.4.2 <br />Mantis <br />螳螂 <br />2003-06-26 <br /><br />J2SE 5.0 (1.5.0) <br />Tiger <br />老虎 <br />2004-10 <br /><br />J2SE 6.0 (Beta) <br />Mustang <br />野马 <br />2006-04 <br /><br />　　从这个表中我们可以看出一个非常有意思的现象，就是JDK的每一个版本号都使用一个开发代号表示（就是表中的中文名）。而且从JDK1.2.2开始,主要版本(如1.3,1.4,5.0)都是以鸟类或哺乳动物来命名的. 而它们的bug修正版本(如1.2.2,1.3.1,1.4.2)都是以昆虫命名的。<br /><br />　　<strong>六、Java的未来10年</strong><br /><br />　　在2005年的Java One开发者大会上，James Gosling作了题为“Java技术下一个10年贡献”的演讲。谈到未来Java的发展时，James Gosling提到了有关Java软件的性能和复杂性问题。鉴于许多机器运行着大量进程的实际情况，人们对线程模型投以越来越多的关注。 <br /><br />　　随着人们对桌面应用的要求越来越高，系统将变得越来越复杂。他指出： “从工程的角度来看，未来10年内我们所面临的最大挑战就是复杂性问题，” James Gosling说， “目前，我们开展了许多工作以解决应用编程接口、语言以及工具中所涉及的复杂性问题。在工具和用户界面(UI)中都会遇到复杂性问题，Java技术设计人员必须处理好大小尺寸调整和国际化的问题。” <br /><br />　　在这次大会上，James Gosling还同Java技术先驱，现任Kleiner, Perkins Caulfield and Byers合伙人的Bill Joy先生，Sun公司首席科学家John Gage先生，未来研究所主任Paul Saffo先生，Sun杰出工程师Guy Steele先生以及Applied Mindes公司主席及首席技术官Danny Hillis先生等一起探讨了讨论Java语言的过去和未来发展情况。 <br /><br />　　他们认为，Java技术提高了计算的“流动性”，就如同货币的发明提高了商品的流动性一样。无所不在的网络丰富了每个人的信息，就如同可以兑换的货币产生了财富一样。由于从前的网络是很慢的，所以计算被束缚在特定的计算机上，而这种情况将一去不复返了。 <br /><br />　　目前，全球Java开发人员已经超过450万，而与之相对应的是Java社区充满活力和创新精神，这正是Java下一个10年更加繁荣的保障。为了保持Java的增长和推进Java社区的参与, Sun在Java One开发者大会上宣布开放Java核心源代码，以鼓励更多的人参与到社团活动中来，这是Sun为推进社团发展和维护Java技术兼容性而迈出的重要一步。 <br /><br />　　Sun公司总裁兼首席运营官Jonathan Schwartz先生指出，来自Java社团和IBM等全球技术合作伙伴两方面的支持，乃是Java技术在创新和社会进步上继续发挥重要作用的强有力的标志。技术开放和社团建设降低了技术应用的壁垒，其结果是为参与和增长创造了更多的商机，这就形成了价值上千亿美元的Java产业。 <br /><br />　　有很多人认为Java开源后，在众多开发人员的参与之下，Java会变得更加强大。随着Java和IT业界的关系变得更加紧密，Sun公司也将更容易卖出自己兼容Java良好的WEB服务器和操作系统。这个举动将会给软件开发群体带来新的活力，改善Sun公司的公众形象，并同时证明Sun可以成为一个开源社会的“良民”。 <br /><br />　　随着Java的开源，Java的未来似乎变得更加明朗。在未来，Java的应用范围有可能变得更广。Sun董事长麦克里尼在2006年的JavaOne会议上说，“全球有3/4的人还不能接入Internet，这对Java技术伙伴来说是一个巨大的经济机会。瘦客户机、微小的传感器以及其它Java驱动的小装置，可以帮助我们改善人们的生活。他希望Java社区通过他们的工作能够弥合数字鸿沟”。 <br /><br />　　Sun认为，数字媒体将是Java的下一个重点市场，同时，教育和健康将是未来Java发展过程中的两大重点应用领域。但愿Java的未来真能象Sun宣称的那样，成为我们未来生活的一部分。<br /><img src ="http://www.cppblog.com/Winux32/aggbug/16853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Winux32/" target="_blank">Charles</a> 2006-12-26 09:02 <a href="http://www.cppblog.com/Winux32/archive/2006/12/26/16853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>