免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 17490 | 回复: 49
打印 上一主题 下一主题

32bit的编译器向64bit移植时要注意的一个小问题. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-23 12:45 |只看该作者 |倒序浏览
Intel CPU
当一个32bit的编译器向64bit移植时,要处理的地方有很多,以下是一个非常常见的指令在两个系统中的细微差别:

32bit
CALL DWORD PTR [N32]
这里调用的是地址为N32处的代码

64bit
address0: CALL DWORD PTR [N32]
这里调用的是地址为address0+N32处的代码

为何这样设计? 这样的好处是64bit与32bit的指令长度都是5byte,当然带来的麻烦是代码的单次跳转范围必须在2G内(一般都够用了),这是兼容带来的代价

评分

参与人数 1可用积分 +3 收起 理由
prolj + 3 一帖引出精彩讨论

查看全部评分

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2008-04-23 15:19 |只看该作者
兼容自然是要损失一些东西的,通用,就会损失效率、存储,不通用,就可以提高效率、存储。使用STL自然不可能有你为特定项目特意设计的算法效率高(当然,前提是设计者不是个棒槌)。编码的冗余问题。鱼与熊掌不可兼得,但是很多时候,兼容是至关重要的东西,只要别的损失并不离谱,会选择兼容

论坛徽章:
0
3 [报告]
发表于 2008-04-23 15:24 |只看该作者
原帖由 cjaizss 于 2008-4-23 15:19 发表
兼容自然是要损失一些东西的,通用,就会损失效率、存储,不通用,就可以提高效率、存储。使用STL自然不可能有你为特定项目特意设计的算法效率高(当然,前提是设计者不是个棒槌)。编码的冗余问题。鱼与熊掌不 ...


所言极是.

论坛徽章:
0
4 [报告]
发表于 2008-04-23 15:34 |只看该作者
原帖由 cjaizss 于 2008-4-23 15:19 发表
兼容自然是要损失一些东西的,通用,就会损失效率、存储,不通用,就可以提高效率、存储。使用STL自然不可能有你为特定项目特意设计的算法效率高(当然,前提是设计者不是个棒槌)。编码的冗余问题。鱼与熊掌不 ...


:wink: 顶...

论坛徽章:
0
5 [报告]
发表于 2008-04-23 15:55 |只看该作者
没看懂楼主是什么意思,lz这个是masm的汇编??感觉LZ把32位的call指令弄错了.

call指令的几种区别.
relative是以当前指令结束时的EIP为参考地址,absolute指绝对地址.
rel32=立即数
r32=寄存器
m32=内存访问(指针)
机器码  指令               说明
E8 cd    CALL   rel32         Call near, relative, displacement relative to next instruction
FF /2     CALL   r/m32       Call near, absolute indirect, address given in r/m32
9A cp    CALL   ptr16:32   Call far, absolute, address given in operand
FF /3     CALL   m16:32    Call far, absolute indirect, address given in m16:32
表格取自intel开发者文档第二卷的指令手册
也就是说
call function  相对地址
mov eax,function
call   eax       绝对地址

不要看到call c000000h就以为是绝对跳转,汇编器会做地址转换,并且生成一个重定位项,链接器在链接时对其进行重定位.
可以做一个简单的实验.
test1.asm          call 1000h
test2.asm          nop  nop  nop  nop call 1000h
编译--反编译对比一下机器码.

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2008-04-23 16:13 |只看该作者
其实编码到机器语言,还是相对地址偏移。

  1. int func(int i){return i+1;}
  2. int func2(int i) {
  3.         return func(i)+2;
  4. }

  5. main()
  6. {
  7.         printf("%d\n",func2(1));
  8. }

复制代码

编译
gcc -c 1.c
gcc 1.o
然后
objdump -D 1.o

  17:   e8 fc ff ff ff          call   18 <func2+0xd>
objdump -D a.out
则有
080483b4 <func>:
...
80483cb:       e8 e4 ff ff ff          call   80483b4 <func>

论坛徽章:
0
7 [报告]
发表于 2008-04-23 16:41 |只看该作者
原帖由 dxcnjupt 于 2008-4-23 15:55 发表
没看懂楼主是什么意思,lz这个是masm的汇编??感觉LZ把32位的call指令弄错了.

call指令的几种区别.
relative是以当前指令结束时的EIP为参考地址,absolute指绝对地址.
rel32=立即数
r32=寄存器
m32=内存访问 ...


在masm中
Call   dword   ptr   [N32] 子程的入口地址在内存   ds:[N32]   处的双字

论坛徽章:
0
8 [报告]
发表于 2008-04-23 17:15 |只看该作者
抱歉,我masm不熟.........

这样确实是绝对地址,属于call m32格式,相当于c里面用函数指针.

论坛徽章:
0
9 [报告]
发表于 2008-04-23 18:13 |只看该作者

回复 #9 dxcnjupt 的帖子

大侠也是一内行,希望能多多交流! :wink:

论坛徽章:
0
10 [报告]
发表于 2008-04-23 19:21 |只看该作者
越来越关注LZ
64位很多第3方软件不能用,还没用64的OS,LZ竟然移植64位编译器。拜一个
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP