大宝(sodme)的专栏

专注于高性能网络服务器技术研发,关注网游产品设计、研发、市场与运营的各个环节

用户操作
[即时聊天] [发私信] [加为好友]
谢廷宝ID:sodme
376235次访问,排名140好友274人,关注者307

倡导并实践着:开发者应具备团队观和大产品观,崇尚实效至上的开发观,不唯技术论,不唯权威论,不畏惧任何困难,不丢下任一战友。

愿广泛结交同秉此理念的志同道合者,可以通过CSDN个人空间加我为好友,或者选择“关注”我。
sodme的文章
原创 132 篇
翻译 0 篇
转载 22 篇
评论 198 篇
大宝(sodme)的公告
我的网易博客:
http://sodme.dev.blog.163.com
GT&mail: sodme.dev#gmail.com
msn: sod_me#hotmail.com

我们的理念:
以市场作产品,以产品作技术。

1. 积极面对自己的工作和生活,是一种有百利而无一害的态度;

2. 不唯技术论,可以让你站在更高的层面去思考更多全局性的东西,而这些东西更直接地影响着产品成败和你个人的发展;

3. 我们希望的是,做一款成功的产品,而不仅仅是做一项成功的技术,如果技术与产品可以合起来当然更好,如果不能,那明智的选择当然是产品;

4. 知识型工作者,要学会自我管理,没有了自我管理,知识型工人可能连一个搬砖工人的价值都顶不上。

最近评论
zatman:谢谢,受益匪浅哈~~~
supperwfy:google的网络框架服务是其精髓。
fjfqslg:看了你的文章受益匪浅,谢谢你,^_^
kissnsms:众所周知,CreateIoCompletionPort函数,有两个作用,一是“创建”一个完成端口,二是将一个socket与已经创建的完成端口句柄相“绑定”,绑定之后,基于该socket的收、发、断开等事件都可以被完成端口感知。

请教一下,如何感知断开?在不进行数据的收发的情况下,谢谢!
rjchen:同意"持续更新, 持续开发, 持续改善能力"的观点,我们现在也在朝这个方向努力,由一个月发布一个新版本,到争取半个月发布一个新版本,到一周发布一个新版本,通过来提高用户的响应速度和体验。
文章分类
收藏
相册
_我的其它站
My GooglePages
My Maillist
My MsnSpace
我的网易博客
非技术
TechWeb
东方宽频
中国企业史
叶蓉
吴晓波
圈子-圈套
士兵突击
多玩网
李书文
王冉
蓝狮子
赢在中国
郎咸平
马未都
存档
订阅我的博客
XML聚合  FeedSky

原创 对标号地址的另一种相对寻址方式收藏

新一篇: 高性能网络编程MailList 热点回顾 [1] | 旧一篇: 由一个vc内嵌asm的BUG引出的...

汇编程序中, 对数据访问时, 通常是这样的:

_asm{
...
DATA_LABLE:
    _emit 0x87
    _emit 0xa0
    _emit 0x49
    _emit 0x90
...

    mov ebx, dword ptr [DATA_LABLE]
...
}

其中, 当程序编译之后, mov指令中的DATA_LABLE标号地址会被转成一个绝对地址. 而有时绝对地址这一点可能会对这样一种需求带来障碍: 我们希望自己写的汇编代码不管被放在哪块地址空间中都是能正常运行的, 就象我们写高级语言中的那些函数一样, 函数位置可以被随意放置, 丝毫不会影响函数本身的功能使用. 当然, 不得不指出的是, 尽管要求的是同样功能, 但汇编与高级语言之间在这方面的实现却相去甚远. 高级语言的函数在最终被编译之后, 其函数地址也是固定的绝对地址, 而我们所想要用汇编实现的才是真正的"可被任意放置"的二进制执行块.

借用call指令, 可以实现运行期标号地址的相对寻址, 大致的思路如下:

_asm{
...
    call FUNC_START
FUNC_START:
    pop ebx
    sub ebx, offset FUNC_START
    mov [ebp-xx], ebx
...

DATA_LABLE:
    _emit 0x87
    _emit 0xa0
    _emit 0x49
    _emit 0x90

...
    mov eax, [ebp-xx]
    mov ebx, dword ptr [DATA_LABLE+eax]
...

}

步骤是这样的:

1.首先, 在汇编功能块或函数首部, 使用以下语句取得运行期地址与编译地址的修正差值.
    call FUNC_START
FUNC_START:
    pop ebx
    sub ebx, offset FUNC_START
    mov [ebp-xx], ebx

略作解释: call 函数会将eip寄存器压入堆栈, 之后用"pop ebp"是将eip值赋给ebp, 而eip表示的是"下一条语句的地址", 在这里, 当程序运行到"call FUNC_START"时, 它表示的是以标号"FUNC_START:"开始的"pop ebx"指令起始地址. 而另一方面, sub指令中的"offset FUNC_START", 在编译时, offset会被转成一个绝对地址. 这样,通过sub操作, 就获得了此段代码在编译期和运行期关于指令地址的修正值. 下面的这句: "mov [ebp-xx], ebx", 实际上只是锦上添花, 它把这个值保存在了某一个自定义的函数局部变量空间内, 以备后续语句方便引用.

2.相应的, 对标号数据的引用就变成这样的两句:
    mov eax, [ebp-xx]
    mov ebx, dword ptr [DATA_LABLE+eax]

对于汇编函数中的此类代码进行这样的处理后, 此段二进制执行块就可以被放置在任意地方而不致因为对DATA_LABLE数据地址的错误引用造成程序错误.

发表于 @ 2006年05月25日 23:18:00|收藏

新一篇: 高性能网络编程MailList 热点回顾 [1] | 旧一篇: 由一个vc内嵌asm的BUG引出的...

评论:没有评论。

Csdn Blog version 3.1a
Copyright © 大宝(sodme)