-
-
[转帖]Intel的64位扩展技术简介 与 AMD64结构和软件接口
-
发表于: 2005-6-30 16:51 6651
-
64位时代己来到了,虽然普及还需时日,不过也就在这1、2年了。
看到一篇64位相关文章,对我们了解64位有一些帮助,故转载过来。
======================================================
建议看原文,格式清楚些:256K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4W2S2L8X3N6I4M7#2)9J5k6h3&6W2j5i4y4W2i4K6u0W2L8X3g2@1i4K6u0r3K9r3q4J5k6s2N6S2M7X3g2Q4x3V1k6A6j5g2)9J5k6o6x3J5k6i4c8W2j5$3S2Q4x3X3g2Z5N6r3@1`.
Intel的64位扩展技术简介
杨全胜翻译
【译者注】Intel公司在IDF2004上展示了他们的IA-32e架构新的处理器,这是一个利用兼容IA-32架构的64位扩展技术开发的64位微处理器,为
了让大家尽早了解该项技术,本人特根据Intel公司提供的64-Bit Extension Technology Software Developer's Guide的部分内容翻译编辑了
本文。
一、操作模式
具有64位扩展技术的处理器能运行在传统IA-32模式或IA-32e模式。传统的IA-32模式允许处理器运行在保护模式、实地址模式或虚拟8086
模式。
IA-32E模式是处理器在运行64位操作系统的时候使用的一种模式。带有64位扩展技术的处理器将初始进入传统的、页式地址、保护模式,
然后,当IA32-EFER寄存器中的某位被设置并且PAE(Physical Address Extensions,物理地址扩展)模式被使能。下表显示了64位扩展技术所支
持的操作模式和他们之间的区别。
1.IA-32e模式
IA-32e模式有两个子模式:64位模式和兼容模式。IA-32e模式只能在装载64位操作系统的情况下进入。
2.64位模式
64位模式用于运行在64位操作系统中的64位应用程序它支持以下的特性:
支持64位线性地址结构;然而支持64位扩展技术的IA-32处理器将用少于64位地址来实现
寄存器扩展后,可以使用新的操作码前缀来访问(REX)
现有的通用寄存器被加宽到64位(RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP)
8个新的通用寄存器(R8?R15)
8个新的128位流SIMD扩展(SSE)寄存器(XMM8?XMM15)
一个64位的指令指针(RIP)
一个新的RIP相关数据寻址模式
对单一的代码、数据和栈空间能用平板地址空间
扩展的和新的指令
支持大于64GB的物理地址;然而支持64位扩展技术的IA-32处理器的实际物理地址要特殊实现
新的中断优先级控制机制
64位模式能够在以代码段为基础的操作系统中被使用。它的缺省地址大小是64位;它的缺省操作宽度大小是32位。注意这些缺省设置能够
在使用新的REX操作码前缀的指令-指令对中被超越。当操作在64位模式下时,REX前缀允许指定一个64位操作数。利用这个机制,很多现有的
指令被修改或重新定义来允许使用64位寄存器和64位地址。
3.兼容模式
兼容模式允许传统的16位和32位应用程序无需重新编译就可以运行在64位操作系统下(然而运行在虚拟8086模式下或使用硬件任务管理中
的传统应用程序将无法工作)。就像64位模式那样,操作系统在一个专门的代码段使能兼容模式。这意味着64位应用程序能运行在处理器中(6
4位模式)的同时,32位应用程序(没有为64位重编译的)运行再兼容模式。
兼容模式像传统的保护模式。应用程序只能存取线性地址空间中的第一个4GB,处理标准IA-32指令前缀和寄存器。在兼容模式下不提供REX
前缀。(REX前缀编码已经处理成传统IA-32指令)兼容模式也必须使用16位和32位地址和操作数。和传统保护模式一样,兼容模式也允许应用
程序使用PAE(物理地址扩展)处理64GB的物理存储。
下列传统保护模式下的项目,在兼容模式下不支持。
虚拟8086模式,任务切换和栈参数拷贝特性在兼容模式下不可用
从操作系统的角度看:使用64位机制替代32位机制来处理系统数据结构,地址变换,中断和异常处理等结构和事务。
4.传统模式为什么Intel现在做这件事情?
传统模式包括保护模式,实地址模式和虚拟8086模式。现有的为这些模式中的任何一种模式而编写的软件都完全能兼容地运行在具有64为扩
展技术的IA-32处理器中。
5.系统管理模式
系统管理模式(SMM)提供与传统IA-32架构中的系统管理中断(SMI)处理程序相同的执行环境。SMM支持从一个模式到另一个操作模式(包
括IA-32e和传统模式)的转换。一个SMI处理程序能够通过PSE机制处理任何的物理存储页。然而由于不支持PAE,SMM环境不支持64位线性地址
。提交给SMI的事务,处理器将转换到SMM,并根据SMM存储映射(save map)将存储器的状态存储到SM RAM中。因此,一个SMI处理程序将执行
在和传统IA-32架构中一样的环境中。
二、寄存器组的改变
下表比较了运行在64位模式的应用程序和运行在传统的IA-32环境的应用程序中寄存器数据结构的不同。传统环境包括那些存在于现有IA-32处
理器、支持64位扩展技术的处理器中的传统模式以及IA-32e兼容模式中的环境。兼容模式应用程序不能在64位模式或64位操作系统中运行,因
此应用程序需要运行在传统IA-32保护模式环境中。
1.通用寄存器(General-Purpose Registers,GPRs)
IA-32结构运行在传统或兼容模式时,有8个通用寄存器。AX, BX, CX, DX, DI, SI, BP, SP对16位操作数有效,EAX, EBX, ECX, EDX,
EDI, ESI, EBP, ESP对32位操作数有效。
在64位模式,缺省的操作数是32位的,然而GPRs可以针对32位和64位操作数。如果是32位操作数 EAX, EBX, ECX, EDX, EDI, ESI, EBP,
ESP, R8D - R15D可用,如果是64位操作数RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8-R15可用,R8-R15是8个新的GPRs。所有的这些寄存
器能够具有字节、字、双字和四字四个级别。这些级别的划分主要是看REX前缀。
在64位模式,将限制指令存取字节寄存器,指令不能同时使用传统的高字节(比如AH, BH. CH, DH)和新的字节寄存器(比如RAX寄存器的
低字节)。然而指令将可同时用传统低字节(比如AL,BL,CL或DL)和新的字节寄存器(比如R8寄存器或RBP)。这种结构将强迫大家遵守以上的
限制,并将任何代REX前缀的指令对高字节(AH, BH, CH, DH)的使用转换到低字节(BPL, SPL, DIL, SIL; 这些是RBP,R SP, RDI 和 RSI的低8位
) 的使用。
在64位模式下,操作数的大小决定了目标GPR的有效位数:
64位操作数产生一个64位的结果到目标通用寄存器
32位操作数产生32位的结果,采用0-扩充的方法将64位结果写到目标通用寄存器
8位和16位操作数产生一个8位或者16位的结果。目标通用寄存器的高56位或48位在操作中不会被修改。如果一个8位或16位操作数的结果被用作
64位地址计算,则会对其进行符号扩展,扩展到64位。
因为64位通用寄存器的高32位在32位模式中没有定义,所以当从64位模式转换到任何一种32位模式(比如传统模式或兼容模式)时,高32
位的数据将不被保留。同样,在64位转换到32位模式之后,软件也不必要用这些没有定义的高字节位来存放数据。这些值回从一个硬件实现转
换到下一个,或从一个周期转换到下一个。
2.流SIMD扩展(SSE)寄存器
在兼容和传统模式下,SSE寄存器组由8个128位的传统寄存器XMM0-XMM7组成。在64位模式,有了8个附加的128位SSE寄存器,XMM8-XMM15。
通过使用REX指令前缀访问这些存储器。XMM寄存器能够在任何模式下,在SSE, SSE2, SSE3指令中使用。
3.系统寄存器
64位引入新的寄存器也改变了现有的系统寄存器。他们是:
MSRs.扩展特性允许MSR(IA-32_EFER)包含控制,允许与禁止64位扩展技术特性的那些位
控制寄存器。所有的控制寄存器扩充到64位,增加了一个新的控制寄存器(任务优先级寄存器CR8或TPR)
描述符表寄存器。全局描述符表寄存器(GDTR)和中断描述符表寄存器(IDTR)被扩展到10字节,以便他们能够包含全部64位地址。局部描述符
表寄存器(LDTR)和任务寄存器也别扩展来包含64位地址。
调试寄存器。调试寄存器扩展到64位。
1)扩展特性允许寄存器(IA-32_EFER)
扩展特性语序寄存器(IA-32_EFER)包含处理器扩展特性控制位。该寄存器在地址C0000080H。下表是该寄存器的各位细节。
LMA(IA-32e模式激活,位10):该位是只读状态位,任何对该位的写入操作都将会被忽略。当IA-32e模式和页式管理被允许后,处理器将该位
置1,这表明处理器运行在兼容模式或64位模式,具体在那个模式就要看代码段描述符的L位和D位的值。LMA=0时,处理器运行在传统模式,在
这个模式下,处理器处理器的行为如同标准32位的IA-32处理器。
LME(IA-32e模式允许,位8):设置该位为1可以使处理器的能力转换到IA-32e模式,但是IA-32e模式并没有真正被激活,只有当软件使能PAE
模式进行页式管理。当PAE页式管理被允许,并且LME被设置为1,处理器将设置LMA位为1,这指明IA-32e模式不仅被允许,同时被激活。IA32_E
FER的其他所有保留位必须位0。
SCE(Syscall/Sysret允许,位0):这位设置为1将支持Syscall/Sysret。Syscall/Sysret只在64为模式下被支持。操作系统负责为64位操作来
使能它。
2)控制寄存器
控制机存器CR0-CR4在64位扩展模式下被扩展到64位。在64位模式,MOV CRn指令读或写这些寄存器的全部64位。操作数宽度前缀被忽略。
兼容和传统模式,控制寄存器的高32位被全部填0,读控制寄存器也只返回低32位。
在64位模式,CR0和CR4的高32位被保留并且必须被写0。对高32位的任何一位进行写的结果是引起一般性保护异常,#GP(0)。CR2的所有
64位都可通过软件来写。CR3的位[51:40]被保留,必须为0。然而MOV CRn指令不检查写到CR2或CR3的地址是否在线性地址或物理地址的实现界
限内。
64为扩展结构引入了一个新控制寄存器―CR8,它被定义为任务优先级寄存器(TPR)。操作系统能够基于中断的优先级别,使用TPR来控制
是否允许外部中断来中断处理器。
3)描述符表寄存器
四个系统描述符表寄存器(GDTR, IDTR, LDTR和TR) 被扩展到能容下64位基地址。这允许运行在IA-32e模式的操作系统能够将描述符表定位
在可用的线性地址空间的任何地方。下表给出了这四个寄存器。在所有的情况下,基地址必须符合范式。线性和物理地址位数能够用执行CPUID
通过EAX设置80000008H来决定。
4)调试寄存器
在64位模式下,调试寄存器DR0-DR7是64位的。MOV DRn指令读或写所有的64个寄存器位。操作数宽度前缀被忽略。
在IA-32e平台上所有16位模式或32位模式(传统模式或兼容模式)写调试寄存器时高32位全部填0,读调试寄存器的时候只返回低32位。
在64位模式下,DR6和DR7的高32位保留并必须是0,对高32位的任何一位写1都会引发#GP(0)异常。
DR0-DR3的所有64位都是软件能写的。然而MOV DRn指令不检查写到DR0-DR3的地址在线性地址的限制内。只在处理器产生有效地址的时候支
持地址匹配。
三、指令集变化
1.地址宽度和操作数宽度前缀
64位模式中,缺省的地址宽度是64位,缺省的操作数宽度是32位。地址宽度和操作数宽度前缀允许32位和64位数据和地址在指令序列中混
用。下表(1-7)显示了在IA-32e模式下需要指令前缀地址宽度。注意,在64位模式下不支持16位地址。在敬爱内容和传统模式下,地址宽度
函数的功能和在IA-32传动架构中一样。
下表(1-8)显示了66H指令前缀和REX.W前缀的有效组合来指定IA-32e操作模式下的操作数宽度问题。
在64位模式下, 缺省的操作数宽度是32位,REX前缀包括4位域来指定16个不同的值。REX前缀的W位域指定为REX.W。REX.W=1时前缀表明
操作数位64为操作数。注意,软件依然能使用操作数宽度66H前缀来切换到16位操作宽度。然而如果同时用REX.W和66H前缀,REX.W的优先权要
高。
在SSE/SSE2/SSE3 SIMD指令的情况下,66H, F2H和F3H前缀作为操作码扩展,并被认为是指令的一部分。在这些情况下,有效的REX.W前缀
和66H代码扩展前缀之间没有相互关系。
2.REX前缀
REX前缀是64位模式下引入的新的指令前缀字节,他作以下工作:
指定新的GPRs和SSE寄存器
指定64位代码宽度
指定扩展的控制寄存器(只给系统软件使用)
不是所有的指令都需要REX前缀。这个前缀只在指令引用扩展的寄存器或使用64位操作数的时候才有必要。如果该前缀放在不需要的地方将
会被忽略。
一个指令只能有一个REX前缀。这个前缀一旦使用,就必须直接放在操作码字节或两字节操作码扩展前缀之前。 其他位置的REX前缀将被忽略。
包含有REX前缀的指令依然要遵循传统的15字节的指令宽度的限制。下图描述了REX前缀如何符合指令的字节次序的。
3.控制和调试寄存器的新编码
在64位模式下,有为控制机存器和调试寄存器指定的附加的编码。当ModRM寄存器的域编码一个控制或调试寄存器的时候,REX.R位被用来
修改这些域。这些编码允许处理器访问CR8-CR15和DR8-DR15。
在64位模式中附加了一个控制寄存器(CR8)。CR8成为任务优先级寄存器(TPR)。在IA-32e技术的首次实现的时候,CR9-CR15和DR8-DR15
都没有实现,对它们的访问将引起无效代码异常(#UD)。
4.新的指令
下面的新指令在带有64位扩展的64位模式下被引入。
SWAPGS 指令
SYSCALL and SYSRET 指令
CDQE 指令
CMPSQ 指令
CMPXCHG16B 指令
LODSQ 指令
MOVSQ 指令
MOVZX(64-bits) 指令
STOSQ 指令
5.堆栈指针
在64位模式,堆栈指针为64位。堆栈大小不是像兼容模式或传统模式中那样靠SS段描述符中的某位来控制,也不通过指令前缀来指示。
对隐式堆栈引用将忽略地址大小的指示。除远分支以外,所有隐式引用RSP的指令在64位模式下缺省为64位操作数。影响到的指令包括:PUSH,
POP, PUSHF, POPF, ENTER, 和LEAVE。使用这些指令在64位模式下将不可能产生32位堆栈值的压栈和退栈。如果使用66H操作数前缀,将支持16
位的压栈和退栈。
当寄存器RAX-RSP被用作操作数的时候,64位模式缺省的操作尺寸无需REX前缀作为这些指令的先导。如果式R8-R15作为操作数,则REX依
然是需要的。这是因为前缀在访问新扩展寄存器中是需要的。
6.分支转移
64位扩展技术扩充2个分支机制来适应64位线性地址空间的分支。他们是:
64位模式下近分支转移被重新定义
在64位模式和兼容模式下,64位调用门描述符定义成远调用
64位模式下,所有近分支转移(CALL, RET, JCC, JCXZ, JMP 和 LOOP)被强迫为64位。这些指令被更新为提供64位的RIP值而无需REX前缀。
下面的近转移被有效的操作数宽度所控制:
指令指针的宽度的截断
由于CALL或RET引起的退栈压栈或退栈的大小
由于CALL或RET而引起的堆栈指针增加或减少的大小
间接转移操作数大小
在64位模式下,以上的所有操作都被强制为64位而不管操作数前缀(操作数大小的前缀被忽略)。然而相对转移的位移区域依然受到32位
的限制;近转移的地址大小没有被强制为64位。
地址大小影响到JCXZ和LOOP中RCX的大小;他们也影响到内存间接转移的地址计算。这样的地址缺省是64位,但是他们可以通过地址宽度前
缀转换到32位宽度。
软件会用远转移来改变优先级。传统IA-32结构提供调用门机制来允许软件去从一个优先级转到另一个优先级,尽管调用门也可以不改变优
先级而只是做转移。当调用门使用的时候,直接或间接的选择器指针会指向一个门描述符(指令重的便宜被忽略)目的代码段的偏移可以从调
用门描述符中获得。IA-32e模式重新定义了32位调用门描述符的类型值,使其成为64位调用门描述符,并扩展64位描述符使其能够容纳64位的
偏移。64位模式调用门描述符允许远转移访问有效的线性地址空间的任何地方。这些调用门也控制代码段选择器(CS),允许转换到特权级和缺
省尺寸并作为门转换的结果。
因为通常情况下是指定32位的,唯一在64位模式下指定完全64位绝对RIP的是间接分支转移,由于这个原因,直接远分支转移被从64位模式
的指令集中删除了。
IA-32e模式扩充了SYSENTER和SYSEXIT指令的语义,以便他们操作在64位存储空间。IA-32e也引入了两个新的指令:SYSCALL和SYSRET,他
们只在64位模式有效。
四、存储组织
1.64位模式下的地址计算
在64位模式(如果没有地址大小的转变),有效地址计算的大小是64位的。一个有效地址计算使用一个64位的基和索引寄存器以及符号扩
展变换成64位。
对于64位模式下平面地址空间,线性地址等同于有效地址。在使用FS和GS段的非0为基的事务中,这个规则不被使用。在64位模式下,有效
地址成分被加进来,并且有效地址在加64位基地址之前被缩短。地址映射模式在64位模式时,基地址从不会被缩短。
在IA-32e模式下,指令指针被扩展到64位来支持64位代码偏移。64位指令指针在调用中将值赋给RIP。下表描述了RIP、EIP和IP之间的不同
。
通常,替换和直接在64位模式下不被扩展到64位。他们在有效地址计算中依然被限制在32位和符号扩展。然而,在64位模式提供了MOV指令
的64位替换和直接形式的支持。
所有的在IA-32e模式下的16位和32位地址计算用0扩展来形成64位地址。地址计算搜现是缩短到当前模式的有效地址宽度,就像地址宽度前
缀的指定那样。其结果是用0扩展得到完全的64位地址宽度。因为这个,16位和32位应用程序运行在兼容模式只能存取64位模式有效地址的低4G
B。同样,在64位模式产生一个32位地址只能访问64位模式有效地址的低4GB。
2.规范的寻址
一个规范形式的地址有地址位63直到更有效的实现位,宏结构设置其为全1或全0。
IA-32e模式定义一个64位的线性地址,但实现的时候支持的位数要少些。第一个具有64位扩展技术的IA-32e结构的处理器将支持48位线性
地址。这意味着规范的地址必须将位63到位48全填0或全填1,填0还是填1要看位47是0还是1。
尽管实现并不用先行地址的全部64位,他们需要检查位63知道更有效的实现位来看是否地址是规范形式。如果一个线性存储引用不是规范
形式,该实现将会产生一个异常。在很多情况下,会产生一个一般保护异常(#GP)。然而,在显示或隐式对战应用的情况下,会产生一个堆
栈错(#SS)。隐式堆栈引用指令包括PUSH/POP指令和使用RSP/RBP寄存器来作为缺省堆栈段寄存器的指令。在这些情况下,一个规范错误式#
SF,如果一个指令使用RSP/RBP作为基寄存器并且有段超越给出一个非SS段,将引起一个一般保护错误(#GP)的规范错误。隐式堆栈引用包括
所有PUSH/POP类型指令和任何使用RSP或RBP作为一个基寄存器。规范地址形式的检查将在特权检查之后页面和边界检查之前完成。
看到一篇64位相关文章,对我们了解64位有一些帮助,故转载过来。
======================================================
建议看原文,格式清楚些:256K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4W2S2L8X3N6I4M7#2)9J5k6h3&6W2j5i4y4W2i4K6u0W2L8X3g2@1i4K6u0r3K9r3q4J5k6s2N6S2M7X3g2Q4x3V1k6A6j5g2)9J5k6o6x3J5k6i4c8W2j5$3S2Q4x3X3g2Z5N6r3@1`.
Intel的64位扩展技术简介
杨全胜翻译
【译者注】Intel公司在IDF2004上展示了他们的IA-32e架构新的处理器,这是一个利用兼容IA-32架构的64位扩展技术开发的64位微处理器,为
了让大家尽早了解该项技术,本人特根据Intel公司提供的64-Bit Extension Technology Software Developer's Guide的部分内容翻译编辑了
本文。
一、操作模式
具有64位扩展技术的处理器能运行在传统IA-32模式或IA-32e模式。传统的IA-32模式允许处理器运行在保护模式、实地址模式或虚拟8086
模式。
IA-32E模式是处理器在运行64位操作系统的时候使用的一种模式。带有64位扩展技术的处理器将初始进入传统的、页式地址、保护模式,
然后,当IA32-EFER寄存器中的某位被设置并且PAE(Physical Address Extensions,物理地址扩展)模式被使能。下表显示了64位扩展技术所支
持的操作模式和他们之间的区别。

1.IA-32e模式
IA-32e模式有两个子模式:64位模式和兼容模式。IA-32e模式只能在装载64位操作系统的情况下进入。
2.64位模式
64位模式用于运行在64位操作系统中的64位应用程序它支持以下的特性:
支持64位线性地址结构;然而支持64位扩展技术的IA-32处理器将用少于64位地址来实现
寄存器扩展后,可以使用新的操作码前缀来访问(REX)
现有的通用寄存器被加宽到64位(RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP)
8个新的通用寄存器(R8?R15)
8个新的128位流SIMD扩展(SSE)寄存器(XMM8?XMM15)
一个64位的指令指针(RIP)
一个新的RIP相关数据寻址模式
对单一的代码、数据和栈空间能用平板地址空间
扩展的和新的指令
支持大于64GB的物理地址;然而支持64位扩展技术的IA-32处理器的实际物理地址要特殊实现
新的中断优先级控制机制
64位模式能够在以代码段为基础的操作系统中被使用。它的缺省地址大小是64位;它的缺省操作宽度大小是32位。注意这些缺省设置能够
在使用新的REX操作码前缀的指令-指令对中被超越。当操作在64位模式下时,REX前缀允许指定一个64位操作数。利用这个机制,很多现有的
指令被修改或重新定义来允许使用64位寄存器和64位地址。
3.兼容模式
兼容模式允许传统的16位和32位应用程序无需重新编译就可以运行在64位操作系统下(然而运行在虚拟8086模式下或使用硬件任务管理中
的传统应用程序将无法工作)。就像64位模式那样,操作系统在一个专门的代码段使能兼容模式。这意味着64位应用程序能运行在处理器中(6
4位模式)的同时,32位应用程序(没有为64位重编译的)运行再兼容模式。
兼容模式像传统的保护模式。应用程序只能存取线性地址空间中的第一个4GB,处理标准IA-32指令前缀和寄存器。在兼容模式下不提供REX
前缀。(REX前缀编码已经处理成传统IA-32指令)兼容模式也必须使用16位和32位地址和操作数。和传统保护模式一样,兼容模式也允许应用
程序使用PAE(物理地址扩展)处理64GB的物理存储。
下列传统保护模式下的项目,在兼容模式下不支持。
虚拟8086模式,任务切换和栈参数拷贝特性在兼容模式下不可用
从操作系统的角度看:使用64位机制替代32位机制来处理系统数据结构,地址变换,中断和异常处理等结构和事务。
4.传统模式为什么Intel现在做这件事情?
传统模式包括保护模式,实地址模式和虚拟8086模式。现有的为这些模式中的任何一种模式而编写的软件都完全能兼容地运行在具有64为扩
展技术的IA-32处理器中。
5.系统管理模式
系统管理模式(SMM)提供与传统IA-32架构中的系统管理中断(SMI)处理程序相同的执行环境。SMM支持从一个模式到另一个操作模式(包
括IA-32e和传统模式)的转换。一个SMI处理程序能够通过PSE机制处理任何的物理存储页。然而由于不支持PAE,SMM环境不支持64位线性地址
。提交给SMI的事务,处理器将转换到SMM,并根据SMM存储映射(save map)将存储器的状态存储到SM RAM中。因此,一个SMI处理程序将执行
在和传统IA-32架构中一样的环境中。
二、寄存器组的改变
下表比较了运行在64位模式的应用程序和运行在传统的IA-32环境的应用程序中寄存器数据结构的不同。传统环境包括那些存在于现有IA-32处
理器、支持64位扩展技术的处理器中的传统模式以及IA-32e兼容模式中的环境。兼容模式应用程序不能在64位模式或64位操作系统中运行,因
此应用程序需要运行在传统IA-32保护模式环境中。

1.通用寄存器(General-Purpose Registers,GPRs)
IA-32结构运行在传统或兼容模式时,有8个通用寄存器。AX, BX, CX, DX, DI, SI, BP, SP对16位操作数有效,EAX, EBX, ECX, EDX,
EDI, ESI, EBP, ESP对32位操作数有效。
在64位模式,缺省的操作数是32位的,然而GPRs可以针对32位和64位操作数。如果是32位操作数 EAX, EBX, ECX, EDX, EDI, ESI, EBP,
ESP, R8D - R15D可用,如果是64位操作数RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8-R15可用,R8-R15是8个新的GPRs。所有的这些寄存
器能够具有字节、字、双字和四字四个级别。这些级别的划分主要是看REX前缀。
在64位模式,将限制指令存取字节寄存器,指令不能同时使用传统的高字节(比如AH, BH. CH, DH)和新的字节寄存器(比如RAX寄存器的
低字节)。然而指令将可同时用传统低字节(比如AL,BL,CL或DL)和新的字节寄存器(比如R8寄存器或RBP)。这种结构将强迫大家遵守以上的
限制,并将任何代REX前缀的指令对高字节(AH, BH, CH, DH)的使用转换到低字节(BPL, SPL, DIL, SIL; 这些是RBP,R SP, RDI 和 RSI的低8位
) 的使用。
在64位模式下,操作数的大小决定了目标GPR的有效位数:
64位操作数产生一个64位的结果到目标通用寄存器
32位操作数产生32位的结果,采用0-扩充的方法将64位结果写到目标通用寄存器
8位和16位操作数产生一个8位或者16位的结果。目标通用寄存器的高56位或48位在操作中不会被修改。如果一个8位或16位操作数的结果被用作
64位地址计算,则会对其进行符号扩展,扩展到64位。
因为64位通用寄存器的高32位在32位模式中没有定义,所以当从64位模式转换到任何一种32位模式(比如传统模式或兼容模式)时,高32
位的数据将不被保留。同样,在64位转换到32位模式之后,软件也不必要用这些没有定义的高字节位来存放数据。这些值回从一个硬件实现转
换到下一个,或从一个周期转换到下一个。
2.流SIMD扩展(SSE)寄存器
在兼容和传统模式下,SSE寄存器组由8个128位的传统寄存器XMM0-XMM7组成。在64位模式,有了8个附加的128位SSE寄存器,XMM8-XMM15。
通过使用REX指令前缀访问这些存储器。XMM寄存器能够在任何模式下,在SSE, SSE2, SSE3指令中使用。
3.系统寄存器
64位引入新的寄存器也改变了现有的系统寄存器。他们是:
MSRs.扩展特性允许MSR(IA-32_EFER)包含控制,允许与禁止64位扩展技术特性的那些位
控制寄存器。所有的控制寄存器扩充到64位,增加了一个新的控制寄存器(任务优先级寄存器CR8或TPR)
描述符表寄存器。全局描述符表寄存器(GDTR)和中断描述符表寄存器(IDTR)被扩展到10字节,以便他们能够包含全部64位地址。局部描述符
表寄存器(LDTR)和任务寄存器也别扩展来包含64位地址。
调试寄存器。调试寄存器扩展到64位。
1)扩展特性允许寄存器(IA-32_EFER)
扩展特性语序寄存器(IA-32_EFER)包含处理器扩展特性控制位。该寄存器在地址C0000080H。下表是该寄存器的各位细节。

LMA(IA-32e模式激活,位10):该位是只读状态位,任何对该位的写入操作都将会被忽略。当IA-32e模式和页式管理被允许后,处理器将该位
置1,这表明处理器运行在兼容模式或64位模式,具体在那个模式就要看代码段描述符的L位和D位的值。LMA=0时,处理器运行在传统模式,在
这个模式下,处理器处理器的行为如同标准32位的IA-32处理器。
LME(IA-32e模式允许,位8):设置该位为1可以使处理器的能力转换到IA-32e模式,但是IA-32e模式并没有真正被激活,只有当软件使能PAE
模式进行页式管理。当PAE页式管理被允许,并且LME被设置为1,处理器将设置LMA位为1,这指明IA-32e模式不仅被允许,同时被激活。IA32_E
FER的其他所有保留位必须位0。
SCE(Syscall/Sysret允许,位0):这位设置为1将支持Syscall/Sysret。Syscall/Sysret只在64为模式下被支持。操作系统负责为64位操作来
使能它。
2)控制寄存器
控制机存器CR0-CR4在64位扩展模式下被扩展到64位。在64位模式,MOV CRn指令读或写这些寄存器的全部64位。操作数宽度前缀被忽略。
兼容和传统模式,控制寄存器的高32位被全部填0,读控制寄存器也只返回低32位。
在64位模式,CR0和CR4的高32位被保留并且必须被写0。对高32位的任何一位进行写的结果是引起一般性保护异常,#GP(0)。CR2的所有
64位都可通过软件来写。CR3的位[51:40]被保留,必须为0。然而MOV CRn指令不检查写到CR2或CR3的地址是否在线性地址或物理地址的实现界
限内。
64为扩展结构引入了一个新控制寄存器―CR8,它被定义为任务优先级寄存器(TPR)。操作系统能够基于中断的优先级别,使用TPR来控制
是否允许外部中断来中断处理器。
3)描述符表寄存器
四个系统描述符表寄存器(GDTR, IDTR, LDTR和TR) 被扩展到能容下64位基地址。这允许运行在IA-32e模式的操作系统能够将描述符表定位
在可用的线性地址空间的任何地方。下表给出了这四个寄存器。在所有的情况下,基地址必须符合范式。线性和物理地址位数能够用执行CPUID
通过EAX设置80000008H来决定。

4)调试寄存器
在64位模式下,调试寄存器DR0-DR7是64位的。MOV DRn指令读或写所有的64个寄存器位。操作数宽度前缀被忽略。
在IA-32e平台上所有16位模式或32位模式(传统模式或兼容模式)写调试寄存器时高32位全部填0,读调试寄存器的时候只返回低32位。
在64位模式下,DR6和DR7的高32位保留并必须是0,对高32位的任何一位写1都会引发#GP(0)异常。
DR0-DR3的所有64位都是软件能写的。然而MOV DRn指令不检查写到DR0-DR3的地址在线性地址的限制内。只在处理器产生有效地址的时候支
持地址匹配。
三、指令集变化
1.地址宽度和操作数宽度前缀
64位模式中,缺省的地址宽度是64位,缺省的操作数宽度是32位。地址宽度和操作数宽度前缀允许32位和64位数据和地址在指令序列中混
用。下表(1-7)显示了在IA-32e模式下需要指令前缀地址宽度。注意,在64位模式下不支持16位地址。在敬爱内容和传统模式下,地址宽度
函数的功能和在IA-32传动架构中一样。

下表(1-8)显示了66H指令前缀和REX.W前缀的有效组合来指定IA-32e操作模式下的操作数宽度问题。
在64位模式下, 缺省的操作数宽度是32位,REX前缀包括4位域来指定16个不同的值。REX前缀的W位域指定为REX.W。REX.W=1时前缀表明
操作数位64为操作数。注意,软件依然能使用操作数宽度66H前缀来切换到16位操作宽度。然而如果同时用REX.W和66H前缀,REX.W的优先权要
高。
在SSE/SSE2/SSE3 SIMD指令的情况下,66H, F2H和F3H前缀作为操作码扩展,并被认为是指令的一部分。在这些情况下,有效的REX.W前缀
和66H代码扩展前缀之间没有相互关系。

2.REX前缀
REX前缀是64位模式下引入的新的指令前缀字节,他作以下工作:
指定新的GPRs和SSE寄存器
指定64位代码宽度
指定扩展的控制寄存器(只给系统软件使用)
不是所有的指令都需要REX前缀。这个前缀只在指令引用扩展的寄存器或使用64位操作数的时候才有必要。如果该前缀放在不需要的地方将
会被忽略。
一个指令只能有一个REX前缀。这个前缀一旦使用,就必须直接放在操作码字节或两字节操作码扩展前缀之前。 其他位置的REX前缀将被忽略。
包含有REX前缀的指令依然要遵循传统的15字节的指令宽度的限制。下图描述了REX前缀如何符合指令的字节次序的。

