Chinaunix

标题: 应PM要求,装B一次以满足其虚荣心。 [打印本页]

作者: folklore    时间: 2012-10-27 19:59
标题: 应PM要求,装B一次以满足其虚荣心。
TO PM: 47# pmerofc


  
不装逼你会死啊

这叫装B? 你有让我装B的“被装许可证”么? 并不是所有人都有资格让我装B,你显然不属于有资格中的一个。

想装逼也行
你给我装出个范儿来

本人承接除开发数据库之外的所有软件开发业务,
包括OS,编译器,驱动(Windows/LInux),图像,3D,网站,加密,压缩,工业机器人控制,以及如此类你能想得到的东西。
你会上面的哪一个?
重复: 我也许会装B,但前提是你有那个让我在你面前装B的资格


别整天像个怨妇似的在论坛上嘟嘟囔囔地嘀咕你在公司的不顺心、勃不起来

我说过不顺心了么?


我问你
那个指责我多次调用printf()的帖子
你后来怎么无声无息地跑没影啦

你太把自已当东西了。我已经在该问题上浪费太多口水,没有义务教育你的。


最后,以后也不会回你的贴子,遇到我的帖子请忽略,谢谢。
作者: 346196247    时间: 2012-10-27 22:38
本帖最后由 346196247 于 2012-10-28 12:47 编辑

楼住是全能大神啊不过,我觉得这是超越大神的存在,现在的科学家,都未必可以,工业机器人,以及3d,图象技术还有驱动,那么多,楼住神级别,啊全精通了,lz随便单手写linux系统了把,3d机器人,这拿的钱,简直吓人,特别是机器人的,工资,楼住说的真实性?
mirnshi 发表于 2012-10-27 23:20
回复 14# 346196247
14楼的大神,说工业机器人,是不可以同智能机器人比较的,哦我错了。其实也可以说是入门级别的机器把不可以说是机器人
作者: folklore    时间: 2012-10-27 22:50
@346196247
自然是真的,第一个工作上的程序就是写WIndows驱动(Linux驱动相对来讲是小儿科了),做工业机器人的公司,自然也顺便做工业机器人的控制及自动化流水线生产系统。。
图像是指图像识别,3D目前只做过DirectX的,GL只是看过理论。
...

目前做板金系统的CAD系统的。

如果你对以上有所怀疑,除了开发数据库系统,你下什么定单我都接,当然要在双方都合适的价位上。

所以说做人要淡定。。。
作者: folklore    时间: 2012-10-27 22:53
本帖最后由 folklore 于 2012-10-27 23:04 编辑

[s]网站的话,可以用C/C++,PHP,ASP写,JSP(Weblogic)也用过,不喜欢
熟HTTP,可过一个可配置的HTTP服务器(支持CGI)。
[/s]
网站的话,可以用C/C++,PHP,ASP写,JSP(Weblogic)也用过,不喜欢
熟HTTP,过一个可配置的HTTP服务器(支持CGI)。


作者: starwing83    时间: 2012-10-27 22:54
回复 2# 346196247


    这你就不懂了,楼主的老板是上帝,楼主的工作就是给Higgs玻色子的轨迹编程不让它们被人类捕获到。开玩笑,这工资能低了?楼主一个月的工资可以给欧洲人造十台强子对撞机。
作者: 346196247    时间: 2012-10-27 22:55
folklore 发表于 2012-10-27 22:50
@346196247
自然是真的,第一个工作上的程序就是写WIndows驱动(Linux驱动相对来讲是小儿科了),做工业机 ...


佩服,我看这c/c++这版,最牛的就是你了,找不出第2个可以与你匹敌的我看,其他的大神怎么说,
作者: folklore    时间: 2012-10-27 22:56
加密和压缩, 专门因此学了数论。。。
作者: folklore    时间: 2012-10-27 22:57
我已经达到了这种程序:
面试的时候,大家都以为我在说谎。。。
作者: folklore    时间: 2012-10-27 23:00
回复 5# starwing83

你不服? 我只是装B给PM看而已,为你的好基友鸣不平么?


   
作者: starwing83    时间: 2012-10-27 23:02
回复 9# folklore


    没,我只是趁这个难得的机会水一下……
作者: __BlueGuy__    时间: 2012-10-27 23:06
笑而不语 ~~
作者: folklore    时间: 2012-10-27 23:08
回复 10# starwing83


    好,顺便拿点分
作者: mirnshi    时间: 2012-10-27 23:10
回复 2# 346196247

不要把工业机器人,过于神化。就如很多人认为汽车的中控很复杂一样。
   
作者: 346196247    时间: 2012-10-27 23:16
回复 13# mirnshi


    大神,工业机器人,同机器人。工业机器人,智能么?
作者: mirnshi    时间: 2012-10-27 23:16
folklore 发表于 2012-10-27 22:56
加密和压缩, 专门因此学了数论。。。


这还需要单独搞算法?国内的加密算法如果涉及到销售,需要经过密码委的认可。压缩,能搞出什么花样,目前都没有实质性的突破,某些数据也就算7z了。
作者: mirnshi    时间: 2012-10-27 23:20
回复 14# 346196247

工业机器人,同机器人


能等同吗?


   
作者: folklore    时间: 2012-10-27 23:21
回复 15# mirnshi


    研究加密是我嫌能找到的加密系统生成密钥太短。
压缩的话,是考虑到在小型应用是,拿个Zlib太拉风了些。。。


作者: mirnshi    时间: 2012-10-27 23:24
folklore 发表于 2012-10-27 23:21
回复 15# mirnshi


加密更多地应该考虑算法,密钥可以通过某种方式增长呀,比如做base64或者hash。
轻量级的压缩算法也很多呀,现成的流压缩lzo就很好。
作者: folklore    时间: 2012-10-27 23:25
回复 13# mirnshi


    对,工业机器人很好做,只要会 多线程和使用锁基本就可以了。
相对来讲流水线比较难些, 生产中产生异常中断后, 要想正确恢复生产, 极难。
作者: folklore    时间: 2012-10-27 23:30
回复 18# mirnshi


  加密更多地应该考虑算法,密钥可以通过某种方式增长呀,比如做base64或者hash。

这种方式没有意义的。因为并没有增加破解难度。
加密要求在以下情况下算法是安全的:
知道算法,知道全部密文,知道部分明文  --》 这种情况下很难算出更多明文  才行

轻量级的压缩算法也很多呀,现成的流压缩lzo就很好。

lzo没听说过,等下看看, 倒是编过lzw
作者: mirnshi    时间: 2012-10-27 23:34
回复 20# folklore

目前块加密,用aes足以,美国FBI都无法搞定,只要密钥足够长,比如用一个mp3做密钥。
   
作者: folklore    时间: 2012-10-27 23:36
回复 21# mirnshi


    对称加密的的确如些,因为密钥可以比明文长好多。。。

非对称加密才是苦力话。
作者: mirnshi    时间: 2012-10-27 23:40
folklore 发表于 2012-10-27 23:36
回复 21# mirnshi


非对称,都是用openssl了。没有考虑过自己实现,不过貌似难度在于大数运算上,其实加密算法本身还是很简单的。
作者: folklore    时间: 2012-10-27 23:43
回复 23# mirnshi


    对,算512Bit 的密钥,马上就能算出来,
算2048bit 的,算了好久(忘记了多久)
4096Bit的,Y的,我算了好几天没算出来,放弃了

作者: gvim    时间: 2012-10-27 23:46
酱油拿2分,楼上二位 V5
向你们学习!
作者: mirnshi    时间: 2012-10-27 23:58
回复 25# gvim

不打酱油而灌水,CU大妈就干着急没办法了。
   
作者: wait_rabbit    时间: 2012-10-28 00:47
{:3_186:} 看见大神要拜。

能不能请教一下防火墙等安全产品相关的学习路线?最近在考虑往这个方向走。要是能跟kernel结合起来是最好的了。
作者: wwwsq    时间: 2012-10-28 03:58
346196247 发表于 2012-10-27 22:38
楼住是全能大神啊不过,我觉得这是超越大神的存在,现在的科学家,都未必可以,工业机器人,以及3d,图象技术 ...



自己sb就不要随便出来冒泡。

操作系统觉得很神秘吗?工业机器人觉得很神秘吗?图像技术觉得很神秘吗?

对你这样的人可能是很神秘。

不要以为人人都和你一样是newbie。


作者: starwing83    时间: 2012-10-28 06:22
回复 19# folklore


    非常不明白工业机器人和多线程和锁有毛线关系。通常这种应用都是强调实时性的,用的都是RTOS,有个屁的多线程……
作者: starwing83    时间: 2012-10-28 06:24
回复 28# wwwsq


    图像技术对我来说很神秘,特别是图像识别。现在大多数都是概率算法或者是很specific的算法吧?真正让计算机“理解”图像是非常困难的。

不过,人家说的是专精一项和各项全能。这年头,全能就意味着全不能。
作者: __BlueGuy__    时间: 2012-10-28 09:17
starwing83 发表于 2012-10-28 06:24
回复 28# wwwsq


不过,人家说的是专精一项和各项全能。这年头,全能就意味着全不能。
作者: folklore    时间: 2012-10-28 09:21
回复 29# starwing83

非常不明白工业机器人和多线程和锁有毛线关系。通常这种应用都是强调实时性的,用的都是RTOS,有个屁的多线程……

    您老牛B,你老的工业机器人同时只做一个动作,不进行动作互锁,自然也不用多线程和线程互锁,
您老的应用只强调实时性,
您老的RTOS不支持多线程。

您老专家,但您老说话时要留些余地噬
  1. 人家说的是专精一项和各项全能。这年头,全能就意味着全不能。
复制代码
这个我同意,所有你看我多么低调噬
作者: starwing83    时间: 2012-10-28 10:05
本帖最后由 starwing83 于 2012-10-28 10:19 编辑

回复 32# folklore


    工业机器人通常在机器人身上有独立的控制芯片(即节点),节点本身可以完成大多数工作,节点和节点之间不会直接连接。

总控器的作用是连接所有节点,并向节点发送指令。你可以认为所有的指令发送以后,都会精确地在既定时间完成,因此根本犯不着加锁和多线程。

节点本身采用RTOS,只需要接受命令并构建动作列表即可。这样的方案很成熟,安全,而且绝对比多线程要有实用性得多。



我还是忍不住想说一下,除了伪实时操作系统,真正的实时操作系统都是不会有线程的概念的。线程就意味着上下文切换,上下文切换就意味着延迟,这和实时性是背道而驰的。
作者: gvim    时间: 2012-10-28 10:37
不对吧。。。

机器人没做过,但就实时来说,实时是相对任务来说的,而实时本身就是来描述任务响应能力的东西,“真正的实时操作系统”要定义真正之前需要先精确定义实时。最实时的就是死等,关掉中断仅轮训某个端口,也就不需要所谓的操作系统。否则只要用中断,也就存在上下文保护、恢复的问题,这个是各种硬件决定的,比如有体系做的快速中断和一般中断。这种情况下,你总不能说有中断的(因为有上下文保存和恢复)处理器就不是真正的实时处理器吧。
RTOS可以没有内存管理,但一定有线程(或者说任务吧)管理,没了上下文管理,也就不必要称为"操作系统"了。
作者: starwing83    时间: 2012-10-28 10:43
回复 35# gvim


    的确就不是啊……实时做事情,为什么要死等呢?往一个端口输出5V信号,按正弦强弱来变化,就是直接一个无限循环啊,这才是实时的啊……

还有,没人规定操作系统必须要有线程甚至进程。理论上说,能管理计算机所有资源的系统就是操作系统。因为实时的原因计算机的CPU资源必须交给一个独立的执行流而无需管理,这样的操作系统也是存在的。这样的操作系统本身可以进行其他的管理,比如连线的端口啊神马的。

早期的DOS那种,就可以算作是实时的操作系统。现代因为非实时操作系统的实时性要求也已经满足需要了,所以用Linux这种抢占式多任务操作系统来代替实时操作系统也是可以的。但是在真正高实时性的需求下(ns级),还是得用专门的RTOS,这时任何一点上下文切换就都是要命的。
作者: cjaizss    时间: 2012-10-28 10:58
starwing83 发表于 2012-10-28 10:05
回复 32# folklore

怎么听上去像裸体机器?
作者: cjaizss    时间: 2012-10-28 11:01
starwing83 发表于 2012-10-28 10:05
回复 32# folklore

另外,当站在所有OS的抽象角度来看问题的时候,我想,用任务这个词汇来代替线程这个词汇是不是要来的恰当点?
作者: folklore    时间: 2012-10-28 11:03
回复 34# starwing83


   工业机器人通常在机器人身上有独立的控制芯片(即节点),节点本身可以完成大多数工作,节点和节点之间不会直接连接。

总控器的作用是连接所有节点,并向节点发送指令。你可以认为所有的指令发送以后,都会精确地在既定时间完成,因此根本犯不着加锁和多线程。

节点本身采用RTOS,只需要接受命令并构建动作列表即可。这样的方案很成熟,安全,而且绝对比多线程要有实用性得多。


不好意思,前面言语过激了。我以为你没做过光扯了。
你说的是那种看Senor做动作的。如果只是这样的话,当然不用多线程。
多线程用在坑爹的情况下:比如,两个Servo共用一个移动轴。 机器人对外界输入(包括产品数量及位置等)做不同响应等相对“智能”的情况。
用户总是希望越快越好,更快,就意味着更精确的流程控制,芯片当然理论上也可以做,只是怕没人发那个钱吧。

此外,做机器强调安全性,所以,我并不完全相信Senser,因为Sensor可以因为各种原因误动作。
做法是装产品信息(摆放方向,位置,数量,有无)信息发布给下一个流程。 下一个流程根据产品信息和Senor检测到的做比较。
不一致则出错。。。。


我还是忍不住想说一下,除了伪实时操作系统,真正的实时操作系统都是不会有线程的概念的。

你说的大都是对的。但实时到什么程序才是真实时,芯片直接控制算实时么?

线程就意味着上下文切换,上下文切换就意味着延迟,这和实时性是背道而驰的。

我想这个不对,实时并不意思着没有延迟,甚至不意味着减少时延。 还有电路叫“实时延时电路”呢:)。
实时最重要的,看起来和实时这两个字没关系的东西是:不丢失事件(也就意味着要“实时处理”,因为硬件不可能无限制锁存事件)

如果为了实时,放弃多线程,那才叫把西瓜乱丢呢。

此外,工业控制需要多”实时“?
作者: starwing83    时间: 2012-10-28 11:05
回复 38# cjaizss


    恩恩,说任务是恰当一点。这么说的话实时性也和多任务不冲突——只要执行实时任务的时候不要调度就行了。

是这样的,我本人对RTOS不了解,以前在bccn混迹的时候有个昵称叫VxWorks的,介绍了风河的一些情况,那个时期稍微了解了一些,才明白其实Linux根本就不算实时操作系统的,只能算伪实时,真正的实时操作系统在执行实时任务的时候是不能做调度的,这个印象就一直留下来了。
作者: folklore    时间: 2012-10-28 11:06
回复 38# cjaizss


   叫什么没关系吧。
此外,任务更近于进程而不是线程吧。 当然,进程和线程的界线也不好定
作者: cjaizss    时间: 2012-10-28 11:11
starwing83 发表于 2012-10-28 11:05
回复 38# cjaizss

实时操作系统和通用操作系统是对立的概念。实时操作系统考虑的个性,通用操作系统考虑的是公平。通用操作系统可以加入一点实时的味道做润色,但一般结构上考虑要比实时操作系统里的复杂一些。
实时操作系统中还是要有很多任务的,它的结构一般和通用不一样,通用的架构层次一般是硬件抽象驱动,软件抽象驱动,系统调用,上层应用(进程/线程),实时一般可能分为几段,比如硬件中断,软件中断,普通任务,闲置等。
作者: starwing83    时间: 2012-10-28 11:11
回复 39# folklore


那个,我得先声明:我是真的没做过实时操作系统的东西,也没做过工业机器人,所以如果有我说的不对的地方,你大胆指出就可以了。

我只是在以前的论坛听人说的比较多,记下来一点,发现和你说的有冲突而已,也可能是我的知识储备陈旧了,你不必在意。

关于实时和延时冲突这里是我没解释清楚。你归纳的更好:的确,实时并不仅仅是不延时,实时意味着对时间的精确控制。比如说在流水线过去的一段时间里面,机械臂必须做出多少个动作,必须焊接多少次,每次必须在什么时候什么位置。万一有一次延迟或者快了都会完蛋。所以仅仅说不延时是不够的,必须是精确控制时间。

在不严格的实时的环境下,用伪实时操作系统是可以的,但是如果是高实时要求的环境,比如流水线机器人,那么VxWorks这样的专业实时操作系统就是必要的。
作者: starwing83    时间: 2012-10-28 11:13
回复 42# cjaizss


    恩,其实你说的一种就是软件控制的调度,即所谓“协作式多任务”,也可以是软件可控抢占,即不重要的任务抢占,而重要任务执行时禁止抢占。也可以是硬件自由决定抢占,即软件仅仅写好回调,由硬件触发,硬件决定是否实时,这些倒是第一次听说,很有意思。
作者: folklore    时间: 2012-10-28 11:16
回复 42# cjaizss


    老白V5,前面那个老白,牛B掉了一地噬,是你的么
作者: folklore    时间: 2012-10-28 11:19
回复 43# starwing83


    没有关系啊,我也只是半桶水而已。
作者: cjaizss    时间: 2012-10-28 11:20
starwing83 发表于 2012-10-28 11:13
回复 42# cjaizss

最终一切还是由硬件决定,这个跑不了的,呵呵.只是策略由软件来决定.
临时插入任务抢占无论如何都只能通过中断。
实时并不代表真正的需求一到就马上开搞,只是,基于这个OS策略,这个开搞的时间是可以预测的。而通用下,这个开搞的时间因为公平性,变的有些不可预测。
作者: cjaizss    时间: 2012-10-28 11:21
folklore 发表于 2012-10-28 11:16
回复 42# cjaizss

除了我,居然还有第二个老白?
作者: starwing83    时间: 2012-10-28 11:22
本帖最后由 starwing83 于 2012-10-28 11:23 编辑

回复 47# cjaizss


    恩恩,这个说法我是赞同的。顺便说一下,最近登陆的好奇号,用的就是风河家的VxWorks实时操作系统~~这货和地球通讯有几分钟的延迟,意味着在这段时间里面,它自己的智能如果搞不定(比如没发现有悬崖)那几亿美元就打水漂了= =
作者: gvim    时间: 2012-10-28 11:33
回复 40# starwing83


    不,实时不是用调度来刻画的,而是响应时间,执行长度这样的属性刻画。简单说来只要能满足x时间开始响应任务,并且在规定的y时间内完成,就是针对你的任务是实时的。中间随便怎么调度,只要能把各种任务满足deadline即可。最合理的实时是先计算时间和周期,再安排调度,最实时的实时(就不叫操作系统了)是裸机关中断轮询。

操作系统最重要的资源就是cpu时间,如果连这个都不管。。。。当然也可以叫操作系统,只是没几个人承认吧。
作者: starwing83    时间: 2012-10-28 11:37
回复 50# gvim


    对于实时性任务,CPU时间的重要性无法和任务的实时性相提并论的。

比如说好奇号,我宁愿在摄像头后面再多装一个CPU,我也绝对不把主芯片做成分时然后同时跑机器视觉和主程序——多装CPU撑死了也就多个几千美元,万一没看到前面的悬崖那几亿美元就报销了。那么,对于那个专门处理计算机视觉的CPU,就无所谓CPU时间资源了——整个CPU就为了搞一件事而已。

实时不仅仅是deadline,如果是机器人,那么对于每个时间做什么事情都要有严格限制,对于一些关键任务,比如说改变电机方向这种,提前了或者推迟了都不行,要严格控制,所以在执行这样的重要任务的时候,直接关掉调度器是最合适的。
作者: gvim    时间: 2012-10-28 11:50
starwing83 发表于 2012-10-28 11:37
回复 50# gvim


那是你的设计问题,不是RTOS的问题。RTOS没有说是任务管理的银弹,很多场景确实就是轮询最合适。单片机便宜的才几块钱,专门做这个任务没什么问题。

》》》我还是忍不住想说一下,除了伪实时操作系统,真正的实时操作系统都是不会有线程的概念的。
线程和任务在这个领域里没区别,只是名词不一样。就像cjzzzz前两天举例说的电子领域里叫固件开发,做软件的就叫嵌入式吧。这里的任务还是有调度,只不过调度策略相对简单。
我的意思是,RTOS不是说有任务/线程就不是RTOS,而是说你的实时性要求可否用你采用的RTOS来满足,或者中断响应能否满足你需要的实时性,这才是做之前应该论证的东西。
作者: gvim    时间: 2012-10-28 11:54
RTEMS,vxworks里面照样有线程/任务的东西。
有否上下文切换这不是区分实时与否的参数
作者: stephen_du    时间: 2012-10-28 12:00
folklore 发表于 2012-10-27 19:59
TO PM: 47# pmerofc


楼主可能真的做过你所描述的领域,我其实也是这个状况,但是领域不如您广,
但是我们可能有点共性就是深度不够,你自己所说的这些领域如果深入挖掘都不是一个人能够搞定的。
作者: starwing83    时间: 2012-10-28 12:22
回复 52# gvim


    你可能是将“需要实时处理的任务”(根据实时的约束不同,可以选用不同的操作系统)和“为实时任务设计的操作系统”(操作系统的目的,就是为了为实时任务提供最好的支持)给搞混了。

前者说明一个任务有实时要求,因此只要满足这个要求的操作系统——哪怕是通用的——都OK。

后者说明这个操作系统就是为了实时而设计的,只要硬件时间辨析度支持,那么可以支持任意实时要求的任务。

这里说的是,如果你的任务对实时要求并不是很高——比如仅仅是一个会根据人的走动而走动的机器人——那么用普通的通用操作系统也是可以的。

然而,如果你的要求本身就需要高实时性,那么配置高性能CPU+通用操作系统,是不如直接配置合适的CPU+实时操作系统的。工业用的流水线焊接机器人就是这种。

所以我才会说,这样的情形下,用线程和锁去进行这样的任务,是很不合适的。
作者: liuiang    时间: 2012-12-03 23:24
鬼使神差翻到此贴,楼主得顶啊~~~~
作者: folklore    时间: 2012-12-04 14:54
  1. Brennan's Guide to Inline Assembly
  2. by Brennan "Bas" Underwood
  3. Document version 1.1.2.2
  4. Ok. This is meant to be an introduction to inline assembly under DJGPP. DJGPP is based on GCC, so it uses the AT&T/UNIX syntax and has a somewhat unique method of inline assembly. I spent many hours figuring some of this stuff out and told Info that I hate it, many times.

  5. Hopefully if you already know Intel syntax, the examples will be helpful to you. I've put variable names, register names and other literals in bold type.


  6. The Syntax
  7. So, DJGPP uses the AT&T assembly syntax. What does that mean to you?
  8. Register naming:
  9. Register names are prefixed with "%". To reference eax:
  10. AT&T:  %eax
  11. Intel: eax

  12. Source/Destination Ordering:
  13. In AT&T syntax (which is the UNIX standard, BTW) the source is always on the left, and the destination is always on the right.
  14. So let's load ebx with the value in eax:
  15. AT&T:  movl %eax, %ebx
  16. Intel: mov ebx, eax

  17. Constant value/immediate value format:
  18. You must prefix all constant/immediate values with "$".
  19. Let's load eax with the address of the "C" variable booga, which is static.
  20. AT&T:  movl $_booga, %eax
  21. Intel: mov eax, _booga

  22. Now let's load ebx with 0xd00d:
  23. AT&T:  movl $0xd00d, %ebx
  24. Intel: mov ebx, d00dh

  25. Operator size specification:
  26. You must suffix the instruction with one of b, w, or l to specify the width of the destination register as a byte, word or longword. If you omit this, GAS (GNU assembler) will attempt to guess. You don't want GAS to guess, and guess wrong! Don't forget it.
  27. AT&T:  movw %ax, %bx
  28. Intel: mov bx, ax

  29. The equivalent forms for Intel is byte ptr, word ptr, and dword ptr, but that is for when you are...
  30. Referencing memory:
  31. DJGPP uses 386-protected mode, so you can forget all that real-mode addressing junk, including the restrictions on which register has what default segment, which registers can be base or index pointers. Now, we just get 6 general purpose registers. (7 if you use ebp, but be sure to restore it yourself or compile with -fomit-frame-pointer.)
  32. Here is the canonical format for 32-bit addressing:
  33. AT&T:  immed32(basepointer,indexpointer,indexscale)
  34. Intel: [basepointer + indexpointer*indexscale + immed32]

  35. You could think of the formula to calculate the address as:
  36.   immed32 + basepointer + indexpointer * indexscale

  37. You don't have to use all those fields, but you do have to have at least 1 of immed32, basepointer and you MUST add the size suffix to the operator!
  38. Let's see some simple forms of memory addressing:

  39. Addressing a particular C variable:

  40. AT&T:  _booga
  41. Intel: [_booga]

  42. Note: the underscore ("_") is how you get at static (global) C variables from assembler. This only works with global variables. Otherwise, you can use extended asm to have variables preloaded into registers for you. I address that farther down.

  43. Addressing what a register points to:

  44. AT&T:  (%eax)
  45. Intel: [eax]



  46. Addressing a variable offset by a value in a register:

  47. AT&T: _variable(%eax)
  48. Intel: [eax + _variable]



  49. Addressing a value in an array of integers (scaling up by 4):

  50. AT&T:  _array(,%eax,4)
  51. Intel: [eax*4 + array]



  52. You can also do offsets with the immediate value:

  53. C code: *(p+1) where p is a char *
  54. AT&T:  1(%eax) where eax has the value of p
  55. Intel: [eax + 1]



  56. You can do some simple math on the immediate value:

  57. AT&T: _struct_pointer+8

  58. I assume you can do that with Intel format as well.

  59. Addressing a particular char in an array of 8-character records:
  60. eax holds the number of the record desired. ebx has the wanted char's offset within the record.

  61. AT&T:  _array(%ebx,%eax,8)
  62. Intel: [ebx + eax*8 + _array]

  63. Whew. Hopefully that covers all the addressing you'll need to do. As a note, you can put esp into the address, but only as the base register.
  64. Basic inline assembly
  65. The format for basic inline assembly is very simple, and much like Borland's method.
  66. asm ("statements");

  67. Pretty simple, no? So
  68. asm ("nop");

  69. will do nothing of course, and
  70. asm ("cli");

  71. will stop interrupts, with
  72. asm ("sti");

  73. of course enabling them. You can use __asm__ instead of asm if the keyword asm conflicts with something in your program.
  74. When it comes to simple stuff like this, basic inline assembly is fine. You can even push your registers onto the stack, use them, and put them back.

  75. asm ("pushl %eax\n\t"
  76.      "movl $0, %eax\n\t"
  77.      "popl %eax");

  78. (The \n's and \t's are there so the .s file that GCC generates and hands to GAS comes out right when you've got multiple statements per asm.)
  79. It's really meant for issuing instructions for which there is no equivalent in C and don't touch the registers.
  80. But if you do touch the registers, and don't fix things at the end of your asm statement, like so:

  81. asm ("movl %eax, %ebx");
  82. asm ("xorl %ebx, %edx");
  83. asm ("movl $0, _booga");

  84. then your program will probably blow things to hell. This is because GCC hasn't been told that your asm statement clobbered ebx and edx and booga, which it might have been keeping in a register, and might plan on using later. For that, you need:
  85. Extended inline assembly
  86. The basic format of the inline assembly stays much the same, but now gets Watcom-like extensions to allow input arguments and output arguments.
  87. Here is the basic format:

  88. asm ( "statements" : output_registers : input_registers : clobbered_registers);

  89. Let's just jump straight to a nifty example, which I'll then explain:

  90. asm ("cld\n\t"
  91.      "rep\n\t"
  92.      "stosl"
  93.      : /* no output registers */
  94.      : "c" (count), "a" (fill_value), "D" (dest)
  95.      : "%ecx", "%edi" );

  96. The above stores the value in fill_value count times to the pointer dest.
  97. Let's look at this bit by bit.

  98. asm ("cld\n\t"

  99. We are clearing the direction bit of the flags register. You never know what this is going to be left at, and it costs you all of 1 or 2 cycles.
  100.      "rep\n\t"
  101.      "stosl"

  102. Notice that GAS requires the rep prefix to occupy a line of it's own. Notice also that stos has the l suffix to make it move longwords.
  103.      : /* no output registers */

  104. Well, there aren't any in this function.
  105.      : "c" (count), "a" (fill_value), "D" (dest)

  106. Here we load ecx with count, eax with fill_value, and edi with dest. Why make GCC do it instead of doing it ourselves? Because GCC, in its register allocating, might be able to arrange for, say, fill_value to already be in eax. If this is in a loop, it might be able to preserve eax thru the loop, and save a movl once per loop.
  107.      : "%ecx", "%edi" );

  108. And here's where we specify to GCC, "you can no longer count on the values you loaded into ecx or edi to be valid." This doesn't mean they will be reloaded for certain. This is the clobberlist.
  109. Seem funky? Well, it really helps when optimizing, when GCC can know exactly what you're doing with the registers before and after. It folds your assembly code into the code it's generates (whose rules for generation look remarkably like the above) and then optimizes. It's even smart enough to know that if you tell it to put (x+1) in a register, then if you don't clobber it, and later C code refers to (x+1), and it was able to keep that register free, it will reuse the computation. Whew.

  110. Here's the list of register loading codes that you'll be likely to use:

  111. a        eax
  112. b        ebx
  113. c        ecx
  114. d        edx
  115. S        esi
  116. D        edi
  117. I        constant value (0 to 31)
  118. q,r      dynamically allocated register (see below)
  119. g        eax, ebx, ecx, edx or variable in memory
  120. A        eax and edx combined into a 64-bit integer (use long longs)

  121. Note that you can't directly refer to the byte registers (ah, al, etc.) or the word registers (ax, bx, etc.) when you're loading this way. Once you've got it in there, though, you can specify ax or whatever all you like.
  122. The codes have to be in quotes, and the expressions to load in have to be in parentheses.

  123. When you do the clobber list, you specify the registers as above with the %. If you write to a variable, you must include "memory" as one of The Clobbered. This is in case you wrote to a variable that GCC thought it had in a register. This is the same as clobbering all registers. While I've never run into a problem with it, you might also want to add "cc" as a clobber if you change the condition codes (the bits in the flags register the jnz, je, etc. operators look at.)

  124. Now, that's all fine and good for loading specific registers. But what if you specify, say, ebx, and ecx, and GCC can't arrange for the values to be in those registers without having to stash the previous values. It's possible to let GCC pick the register(s). You do this:

  125. asm ("leal (%1,%1,4), %0"
  126.      : "=r" (x)
  127.      : "0" (x) );

  128. The above example multiplies x by 5 really quickly (1 cycle on the Pentium). Now, we could have specified, say eax. But unless we really need a specific register (like when using rep movsl or rep stosl, which are hardcoded to use ecx, edi, and esi), why not let GCC pick an available one? So when GCC generates the output code for GAS, %0 will be replaced by the register it picked.
  129. And where did "q" and "r" come from? Well, "q" causes GCC to allocate from eax, ebx, ecx, and edx. "r" lets GCC also consider esi and edi. So make sure, if you use "r" that it would be possible to use esi or edi in that instruction. If not, use "q".

  130. Now, you might wonder, how to determine how the %n tokens get allocated to the arguments. It's a straightforward first-come-first-served, left-to-right thing, mapping to the "q"'s and "r"'s. But if you want to reuse a register allocated with a "q" or "r", you use "0", "1", "2"... etc.

  131. You don't need to put a GCC-allocated register on the clobberlist as GCC knows that you're messing with it.

  132. Now for output registers.

  133. asm ("leal (%1,%1,4), %0"
  134.      : "=r" (x_times_5)
  135.      : "r" (x) );

  136. Note the use of = to specify an output register. You just have to do it that way. If you want 1 variable to stay in 1 register for both in and out, you have to respecify the register allocated to it on the way in with the "0" type codes as mentioned above.
  137. asm ("leal (%0,%0,4), %0"
  138.      : "=r" (x)
  139.      : "0" (x) );

  140. This also works, by the way:
  141. asm ("leal (%%ebx,%%ebx,4), %%ebx"
  142.      : "=b" (x)
  143.      : "b" (x) );

  144. 2 things here:
  145. Note that we don't have to put ebx on the clobberlist, GCC knows it goes into x. Therefore, since it can know the value of ebx, it isn't considered clobbered.
  146. Notice that in extended asm, you must prefix registers with %% instead of just %. Why, you ask? Because as GCC parses along for %0's and %1's and so on, it would interpret %edx as a %e parameter, see that that's non-existent, and ignore it. Then it would bitch about finding a symbol named dx, which isn't valid because it's not prefixed with % and it's not the one you meant anyway.
  147. Important note: If your assembly statement must execute where you put it, (i.e. must not be moved out of a loop as an optimization), put the keyword volatile after asm and before the ()'s. To be ultra-careful, use
  148. __asm__ __volatile__ (...whatever...);

  149. However, I would like to point out that if your assembly's only purpose is to calculate the output registers, with no other side effects, you should leave off the volatile keyword so your statement will be processed into GCC's common subexpression elimination optimization.
  150. Some useful examples
  151. #define disable() __asm__ __volatile__ ("cli");

  152. #define enable() __asm__ __volatile__ ("sti");

  153. Of course, libc has these defined too.
  154. #define times3(arg1, arg2) \
  155. __asm__ ( \
  156.   "leal (%0,%0,2),%0" \
  157.   : "=r" (arg2) \
  158.   : "0" (arg1) );

  159. #define times5(arg1, arg2) \
  160. __asm__ ( \
  161.   "leal (%0,%0,4),%0" \
  162.   : "=r" (arg2) \
  163.   : "0" (arg1) );

  164. #define times9(arg1, arg2) \
  165. __asm__ ( \
  166.   "leal (%0,%0,8),%0" \
  167.   : "=r" (arg2) \
  168.   : "0" (arg1) );

  169. These multiply arg1 by 3, 5, or 9 and put them in arg2. You should be ok to do:
  170. times5(x,x);

  171. as well.
  172. #define rep_movsl(src, dest, numwords) \
  173. __asm__ __volatile__ ( \
  174.   "cld\n\t" \
  175.   "rep\n\t" \
  176.   "movsl" \
  177.   : : "S" (src), "D" (dest), "c" (numwords) \
  178.   : "%ecx", "%esi", "%edi" )

  179. Helpful Hint: If you say memcpy() with a constant length parameter, GCC will inline it to a rep movsl like above. But if you need a variable length version that inlines and you're always moving dwords, there ya go.
  180. #define rep_stosl(value, dest, numwords) \
  181. __asm__ __volatile__ ( \
  182.   "cld\n\t" \
  183.   "rep\n\t" \
  184.   "stosl" \
  185.   : : "a" (value), "D" (dest), "c" (numwords) \
  186.   : "%ecx", "%edi" )

  187. Same as above but for memset(), which doesn't get inlined no matter what (for now.)

  188. #define RDTSC(llptr) ({ \
  189. __asm__ __volatile__ ( \
  190.         ".byte 0x0f; .byte 0x31" \
  191.         : "=A" (llptr) \
  192.         : : "eax", "edx"); })

  193. Reads the TimeStampCounter on the Pentium and puts the 64 bit result into llptr.

  194. The End
  195. "The End"?! Yah, I guess so.
  196. If you're wondering, I personally am a big fan of AT&T/UNIX syntax now. (It might have helped that I cut my teeth on SPARC assembly. Of course, that machine actually had a decent number of general registers.) It might seem weird to you at first, but it's really more logical than Intel format, and has no ambiguities.

  197. If I still haven't answered a question of yours, look in the Info pages for more information, particularly on the input/output registers. You can do some funky stuff like use "A" to allocate two registers at once for 64-bit math or "m" for static memory locations, and a bunch more that aren't really used as much as "q" and "r".

  198. Alternately, mail me, and I'll see what I can do. (If you find any errors in the above, please, e-mail me and tell me about it! It's frustrating enough to learn without buggy docs!) Or heck, mail me to say "boogabooga."

  199. It's the least you can do.



  200. --------------------------------------------------------------------------------

  201. Related Usenet posts:
  202. local labels
  203. fixed point multiplies

  204. --------------------------------------------------------------------------------
  205. Thanks to Eric J. Korpela <korpela@ssl.Berkeley.EDU> for some corrections.
  206. --------------------------------------------------------------------------------
  207. Have you seen the DJGPP2+Games Page? Probably.
  208. Page written and provided by Brennan Underwood.
  209. Copyright &copy; 1996 Brennan Underwood. Share and enjoy!
  210. Page created with vi, God's own editor.  
