32bit的编译器向64bit移植时要注意的一个小问题.

发布于 2022-09-19 16:02:35 字数 322 浏览 19 评论 0

Intel CPU
当一个32bit的编译器向64bit移植时,要处理的地方有很多,以下是一个非常常见的指令在两个系统中的细微差别:

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

孤檠 2022-09-26 16:02:35

兼容自然是要损失一些东西的,通用,就会损失效率、存储,不通用,就可以提高效率、存储。使用STL自然不可能有你为特定项目特意设计的算法效率高(当然,前提是设计者不是个棒槌)。编码的冗余问题。鱼与熊掌不可兼得,但是很多时候,兼容是至关重要的东西,只要别的损失并不离谱,会选择兼容

冷血 2022-09-26 16:02:35

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

所言极是.

北方的巷 2022-09-26 16:02:35

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

:wink: 顶...

南巷近海 2022-09-26 16:02:35

没看懂楼主是什么意思,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
编译--反编译对比一下机器码.

递刀给你 2022-09-26 16:02:35

其实编码到机器语言,还是相对地址偏移。

  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>

把人绕傻吧 2022-09-26 16:02:35

原帖由 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]   处的双字

放肆 2022-09-26 16:02:35

抱歉,我masm不熟.........

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

零度℉ 2022-09-26 16:02:35

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

逆光下的微笑 2022-09-26 16:02:35

越来越关注LZ
64位很多第3方软件不能用,还没用64的OS,LZ竟然移植64位编译器。拜一个

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文