system888net 发表于 2008-04-23 12:45

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

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

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

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

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

cjaizss 发表于 2008-04-23 15:19

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

system888net 发表于 2008-04-23 15:24

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

所言极是.

chzCPU 发表于 2008-04-23 15:34

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

:wink: 顶...

dxcnjupt 发表于 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          nopnopnopnop call 1000h
编译--反编译对比一下机器码.

cjaizss 发表于 2008-04-23 16:13

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

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

main()
{
      printf("%d\n",func2(1));
}


编译
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>

system888net 发表于 2008-04-23 16:41

原帖由 dxcnjupt 于 2008-4-23 15:55 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
没看懂楼主是什么意思,lz这个是masm的汇编??感觉LZ把32位的call指令弄错了.

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

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

dxcnjupt 发表于 2008-04-23 17:15

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

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

system888net 发表于 2008-04-23 18:13

回复 #9 dxcnjupt 的帖子

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

prolj 发表于 2008-04-23 19:21

:shock: 越来越关注LZ
64位很多第3方软件不能用,还没用64的OS,LZ竟然移植64位编译器。拜一个
页: [1] 2 3 4 5
查看完整版本: 32bit的编译器向64bit移植时要注意的一个小问题.