复制代码
回复 56# liuiang


    ...

by the way. i am search/learn/forgot it a hunders of times.
memo it:


作者: 一个人取暖    时间: 2012-12-04 19:02
folklore 发表于 2012-10-27 22:57
我已经达到了这种程序:
面试的时候,大家都以为我在说谎。。。


看到这句 我笑了 哈哈哈
作者: windoze    时间: 2012-12-05 09:56
回复 55# starwing83


“实时”这个词得先明确一下含义。
“实时”不等同于很快,也不等同于非常快,它等同与“保证足够快”。
重点在于两个,一个是“足够快”,对于不同的场合快慢要求是不一样的,需要明确指定响应时间的指标,对于火星车来说足够快的系统对于喷气机就有可能不够快。
还有一点是“保证”,目前大多数(如果不是全部)通用操作系统都没有办法保证任何一个动作一定在一个给定时间内完成,实时操作系统正是在这一点上区别于通用操作系统。
作者: orafy    时间: 2012-12-05 10:52
支持楼主,我也对那人挺无语的。
上次我在链表排序那帖子里说算法简单,容易实现就是优点,居然被喷。

怀疑这种写书的到底有多少实际编码经验,
当由于进度安排,竞争对手压力逼得通宵加班编码,产品第二天就要放demo,还有一堆必须修补的bug时,哪还有心情研究c/c++的特殊用法,
编写直白易读,也便于同事理解和维护的,遵循小组编码规范的代码才是最重要的。