3.控制和调试寄存器的新编码
在64位模式下,有为控制机存器和调试寄存器指定的附加的编码。当ModRM寄存器的域编码一个控制或调试寄存器的时候,REX.R位被用来
修改这些域。这些编码允许处理器访问CR8-CR15和DR8-DR15。
在64位模式中附加了一个控制寄存器(CR8)。CR8成为任务优先级寄存器(TPR)。在IA-32e技术的首次实现的时候,CR9-CR15和DR8-DR15
都没有实现,对它们的访问将引起无效代码异常(#UD)。
4.新的指令
下面的新指令在带有64位扩展的64位模式下被引入。
SWAPGS 指令
SYSCALL and SYSRET 指令
CDQE 指令
CMPSQ 指令
CMPXCHG16B 指令
LODSQ 指令
MOVSQ 指令
MOVZX(64-bits) 指令
STOSQ 指令
5.堆栈指针
在64位模式,堆栈指针为64位。堆栈大小不是像兼容模式或传统模式中那样靠SS段描述符中的某位来控制,也不通过指令前缀来指示。
对隐式堆栈引用将忽略地址大小的指示。除远分支以外,所有隐式引用RSP的指令在64位模式下缺省为64位操作数。影响到的指令包括:PUSH,
POP, PUSHF, POPF, ENTER, 和LEAVE。使用这些指令在64位模式下将不可能产生32位堆栈值的压栈和退栈。如果使用66H操作数前缀,将支持16
位的压栈和退栈。
当寄存器RAX-RSP被用作操作数的时候,64位模式缺省的操作尺寸无需REX前缀作为这些指令的先导。如果式R8-R15作为操作数,则REX依
然是需要的。这是因为前缀在访问新扩展寄存器中是需要的。
6.分支转移
64位扩展技术扩充2个分支机制来适应64位线性地址空间的分支。他们是:
64位模式下近分支转移被重新定义
在64位模式和兼容模式下,64位调用门描述符定义成远调用
64位模式下,所有近分支转移(CALL, RET, JCC, JCXZ, JMP 和 LOOP)被强迫为64位。这些指令被更新为提供64位的RIP值而无需REX前缀。
下面的近转移被有效的操作数宽度所控制:
指令指针的宽度的截断
由于CALL或RET引起的退栈压栈或退栈的大小
由于CALL或RET而引起的堆栈指针增加或减少的大小
间接转移操作数大小
在64位模式下,以上的所有操作都被强制为64位而不管操作数前缀(操作数大小的前缀被忽略)。然而相对转移的位移区域依然受到32位
的限制;近转移的地址大小没有被强制为64位。
地址大小影响到JCXZ和LOOP中RCX的大小;他们也影响到内存间接转移的地址计算。这样的地址缺省是64位,但是他们可以通过地址宽度前
缀转换到32位宽度。
软件会用远转移来改变优先级。传统IA-32结构提供调用门机制来允许软件去从一个优先级转到另一个优先级,尽管调用门也可以不改变优
先级而只是做转移。当调用门使用的时候,直接或间接的选择器指针会指向一个门描述符(指令重的便宜被忽略)目的代码段的偏移可以从调
用门描述符中获得。IA-32e模式重新定义了32位调用门描述符的类型值,使其成为64位调用门描述符,并扩展64位描述符使其能够容纳64位的
偏移。64位模式调用门描述符允许远转移访问有效的线性地址空间的任何地方。这些调用门也控制代码段选择器(CS),允许转换到特权级和缺
省尺寸并作为门转换的结果。
因为通常情况下是指定32位的,唯一在64位模式下指定完全64位绝对RIP的是间接分支转移,由于这个原因,直接远分支转移被从64位模式
的指令集中删除了。
IA-32e模式扩充了SYSENTER和SYSEXIT指令的语义,以便他们操作在64位存储空间。IA-32e也引入了两个新的指令:SYSCALL和SYSRET,他
们只在64位模式有效。
四、存储组织
1.64位模式下的地址计算
在64位模式(如果没有地址大小的转变),有效地址计算的大小是64位的。一个有效地址计算使用一个64位的基和索引寄存器以及符号扩
展变换成64位。
对于64位模式下平面地址空间,线性地址等同于有效地址。在使用FS和GS段的非0为基的事务中,这个规则不被使用。在64位模式下,有效
地址成分被加进来,并且有效地址在加64位基地址之前被缩短。地址映射模式在64位模式时,基地址从不会被缩短。
在IA-32e模式下,指令指针被扩展到64位来支持64位代码偏移。64位指令指针在调用中将值赋给RIP。下表描述了RIP、EIP和IP之间的不同
。

通常,替换和直接在64位模式下不被扩展到64位。他们在有效地址计算中依然被限制在32位和符号扩展。然而,在64位模式提供了MOV指令
的64位替换和直接形式的支持。
所有的在IA-32e模式下的16位和32位地址计算用0扩展来形成64位地址。地址计算搜现是缩短到当前模式的有效地址宽度,就像地址宽度前
缀的指定那样。其结果是用0扩展得到完全的64位地址宽度。因为这个,16位和32位应用程序运行在兼容模式只能存取64位模式有效地址的低4G
B。同样,在64位模式产生一个32位地址只能访问64位模式有效地址的低4GB。
2.规范的寻址
一个规范形式的地址有地址位63直到更有效的实现位,宏结构设置其为全1或全0。
IA-32e模式定义一个64位的线性地址,但实现的时候支持的位数要少些。第一个具有64位扩展技术的IA-32e结构的处理器将支持48位线性
地址。这意味着规范的地址必须将位63到位48全填0或全填1,填0还是填1要看位47是0还是1。
尽管实现并不用先行地址的全部64位,他们需要检查位63知道更有效的实现位来看是否地址是规范形式。如果一个线性存储引用不是规范
形式,该实现将会产生一个异常。在很多情况下,会产生一个一般保护异常(#GP)。然而,在显示或隐式对战应用的情况下,会产生一个堆
栈错(#SS)。隐式堆栈引用指令包括PUSH/POP指令和使用RSP/RBP寄存器来作为缺省堆栈段寄存器的指令。在这些情况下,一个规范错误式#
SF,如果一个指令使用RSP/RBP作为基寄存器并且有段超越给出一个非SS段,将引起一个一般保护错误(#GP)的规范错误。隐式堆栈引用包括
所有PUSH/POP类型指令和任何使用RSP或RBP作为一个基寄存器。规范地址形式的检查将在特权检查之后页面和边界检查之前完成。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
|
|
---|---|
|
AMD64 结构和软件接口
建议看原帖,格式清楚些:59fK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4W2S2L8X3N6I4M7#2)9J5k6h3&6W2j5i4y4W2i4K6u0W2L8X3g2@1i4K6u0r3K9r3q4J5k6s2N6S2M7X3g2Q4x3V1k6S2L8h3b7$3y4q4)9J5k6h3S2@1L8b7`.`. AMD64 结构和软件接口 Rich Brunner著 杨全胜翻译 一、X86-64指令集结构 1.x86-64结构 AMD 使用x86结构并扩展到64位来获得x86-64结构 - 处理器使用32位x86传统模式来执行现在的32位操作系统和应用程序。 - 处理器在“长模式”方式下运行64位操作系统并能同时运行32位和64位应用程序。 - 只有在64位模式下才能处理64位地址空间和64位寄存器 简单和具有兼容性的扩展使得处理器能全速高性能地运行x86和x86-64程序 - 所有用户可以获得32位性能和32位兼容性。 - 在需要的时候,用户可以放弃32位兼容性而转移到64位地址和数据类型。 2.x86程序员模式 ![]() 3.64位模式操作 新指令只有两个 - MOVSXD 将双字的符号位扩展到四字 - SWAPGS 内核模式下的指令,用于减少中断处理的开销 新的覆盖(override)允许命名16GP和16 SSE寄存器 - 不管指令使用多少寄存器,每个指令只需要一个覆盖字节来标明扩展寄存器 堆栈调整到64位 该结构支持64位虚拟地址空间和52位物理地址空间 - 具体实现时略少些 内存页面机制扩展以提供64位寻址 - 4级页 - 页表条目就是X86的PAE模式条目的简单扩展 中断和例外建立64位状态 - SMI(系统管理中断)受影响于32位模式 废弃了一些冗余指令编码 64位模式不使用分段模式――平板寻址 4. “长模式(Long Mode)”概览 长模式由两个子模式组成 - 64位模式 - 兼容模式 长模式由一个全局控制位(LME)来使能 当LME=0, CPU是一个标准的32位处理器 ![]() 5. 64位模式 缺省的数据大小为32位 - 64位使用新的REX前缀 - 16位采用传统的操作尺寸前缀(66h) 缺省的地址大小是64位 - 指针是64位的 前缀类型 没有 REX 66h 操作尺寸 32 64 16 6. 兼容模式 该模式能使现有的应用程序无需修改就能在长模式下运行 选择代码段(CS.L=0) - 使用远转换(Far Transfer)优于全模式开关,比模式开关快 无需修改的应用级代码运行 - 传统分段 - 传统的地址和数据尺寸缺省值 系统方面使用64位模式语义 - 中断和例外使用长模式句柄 - 页面机制使用长模式语义 7. REX前缀字节 ![]() 添加寄存器编码而无需改变原来的指令模式 可选的REX前缀指明64位操作尺寸 - 添加了3个寄存器编码位 REX实际上是16位前缀家族的 在64位模式中平均指令长度是0.4字节 8. 段和分段方式 64位模式提供平板、非分段的虚拟地址空间 - 传统的16位模式下的分段框架在64位模式下不能使用 长模式下代码段依然存在 -需要指明缺省模式(16,32和64位)个执行特权级 - 也意味着已经有的执行特权级和检查机制被保留下来 通过普通的远转换指令,开在64位模式和兼容模式之间切换 - CALLF、RETF、JMPF、IRETF、INT 9. X86-64 64位虚拟寻址 ![]() 10. 结构反馈 指令集不影响性能 - RISC 避免了RISC-CISC之争 -对于ISA,兼容性是最主要的操作机构。由于x86是将其作为基本功能安装的,所以ISA功能是必须的一个选择。 - X86的代码密集性是很突出的 下面信息是关于x86以及来自于SpecINT2000编译系统 - 代码长度大约增加5%,主要原因是由于使用64位代码文字 - 指令数大约减少15% + 附加的寄存器确实得到好处 + 很多spill/fill存储器被消除 + Call-Exit序列得到大幅改善 降低了指令数提高了IPC,意味着性能得到实质性的提高 - “Hammer”IPC提高大约5% - x86-64指令数下降大约15% - 网络大约改善20% - 你的代码使用数将根据你的应用变化 IA-64反馈严格的和下列情况相反:指令数增加和IPC下降 二、操作系统模式 1. 64位考虑 Hammer BIOS 标准的x86的32位代码 - 在操作系统加载和启动控制的时候转换到64位操作 - 没有附加的固件需求 32位应用 - 处理器核心提供完全的x86兼容性(全速的,但不支持V86模式) - 操作系统在核心调用的边界上提供一个转换层 64位应用程序需要64位操作系统 - 所有情况的都是新的,目前的操作系统不具备64位功能 设备驱动程序 - 64位操作系统需要64位设备驱动程序 - 分布包括很多设备驱动 - 固件回调不在被支持 新的64位工具 - 仿真、模拟 - 编译器、连接器、库 - 调试器和性能分析器 2. 64位计算策略 传统模式 - Hammer处理器设计成能够以脉冲前沿(leading-edge)执行方式运行任何32位操作系统 - 在驱动程序、OS和BIOS多个层面上完全兼容先前的x86系列 兼容模式 - 在64位操作系统控制下,现有的32位应用程序可以以脉冲前沿方式执行 - 应用程序无需重编译,也没有模拟层 64位模式 - 要求应用程序能够在写和端口操作中充分发挥x86-64的64位能力 - 在许可和用户要求的情况下做移植 - 也许只有1%的应用程序需要这种模式 3. 64位操作系统和应用程序交互 ![]() 4.兼容转换层 整合一个库到操作系统中 - 对终端用户透明 64位操作系统建立了一个驻留的32位处理核心来处理32位应用程序 32位应用程序被动态连接到转换层 转换层实现所有的32位核心调用 - 必要的时候解释参数 - 调用64位核心 - 必要的时候转换结果 在Windows和Linux上都有很好的实现 |
![]() |
赞赏
雪币:
留言: