|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
最近接触到X64汇编,不得不说32位和64位汇编差别蛮大的。 不论内存模式, 寻址,还是参数传递都有很大差别,就连段寄存器在X64汇编中都没用了,当然为了兼容32位平台,还是保留了段寄存器。 先说AMD平台提供的运行模:
1、长模式
(1)、64位模式
(2)、兼容模式
2、遗留模式(听名字就知道以后要扔掉)
(1)、实模式
(2)、保护模式
(3)、虚拟8086模式
首先当然必须的,AMD64平台是兼容16位和32位模式的,但是它不叫兼容模式,而是用了一个遗留模式的名字,等将来CPU结构越来越复杂,Intel,AMD这些公司估计就会考虑解决一些历史遗留问题了。 遗留模式其实就是一个32位的CPU,在遗留模式下编程看到的就是IA32的体系结构。
遗留模式我们虽然熟悉,但是重点不是这个,长模式才是重点。长模式顾名思义就是64位了,它有两个子模式,分别是64位模式和兼容模式,听起来可能有点绕,单它就是起了这样一个淡疼的名字。说明白一点,就是64位系统就运行于长模式下,其他的就是遗留模式。但是要在64位系统下运行32位程序,就进入兼容模式,但没提供16位模式。这么说懂了吧。这就是为什么64位win7下不能运行16位程序,但32位的win7却可以的原因。
下面是64位平台的特点,如果连32位平台都不了解,先自行补习吧,限于篇幅就不写了
1、寄存器
当CPU运行于长模式下,可用的寄存器有极大的扩展,首先,32位下的8个通用寄存器全部扩展成64位EXX->RXX,比如EAX成了RAX,并增加了R8-R15 8个额外的通用寄存器。增加8个XMM寄存器,指令指针寄存器EIP扩展为64位的RIP
2、CPU 栈
长模式下push操作只针对64位数据。
3、参数传递
这是唯一在X64平台下反而变简单了的一个元素, 以前那些__stdcall,__cdecl,__fastcall,__thiscall,__nakedcall,__pascal什么的,统统扔掉,现在基本统一成一种方式----寄存器传参数(类似于fast call)。64位汇编的前4个参数分别用rcx,rdx,r8,r9来传递,如果超过4个参数,才会用到堆栈来传递,被调用者不会清理堆栈(这个似乎把任务交给编译器了,总不能让程序员手动把)。
4、内存模型
这里只讨论64位模式,在64位模式下段寄存器不再有用,不只是在用户级,在内核也不再有用了,这似乎是个好消息,内存通过分页机制直接映射为物理地址,这个真是喜大普奔,想以前被Intel的段机制弄得一团屎,到了32位Intel还是没舍得仍,现在终于是时候舍弃这个臃肿的机制了,建议大家不要纠缠段机制了,特别是32位的段机制,臃肿不堪,而且完全可以不用就实现内存保护,早就该扔了。不得不说Linux还是有远见,设计的时候就巧妙地绕过了Intel的段机制,直接将所有段描述符置为0,都从00000000h开始寻址。至于16位的段机制,系统启动必须要通过实模式进行跳转到更长的模式的准备工作,比如初始化32位模式的段描述符,编程8259A中断芯片,打开A20地址线之类的琐事。暂时还不能丢弃,但是也是迟早的事。
至于字节存储顺序,还是小端法,不谈。
这大概就是X64平台与32位平台的一些区别,当然这只是一小部分,还只是概览(看标题),关于编程细节的话,如果有人对X64编程感兴趣,以后再开贴吧
|
评分
-
查看全部评分
|