这是我工作中的感触,特别是上个月过了一段加班到半夜4,5点的噩梦一周后的切身体会,30多个人半夜等你修复bug。。。

可读性,可维护性,可测试性才是最重要的。
作者: liuiang    时间: 2012-12-05 12:08
链表排序那帖就不用说了,完全误导初学者。
作者: folklore    时间: 2012-12-05 20:35
@orafy
可读性,可维护性,可测试性

真能做做到的没几个。


很多系统从设计开始就已经烂掉了。
代码被“软件工程”说得一文不值。但事实上,代码的重要性,不低于一个好的,精巧的设计。
作者: folklore    时间: 2012-12-05 20:46
@liuiang
他只会说一些自以为是,“好像是对的”的东西。
-- 这个其实是一个人长大了没有的重要指标。

(这种错误我在大学时代也犯过。现在讲话都只讲事实,谨慎做评论)
你就原谅他吧。

PS: 发现有人有点怀疑本贴噬。
虽然只是装B,我敢发贴,自然就有两把刷子。
我提到的各个领域,在论坛上,自然都会有精于此道的大家在。
虽然他们可以不肖于理我,
但事实上,发此贴时,是有和个别性子急的大家角力的觉悟的。
作者: cokeboL    时间: 2012-12-05 20:59
回复 62# folklore


    一切从实际出发,马克思的哲学还是不错的
作者: Sevk    时间: 2012-12-05 21:04
提示: 作者被禁止或删除 内容自动屏蔽
作者: liuiang    时间: 2012-12-06 09:44
回复 63# folklore


    我记得大学毕业那会儿,也是豪情万丈,感觉良好。工作时间越长心里越虚倒是真的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2