我需要弄乱这些架构上的堆栈,这真的是一个n00b。我可以做任何阅读主题/谷歌搜索的指针。我正在寻找这些架构如何从根本上彼此不同。关于此主题的维基百科文章http://en.wikipedia.org/wiki/X64
答案 0 :(得分:9)
在x86中有8个32位寄存器,在x64中,寄存器各为64位,还有8个寄存器。 128位SSE寄存器在两者中均为128位,但在x86上有8位,而在x64中有16位。另外一些指令在x64中被删除。
在x64模式下,您仍然可以使用32位名称(以“e”开头)而不是64位名称(以“r”开头)将寄存器用作32位,并且程序集主要是同样的。
http://en.wikipedia.org/wiki/X86#x86_registers
或者如果你想要一些非常繁重的阅读(比如1000页......)
http://www.intel.com/products/processor/manuals/index.htm 我阅读了这些手册的几百页,并学到了很多非常好的东西。
答案 1 :(得分:8)
这里的所有答案都提到了寄存器集的变化,我将在此列出完整性:
EAX
扩展为RAX
,依此类推)R8
到R15
)XMM8
到XMM15
)寻址模式也有变化:
0x0
,其限制为0xffffffffffffffff
。 FS和GS可以有超过32位的基数。0x0
到0xfffffff
。在64位模式下,线性地址空间从0x0
分割为0x00007ffffffff
,从0xffff800000000000
分割为0xffffffffffffffff
。基本上,只有48位地址,地址符号扩展为64位。删除了各种说明:
INC
和40+rw
的一个字节40+rd
指令。 4x
字节成为 REX
前缀。LDS
,LDS
,LSS
。我还记得更多的不同之处。如果我能想到更多,我会添加它们。
答案 2 :(得分:3)
我相信您链接的维基百科文章提供了合理数量的介绍性信息。如果您对长模式差异的具体细节感兴趣,可以参考其中一个官方参考文献:Intel® 64 and IA-32 Architectures Software Developer's Manuals。
答案 3 :(得分:2)
在x86上,几乎每个C编译器都使用cdecl
调用标准。我不记得它的细节,但它在编译器和操作系统之间是一致的。基本上,参数被推送到堆栈(从右到左),然后返回值放在eax中,调用者负责清理。
虽然在x86-64上,它的一切都搞砸了。 Windows调用约定不同于linux(大多数非Linux unix类操作系统保留了原始的C调用标准,但这会导致更多的麻烦)。我不记得他们有什么不同,但他们确实如此。在谷歌中查找“不同的呼叫约定x86-64”,您将找到它的详细信息。
请参阅:http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention
答案 4 :(得分:1)
对于初学者,指针的大小是8个字节而不是4个。
寄存器也可以保存64位值。
此外,操作系统级别通常存在许多差异。例如,在Windows上,当您在64位Windows操作系统上运行32位应用程序时,您会遇到文件系统重定向和注册表重定向(WOW64)等问题。
答案 5 :(得分:1)
人们没有提到的一件事是寻址,在32位保护模式下,段寄存器具有意义,并且SS DS和CS可以各自处于不同的偏移。在64位保护模式下,不可能发生。唯一可以具有偏移(但没有限制)的寄存器是FS和GS。这意味着在32位模式下ds:[ebx]和cs:[ebx]可以有不同的值,这允许一些肮脏。但通常操作系统不会这样做。
人们在这里没有提到的另一件事是,如果你在64位模式下修改32位寄存器,它将清除上半部分,但只有你修改了32位。例如mov eax,0将导致rax为0,而mov ax,0将不会触及上半部分。所以看看装配时有点棘手。
对于堆栈,它更多的是操作系统而不是CPU的问题。 x64的windows ABI与其他人使用的不同(linux,mac ...)。您可能需要更深入地研究“调用约定”和ABI(应用程序二进制接口)。但是,在x64上,RSP需要在函数入口处对齐16字节,这就是为什么你经常会看到虚拟rsp递减的原因。这是为了确保堆栈上的16字节值始终对齐。但是在CPU级别它完全相同,RSP减少,push仍然是“sp- = word_size; ram [sp] = value”。哦,并且在x64上RSP没有限制,在x32上你可以告诉CPU堆栈指针不能低于某个地址,因此对较低地址的堆栈访问会导致错误。
我不确定你究竟在问什么。也许更具体的问题可以提供更具体的答案。
答案 6 :(得分:0)
x86的CPU中的所有寄存器都是32位,而64位的64位是:)
如果你使用指针arithematic,那么sizeof()会产生不同的结果,因此会有一个incrment操作。
我觉得你可以在intel网站上获得关于这两个架构的详细信息,甚至还有指示集突出显示64位处理器添加的新指令。
答案 7 :(得分:0)
除了通用寄存器现在是64位而不是32位之外,还有新的寄存器:r8,r9,r10,r11,r12,r13,r14和r15。事实上,有更多寄存器也导致大多数编译器对函数调用使用传递寄存器调用约定(除了那些使用varargs),而在x86中,大多数编译器将所有参数都推送到堆栈。
x87 FPU也不推荐使用,更喜欢SSE。
答案 8 :(得分:0)
虽然我认为这不是特别针对x86和x64的答案,但它可能是相关的。
在Linux上,在x86下,堆栈为4k或8k,而在x64下则为16k。