五三记 中关村的水啊深又深
又是“五一”,这是我在北京度过的第一个劳动节,三天假期。
本打算去“家*乐*福”看看热闹,正好有事情,没去成。等到有空了,在网上
搜索“家*乐*福”惊奇的发现无论是baidu还是google都表示“这个东西不存在”。汗。
缩短关键字绕过去,找到某人的blog,似乎什么都没发生。想必也是真的没有发生
什么吧,大家还是相应了xxx的号召,度过了一个平和安详的劳动节。
3号,被隔壁装修的电钻吵醒。起来准备上街。天色昏暗,一眼望去,竟然有黄昏
的错觉,天,非常严肃的阴沉着。带伞,外套。逛街去了~
先去银行,开通可以支付的网上银行,交水煤气费会省事许多,到了北大北门只见
上面挂着横幅“庆祝北大建校110周年”。有很多人在照相,白天照出夜景效果。我拿出
手机拍了张,回来一看:果真是夜晚的效果,除了灯泡耀出的光点,其余部分一片漆黑。
回来baidu一下,“北京大学创建于1898年”,历史真的蛮长的,同西南交大有得一拼。
清华建校于1928年,原来以为他们是一起建立的。现在知道北大是清华他爹那辈的了。
天色越发阴沉,仿佛晚上七八点。路上的车都打开了前灯,楼中也都开了灯。
走着走着,我头顶一闪,心中一紧,不由得快“走”了起来。虽然江湖传闻,雷公雷母
只打坏人,但是,没准有打歪的时候。一阵小跑,穿过马路,翻越护栏,冲进了工商
银行。刚进门,伴随着巨大的雷声,外面的雨下起来了。
这家银行位于中关村图书大厦附近,周末人很少,莫非是因为附近没有住宅区?
门口牌子上提示,您可能需要等待20分钟,但是排号大约只有2分钟就到了。我要开户,
实践证明,银行之间关于网上银行的规定差别还是挺大的。比如,招商银行,只容许
开设一个网上银行账号,其余的无论你是在什么地方办的账号只能挂在这个账号
下面。我去开户的时候,对方突然问我以前是不是开设过账号?我想了一下,敢情
1999年在学校的时候开过,里面还有50元,卡还在我手中,密码已经忘记了很多年。
工商银行,你可以开多个。比如,我在昆山开过一个网上银行,现在北京又可以开一个。
刚开始服务小姐不知道,本打算将昆山账号帮我注销掉。后来才发现可以同时开设2个的。
之后我又去中关村图书大厦转了一圈,书非常多,办个会员卡就可以打8折,和网上
购书差别不大,最主要是网上购书配送总是瓶颈。转了2个多小时。相中了几本书,用手机
拍下封皮,等以后有时间有精力再来买。我现在最大的问题是没有时间和精力来看书。
床上一本《联想风云》,已经翻看了个把星期,竟然还没有看完,惭愧之极。
中午吃的麦当劳,注意到他的门都是从里面向外推的,后来又光顾了一下肯德基
(不是吃东西)发现它的门也是这样的。不知道其他的麦肯店是不是也是这样的呢?
吃麦当劳,点了一份套餐,装可乐的是非常夸张的带吸管的塑料杯。端的时候,服务员
特地提醒,请用双手,容易翻... ...等我坐下了,边上来了几个学生就给我表演了一下
单手拿托盘,他们的杯子哗的一下翻了~ 水淹七军。
顶风冒雨,打算去买个小灵通,公司晚上经常开电话会议,只有固定电话或者小灵通
接入才是免费的,而我的住地没有固定电话,一般是在楼下的IC卡机器上拨打。拨打免费,
但是,深更半夜,一个精壮的男人,胯下红色的自行车,占着电话机一言不发,一听就是
1个小时,难免招来怀疑的目光。
海龙,鼎好门口聚集着很多拉客的人,他们用“秃鹫”的眼神打量着每一个过往者。
口中念到,数码相机看一下,笔记本电脑看一下。有时候还会拉你,让人很不舒服。据说
他们给拉上一位客人到某个摊位,就会有几十元的提成。转了半天,智能手机很多,黑莓
手机很多,小灵通没有。
转出去,准备到对面的科贸看看。过了马路,对面有一家华信通电讯,店面挺大,看起
来很正规。进去问了一下价格,感觉不贵,就在那里买了部ZTE V190,花了399,又买了张
充值卡。回来上网一查,这部小灵通报价在100-150,被人宰了。更不幸的是,我发现
将小灵通的SIM卡,放在公司的小灵通上竟然也可以用。早知道买个号码就可以了。
总结:中关村水很深,到哪里买东西最好现在网上查询好。然后,进去只买你查好的那个
东西,其余不计。唉,这次是花钱买个教训吧。
作者: ziv2013
[April , 23, 2008] 三无产品:管理小故事
三无产品:管理小故事
三无产品:管理小故事 最近又看余世维先生的管理讲座,发现他基本上不用那种管理小故事来说明问题了。许多年前, 他的管理讲座中有很多小故事,比如日本人参观北洋水师的定远号,伸手一摸发现炮管里面灰很大, 必定平常疏于打扫,于是断定舰队没有战斗力;还有镇远在船尾晾衣服… … 上班4年,每月的早会都会有一个台干来“分享管理小故事”。我们的喇叭通常只认女人,尖锐的 声音很容易从中播出,而男人的声音听起来多像狗叫。偶然有几个能让人听得清楚的男人讲述的管理 小故事必定是“从频谱功率上来说,高音部分功率谱密度较大”。因此,几年下来还记得的小故事不多, 有一个是卖鞋的去非洲市场调查,悲观的人报告那边的人没有穿鞋的习惯,所以我们没有市场;乐观的 人调查结果是,那边市场很大,大家都光脚… …讲这个故事的时候,我一直在疑心话锋一转会讲应该 先给当地的医生卖钉子,再买治疗脚伤的药品和工具,最后卖鞋子—-这样的做法称为营销(一次我去 测试组转悠,有一个dd在复习准备考试,其中的一道填空题是“营销的目的是创造需求”)。还有一个 有点印象的故事是动物园的斑马经常跑出来,于是管理部门不断加高围栏,结果斑马还是能跑出来。后来 斑马和邻居长颈鹿聊天说“如果他们继续忘记锁门,围栏再高我也会跑出来”。 我已经过了喜欢这样的小故事的年龄了。并且这样的小故事多是“三无产品”,同江湖传闻中那些 “吃人的树”和“神秘的金字塔”等等很类似。好比现在告诉我说某人,小时候特别笨,长大了学习也不好, 后来坚持读书,读到了博士,引申出来不断坚持,不断进取再笨的人也可能成功。我一定摇头不相信, 现实中,这样的事情发生的唯一理由是他有很多好爷爷或者爸爸。 以前还有个经典的管理小故事:说某家牙膏厂,面向员工征集提高销量的办法,许诺重金奖励, 在各种方案中最终采纳的是非常简单的方案“加大牙膏口1mm”… …当时我觉得这个是非常好的主意, 直到有一天我突然发现这个方法不能保证降低成本甚至会很愚蠢。是这样的,我在床上喝矿泉水,一瓶是 农夫山泉,另一瓶是娃哈哈的。我试验将农夫山泉的瓶盖拧在娃哈哈上,竟然严丝合缝,反之亦然。为什么 这样是这样的?原因很简单:标准化工业生产。制造饮料的公司,如果连瓶子瓶盖都要自己生产,那他 肯定是国企。“正常思维”的企业都会找其他公司直接买,自己把关质量就可以了。从外面买能降低很多成本。 而生产瓶盖的公司则会采用同样的模具为不同家生产,这样,不同牌子的矿泉水瓶盖相同不足为奇了。再回 到上面的小故事,你就会发现这个故事的荒谬之处了。修改口径之后,装牙膏的容器要重新设计,盖子也要 重新设计。这些是很大的花费。 若干年前,还有个经典小故事:说一个拾荒者与众不同,善于思考,别人只是捡易拉罐,而他花了600块 到金属研究所测试了易拉罐中各种金属的含量,发现其中有很多有价值的金属,于是自己开始提炼这些金属。 这个故事告诉我们要多观察,多思考,多动脑。后来,我在《知音》杂志上看到了一篇类似的文章,颇感惊讶。 开头都非常相似,那个人提炼金属,很快发家致富,老婆都娶了5个。最后的结局是进监狱了,不是因为重婚, 而是因为他偷电。融化金属需要大量的电,他在输电线上做手脚… …我宁愿相信这个故事是真是的,很多 东西我们不去做,原因很可能是成本太高。这样说说似乎有吃不着葡萄就说葡萄是酸的意味…… 房屋都是有使用寿命的,哪怕你修建之时用料再扎实也是这样的。国外有很多旧房屋改造加固的项目, 有人看好这样的项目,希望引入国内。但是经过一番考察发现这是不可能的,原因是:成本太高。国外,这样的 项目费用通常接近重新建造。而国内,这样高的成本来维护旧房子,人们根本不接受。或者一拆了之,再建 新房。 总而言之,事物是诸多因素交织在一起的,单独的强调某个方面是不科学的,甚至与真实的决定因素大相径庭。 我想也正是因为这样的小故事过于捕风捉影,正龙打虎,余世维先生在他的讲座中也不愿意使用了吧? Zoologist 2008-4-23
[April , 16, 2008] 离职指南
离职指南
离职指南
许许多多年以前,偶然父亲听说单位(大型国有企业)有两个“人事干部”。一个负责
“进口”,就是负责考核招聘干部;另一个负责“出口”,基本上工作就是送葬等等善后工作。
据说前者脾气非常好,态度也非常好,后者与之截然相反。后来我接触到心理学,尝试着
使用心理学的观点进行分析,有很多种解释。不过现在想起来,这个和心理学什么关系都
没有,完全是利益的问题:你招聘的时候谁知道进来的人是领导的七大姑还是八大姨?
谁知道招进来的干部是否会成为他的上司?而负责出口的则完全没有顾虑,他“送出去”的
干部永远不会再见的。
通常与XX课打交道非常痛苦,因为他们总是认为很多事情都是常识,比如:政府公文
“都”必须用黑色水笔填写(黑色圆珠笔不行,蓝黑色钢笔不行)。当我说我不知道的时候,
人资一个mm用惊异的表情看着我,仿佛她刚知道自己吃下了什么似的。其实,我要问问她
身为一个在主板制造为主的公司呆了n多年,你可知道当今最流行的 LGA775接口的CPU有
多少脚,她肯定回答不正确----没接触过,谁TMD知道啊!
闲话不提,下午三点之后,到人资取离职单。主意必须是三点之后,这样的刻意安排让我
很不理解。也许是上峰考虑经过一天紧张激烈的工作,应该让手下放松一下,找机会发泄
一下吧。早于这个时间去,通常他们会用瞪着绿豆的眼神看着你,说三点后过来。如果此刻
心情不好,必定补充道“你们有看到过通知么”?仔细回想起来,还真没少收过各种龟“腚”。
不过时日一长,总是不清楚哪里是头哪里是尾的。
记得带一支笔,他们那边没有多余的。会让你填三份单子。还要找到最近一次的合同交
上去。如果没有的话,说说好话,借他们的复印一下。这里我非常怀疑他们把我当成日本鬼子,
我问是否可以借来复印的时候,某人居然一口咬“腚”说他们没有,都上交了... ... 多问几个
人就好了,总会有人说漏嘴的。另外,还要交上去一份什么户籍证明,档案在人力资源有限
公司的,需要去青阳路的劳动局打印出来,收费是2元。尽量多打电话问问先,这方面,昆山的
政府部门还是非常不错的。需要注意,公司在这里还有个“腚”,打印完证明之后,必须去派出所
盖章。劳动局的工作人员说,其他公司都没有这个手续的。
然后,把三份单子,合同,户籍证明,交上。换来一张移交手续办理单。去成仓,零仓找人
签字。正常情况下不会有什么问题。法务也不会有什么问题。之后跑电子公文,将能转出去的都
转出去。财产将会是非常麻烦的事情。东西很多的话你就有种被当作土豪被“打”的感觉。你还会
发现名下会平白“多”出很多东西。最常见的就是“不小心”,工作机里面的东西在外面又列出
一次。遇到这种情况,最好及时解释清楚,能早解决就尽量早解决,也给后继者方面的,大家
都是同事,枪口对外。我们这时候也要理解YY课的行为,他们不琢磨多点事情怎么体现价值,
怎么表现很忙碌的样子,此之谓“有困难要上,没有困难创造困难也要上”,是也。
上面的东西签下来,大约要2天时间。之后可以去找会计签字。他要检查你的财产是否已经
清理干净。他们使用ERP的网站查询,ERP会比电子公文再慢上3-4天(YY课自己承认的)。也就
是说,你的电子公文中可能什么东西都没有了,但是ERP上还有一大坨。解决方法是将跑完的电子
公文打印出来,给会计看一下。保存好这个电子公文,说不定后面还要给总务课show出来。
顺便提一句:除非你有特别的信心----比如老大渴望你马上滚蛋,或者你爬的职位足够高,
否则,报废物品上缴的时候,千万要记得,找那个“没收”你物品的人签名留作纪念。我在去年报废
几样物品,上缴时说非常敬仰,好不容易瞻仰到容貌,请他签了字(先见之明,事实上当时我说
的是“哥们我信不着你”)。果真,即至离职的时候惊奇的发现报废单跑了4个月居然没有跑完。
而没签的人,恰好是XX课“最有常识的人”。找她的时候,她竟然和我要看报废的东西。不过好
在我拿出那张签字的单子,她最后没有抵赖。前车之鉴引以为戒,害人之心不可有。
余下还有总务课要签字,退工衣之前必须先退水卡才可以。退这些东西的时候要记得
带上那个离职单,否则去了也没有用。需要注意,他们不会主动给你免穿工衣卡,除非你还有
工衣,否则警卫会找你的麻烦。ps:他们就没有给我,也许这个又是我不知道的常识:(
还有取消资讯权限,要通过电子公文申请取消,这样做多少有点自废武功的意思。
最后,找老大再签字。交给人资,他们会给你一个小纸片,上面注明日期。在那个日期的
12之前必须离开公司,隐约仿佛宾馆客栈。不知道如果商量一下过几天再走是否可行?
还有一项非常非常重要的事情就是离职单。公司规定是你离职之日之后的15天。如果你是
4日走的,那么19日左右才能拿到这个单子。并且这个单子对于你入职来说非常重要。
很多大公司必须凭借这个单子才能报道。因此在开始最好计算清楚。通常可以和对方公司
商量着来的。多出来的时间你可以用来熟悉环境,或者像我一样,用这些时间认真钻研2个
单机游戏。
最后的抒情:当我摘下胸口的钥匙交上去之后(不好意思,幼稚了,我一直把寝室
钥匙挂在了胸前),再戴上工牌,就隐隐的觉得胸口少了点什么。木然回首(工程师做久
了人都这样),我已经在公司呆了四年。从面带青涩,慌张应付客户的毕业生,成为
即使对待FAE也是连唬带蒙的工程师。四年间我改变了很多。床铺,我已经睡了3年(第一年
睡上铺),已经符合人体工程学(床板某处裂了,碎了)。
天是阴沉沉的,大雄在我身后用力的挥着手,亲爱的朋友们,我们不知何时才能够再次
相见;不知何时我才能对你们再说一次“I am back!”
Zoologist
2008年4月5日 [April , 12, 2008] 汇编语言作业的作弊方法 本文程序和工具
汇编语言作业的作弊方法 本文程序和工具
ah 汇编语言作业的作弊方式 帮着朋友写汇编语言作业(好像从小到大我经常帮别人写作业),前后花了一个星期,没写出来。感觉很糟糕, 出题老师疯了,居然要求学生用汇编语言写学生成绩管理系统。要求“能够实现菜单显示、菜单选择、编辑(录入、 插入、修改、删除等)、查找、显示、求总成绩、按总成绩排序(高→低)并显示、装入数据文件、数据文件存盘、 退出、为数据动态分配存储空间等功能”。这样的要求仿佛是给学生火柴棍和502胶水,要求制作能装人的船---- 理论上完全能实现,实际上可行性不高。 既然没写出来,自然要琢磨“歪门邪道”。方法就是用C语言直接写出功能。编译之后有2条路可以选择: 1.反编译为汇编语言;2.插入在汇编语言中。 花了大约4个小时编写了简单的C语言程序,用TC3正常编译,生成 xy.exe 再使用 exe2bin 生成 xy.com文件。 不清楚什么地方的问题,最开始使用TCC -mt -lt xy.c 可以直接编译为 xy.com 文件。选择生成 com文件的原因是 它没有段切换的问题,使用非常方便,也足够小。 xy.com的大小是18,576byte,一般来说汇编程序的源程序大小是它生成的机器代码的7-8倍。反过来估计, 如果手写汇编,完成这些功能就需要大约 140000byte 的源程序... ...这就是我说出题老师疯了的原因...... 使用IDA 5反编译,结果太难看懂了,估计老师一眼就能看出来“代码不是人写的”。顺便提一句:IDA5的功能 好强大,反编译后直接能够生成程序的流程图(接近);使用IDA4 反编译了一下,结果也过于复杂,整理起来非常 困难。 看起来想直接反出来汇编程序这条路走不通。 第二条路,用汇编程序包括这个文件,这个是名副其实的“作弊”,不过看起来更专业。我想如果有汇编语言老师 能看到我的这个文章,并且发现有同学用我这个方法,不妨放他们一马吧,你的题目太难了能理解/想到这个方法的人 就是对汇编认识很深刻的了。 具体方法,用工具 bin2inc 将 xy.com 转化为 x.inc,然后将程序写成这个样子: .model tiny ;为了表示你是一个认真的同学,这里可以插入宏 .data ;为了表示你是一个专业的同学,这里可以插入数据定义 .code ;为了表示你不想让老师一眼看出问题的同学,这里可以插入过程 .startup include x.inc ;为了表示你写了很多,这里可以插入代码 .exit end 实际上,程序的关键只有 include x.inc 这句话。 交作业的时候,需要交上上面的程序和x.inc 。 最后的话,我将东西做完,交给朋友。朋友没同意,觉得 x.inc 太难解释清楚。后来不得不再花了十几个小时给他 写纯汇编语言的作业。未来如果有一个以生成汇编语言代码为目标的简单C编译器,中国学生的汇编语言作业将不会是 什么难题。 Zoologist 2008-4-12
[March , 26, 2008] Watcom C 的笔记14 Watcom C (14)
Watcom C 的笔记14 Watcom C (14)
[March , 25, 2008] Watcom C 的笔记13 Watcom C (13)
Watcom C 的笔记13 Watcom C (13)
生成 .COM 文件的 BUG?
如下程序:
#include <stdint.h>
main ()
{
uint32_t wsize=64*1024,length=0x12345678;
return length/wsize;
}
编译命令:
SET WATCOM=\watcomc
set include=%watcom%\h
path %watcom%\binw
wcc bbb.c /ms
wlink system com file bbb.obj
运行期会出现除零错误 “Divide overflow”。
查看代码发现它使用下面的代码处理这个乘法
seg000:030F mov ax, 5678h
seg000:0312 mov dx, 1234h
seg000:0315 xor bx, bx
seg000:0317 xor cx, cx
seg000:0319 call sub_104DB
seg000:031C pop dx
seg000:031D pop cx
seg000:031E pop bx
seg000:031F retn
seg000:031F sub_10306 endp
子程sub_104DB是使用bx作为除数的除法过程。计算这个除法的
过程很有意思,是分开,先计算 1234h / bx ,再计算 (余数+5678h)/ bx
的。也许这样处理应该是防止结果过大溢出的吧。
如果让代码生成 DOS4GW的 EXE文件就不会有这样的问题。
暂时的猜测是 Watcom C 生成 COM 是默认在16位代码方式下的。它在处理
32位的数据上是有问题的,应该避免这样的情况。
Zoologist
2008-3-25 [March , 24, 2008] Watcom C 的笔记12 Watcom C (12)
Watcom C 的笔记12 Watcom C (12)
函数指针的简单试验
函数指针是:指向一个函数的指针。
#include <stdio.h>
void (*ptr)();
void func1()
{
printf( "This is function 1 \n" );
}
void func2()
{
printf( "This is function 2 \n" );
}
int main()
{
ptr=func2;
(*ptr)();
ptr=func1;
(*ptr)();
return( 0 );
}
Zoologist
2008-3-20
参考:
【1】:来自 http://www.yourblog.org/Data/20041/2519.html
作者:在黑暗中举起探索的火炬
指针函数和函数指针有什么区别
1,这两个概念都是简称,指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。其定义格式如下所示:
返回类型标识符 *返回名称(形式参数表)
{ 函数体 }
返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子:
#include
float *find();
main()
{
static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
float *p;
int i,m;
printf("Enter the number to be found:");
scanf("%d",&m);
printf("the score of NO.%d are:\n",m);
p=find(score,m);
for(i=0;i<4;i++)
printf("%5.2f\t",*(p+i));
}
float *find(float(*pionter)[4],int n)/*定义指针函数*/
{
float *pt;
pt=*(pionter+n);
return(pt);
}
学生学号从0号算起,函数find()被定义为指针函数,起形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向 score的第一行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.
2,“函数指针”是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。函数指针的说明方法为:
数据类型标志符 (*指针变量名)(参数);注:函数括号中的参数可有可无,视情况而定。
下面的程序说明了函数指针调用函数的方法:
#include
int max(int x,int y){ return(x>y?x:y); }
void main()
{
int (*ptr)();
int a,b,c;
ptr=max;
scanf("%d,%d",&a,&b);
c=(*ptr)(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
}
ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你像怎么做了。在程序中把哪个函数的地址赋给它,它就指向哪个函数。而后用指针变量调用它,因此可以先后指向不同的函数,不过注意,指向函数的指针变量没有++和--运算,用时要小心。
junglesong 转载www.chinagpa.com [March , 20, 2008] Watcom C 的笔记11 Watcom C (11)
Watcom C 的笔记11 Watcom C (11)
结构体对齐
我是不主张使用汇编语言学习算法的,最主要的原因是汇编语言并不适合
构造复杂的数据结构。当然,在内存特别紧张的情况下,必须使用汇编语言做算法,
将会是非常痛苦的事情。我曾经研究过一段压缩代码,从上面的部分特征来看,
似乎是先用C语言实现算法,再尝试逐步转化为汇编语言的。额外的话题:BIOS
中的代码大部分是压缩后再存放的。AMI的压缩比大约高出Award 20-30%(个人
估计:)
下面是我写程序中使用的结构体,编写中需要确定结构体中每个成员是否处在内存
中正确的位置,诸如freg0要在 50h 偏移处......
struct spistruct{
uint32_t bfpr; //00-03 BIOS Flash Primary Region
uint16_t hsfsts;//04-05 Hardware Squuencing Flash Status
uint16_t hsfctl;//06-07 Hardware Sequencing Flash Control
uint32_t faddr; //08-0B Flash Address
uint32_t rsrvd1;//0C-0F Reserved
uint8_t fdata[0x40];//10-13 Flash Data 0
//14-4F Flash Data N
uint32_t fracc; //50-57 Flash Region Access Permissions
uint32_t freg0; //54-57 Flash Region0
uint32_t freg1; //58-5B Flash Region1
uint32_t freg2; //5C-5F Flash Region2
uint32_t freg3; //60-63 Flash Region3
uint32_t freg4; //64-67 Flash Region4
uint8_t rsrvd2[12];//68-73 Reserved
uint32_t fpr0; //74-77 Flash Protected Range 0
uint32_t fpr1; //78-7B Flash Protected Range 1
uint32_t fpr2; //7C-7F Flash Protected Range 2
uint32_t fpr3; //80-83 Flash Protected Range 3
uint32_t fpr4; //84-87 Flash Protected Range 4
uint32_t rsrvd3[2];//88-8F Reserved
uint8_t ssfsts;//90 Software Squency Flash Status
uint16_t ssfctl1;//91-92
uint8_t ssfctl2;//93 //91-93 Software Squency Flash Control
uint16_t preop; //94-95 Prefix Opcode Configuration
uint16_t optype;//96-97 Opcode Type Configuration
uint8_t opmenu[8];//98-9F Opcode Menu Configuration
uint32_t bbar; //A0-A3 BIOS Base Address Configuration
uint32_t rsrvd4[3];//A4-AF Reserved
uint32_t fdoc; //B0-B3 Flash Descriptor Observerability Control
uint32_t fdod; //B4-B7 Flash Descriptor Observerability Data
uint32_t rsrvd5[2];//B8-BF Reserved4
uint32_t afc; //C0-C3 Additional Flash Control Register
uint32_t lvscc; //C4-C7 Host Lower Vendor Specific Component Capabilities Register
uint32_t uvscc; //C8-CB Host Upper Vendor Specific Component Capabilities Register
uint32_t rsrvd6;//CC-CF Reserved
uint32_t fpb; //D0-D3
} ;
最初,我采用的是笨办法:给成员赋值,然后查看是否出现在应该的内存位置。
后来发现了一个很好用的宏,它是标准库的扩充,可以直接使用:
#define offsetof(type,memb) ((size_t) & ((type *) 0)->memb 参考[2]
使用的例子: printf("[%lx] [%x]\n",spi->opmenu[0],offsetof(struct spistruct,opmenu) );
随后调试中又发现 ssfctl1 成员总是不能处在正确的位置上。经过研究发现,
结构体中有一个"对齐"的问题。因为内存如果对齐的话,会节省访问时间。我们希望
成员处于91h的位置,而由于对齐,编译器会将其放在92h处对齐。
Watcom C 中上述问题可以用下面的方法解决:
#pragma pack(1) //指定按照 1 byte 对齐
struct spistruct{
uint32_t bfpr; //00-03 BIOS Flash Primary Region
uint16_t hsfsts;//0
... ... ... ...
... ... ... ...
... ... ... ...
参考:
[1] 败中求胜——Qdieyou个人工作室
http://blog.csdn.net/Qdieyou/archive/2007/04/26/1585715.aspx
[2]《C语言参考手册》 P325
Zoologist
2008-3-20 [March , 17, 2008] DOS下的C语言编辑器 我之前之前一直使用Boxer,感觉很糟糕。这个编辑器似乎是专门为Watcom C 设计的,不过最好不要配置在IDE中编译,我试验发现编译经常会死机。也许以后有时间我会考虑写一个类似Turbo C的编辑器吧。
DOS下的C语言编辑器 我之前之前一直使用Boxer,感觉很糟糕。这个编辑器似乎是专门为Watcom C 设计的,不过最好不要配置在IDE中编译,我试验发现编译经常会死机。也许以后有时间我会考虑写一个类似Turbo C的编辑器吧。
[March , 15, 2008] Watcom C 的笔记10 Watcom C (10)
Watcom C 的笔记10 Watcom C (10)
局部变量在内存的位置
在编写一个com文件的时候,遇到奇怪的问题:编译正常,运行后显示
“Stack Overflow!”。程序片段如下:
#include <stdio.h>
int main(int argc,char *argv[])
{
int i,n;
FILE *f;
long int sum=0;
char buffer[2048]=; //1K 就在这里指定一个做buffer的变量
if (argc!=2) {printf("usage: checksum file
试验表明,如果在1024之上就会出现这个错误。在编译过程中,还发现
这个地方的大小不会影响生成com文件的大小。查阅资料【参考1】,上面说
局部变量存放在堆栈中... ...因此如果太大了自然会出现堆栈溢出的问题。
设置为全局变量就可以了,这样并不会影响生成文件的大小,看起来仍然是
在运行过程中动态分配的。分配在代码和堆栈之间的空间。具体如何确定,还不
清楚。
编译批处理文件 mkchk.bat
wcc checksum /ms
wlink system com file checksum
源程序:
#include <stdlib.h>
#include <stdio.h>
char buffer[0xC000]; //48K
int main(int argc,char *argv[])
{
int i,n;
FILE *f;
unsigned long int sum=0;
if (argc!=2) {printf("usage: checksum filename\n"); exit(1);};
//argv[0] is executable file name
f=fopen(argv[1],"r+b");
if (f==NULL) {printf("File open error!");}
n=fread(buffer,sizeof(char),sizeof(buffer),f);
while (n!=0)
{
for (i=0;i<n;i++)
{
sum=sum+buffer[i];
}
n=fread(buffer,sizeof(char),sizeof(buffer),f);
}
printf("Checksum in BYTE: %12hX\n",sum & 0xFF);
printf("Checksum in WORD: %12X\n", sum & 0xFFFF);
printf("Checksum in DWORD: %12lX\n",sum);
return 0;
}
运行结果:
G:\watcomc>checksum dos4gw.exe
Checksum in BYTE: 40
Checksum in WORD: 3E40
Checksum in DWORD: F0153E40
参考:
1.http://topic.csdn.net/t/20040316/12/2848204.html
2008-3-15
Zoologist