开发者

How is the x64 architecture different from x86

开发者 https://www.devze.com 2022-12-12 12:45 出处:网络
I need to mess around with the stacks on these architecture and am really a n00b here. Any pointers to reading topics/google searches that i can do. I am looking for how these architectures are fundam

I need to mess around with the stacks on these architecture and am really a n00b here. Any pointers to reading topics/google searches that i can do. I am looking for how these architectures are fundamentally different from each other. something more than the wikipedia article on 开发者_如何转开发this topic http://en.wikipedia.org/wiki/X64


In x86 there are 8 32 bit registers, in x64 the registers are 64 bits each and there are 8 more of them. The 128 bit SSE registers are 128 bits in both, but on x86 there are 8 of them while in x64 there are 16 of them. Also some instructions were cut in x64.

In x64 mode you can still use the registers as 32 bits by using their 32 bit name(starting with an 'e') instead of their 64 bit name(starting with an 'r'), and the assembly would be mostly the same.

http://en.wikipedia.org/wiki/X86#x86_registers

Or if you want some really heavy reading(like 1000s of pages...)

http://www.intel.com/products/processor/manuals/index.htm I read through a few hundred pages of those manuals and learned a lot, really good stuff.


All the answers here mention the changes in the register set, which I'll list here for completeness:

  • All existing 32-bit general purpose registers are extended to 64 bits (EAX is extended to RAX and so on)
  • 8 new 64-bit general purpose registers (R8 through R15)
  • 8 new 128-bit SSE registers (XMM8 through XMM15)

There are also changes in addressing modes:

  • CS, DS, ES and SS are flat. That is, their base is 0x0 and their limit is 0xffffffffffffffff. FS and GS can have a base over 32 bits.
  • Descriptors in the GDT, LDT and IDT have changed. They have 8 bytes in 64-bit mode
  • A non-contiguous address space. In 32-bit mode the linear address space is from 0x0 to 0xfffffff. In 64-bit mode the linear address space is split from 0x0 to 0x00007ffffffff and from 0xffff800000000000 to 0xffffffffffffffff. Basically, there are only 48 bits of address, and the address is sign-extended to 64 bits.
  • A new paging mode.

Various instructions were removed:

  • One byte INC instructions with encoding 40+rw and 40+rd. The 4x byte became the REX prefix.
  • instructions for loading the segment registers that are now flat: LDS, LDS, LSS.

There are more differences that I simply can remember off the top of my head. I'll add them if I can think of some more.


I believe the Wikipedia article you linked to provides a reasonable amount of introductory information. If you are interested in the specific details of differences in Long Mode, you can consult one of the official references: Intel® 64 and IA-32 Architectures Software Developer's Manuals.


Um, stack? Do you mean the physical(E/RSP stack)? If so then my answer is relevant:

On x86, almost every C compiler uses the cdecl calling standard. I can't remember the details on it, but it was consistent among compilers and operating systems. Basically, arguments is pushed to the stack(right to left) and then the return value is put in eax and the caller is responsible for cleanup.

On x86-64 though, its all pretty screwed up. The windows calling convention is different from linux(most non-linux unix-like OSs have kept with the original C calling standard though which leads to more screwyness). I can't remember how they differ, but they do. Look up "different calling conventions x86-64" in google and you'll find the details of it.

see: http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention


For starters the size of a pointer is 8 bytes instead of 4.

Registers can hold 64-bit values as well.

Also there are often many differences at the OS level. For example on Windows you have things like filesystem redirection and registry redirection (WOW64) when running 32-bit apps on a 64-bit Windows OS.


One thing people didn't mention is the addressing, in 32 bit protected mode the segment registers have meaning and the SS DS and CS can each be at a different offset. In 64 bit protected mode that can't happen. The only registers that can have an offset (but no limit) are FS and GS. Which means that in 32 bit mode ds:[ebx] and cs:[ebx] can have a different value which allows some nastiness. But usually OSes don't do this.

Another thing that people didn't mention here is that if you modify a 32 bit register in 64 bit mode it will clear the upper half, but only if you modify the 32bits. e.g. mov eax,0 will result in rax being 0, whereas mov ax,0 wouldn't touch the upper half. So it's a bit tricky when looking at assembly.

As for the stack, it is more a question of OS than the CPU. The windows ABI for x64 is different from the one used by everyone else (linux, mac ...). You probably need to look more deeply at "calling conventions" and ABIs (application binary interface). However, on x64 the RSP needs to be 16 byte aligned at the entry to a function, which is why you'll often see dummy rsp decrements. This is to make sure 16 byte values on the stack are always aligned. But at the CPU level it's all the same, RSP decrements, push is still "sp-=word_size ; ram[sp]=value". Oh, and on x64 RSP doesn't have a limit, on x32 you can tell the CPU that the stack pointer can't go below a certain address, so stack access to lower addresses will cause a fault.

I'm not sure what you're asking exactly. Maybe a more specific question would permit a more specific answer.


All the registers in CPU of x86 are 32-bit where as for 64-Bit its 64-Bit :)

If you using pointer arithematic then sizeof() will yeild different results and so would an incrment operation.

I feel you can get detailed information on intel site about the two architecutures and also even the instruction set highlighting new instructions add with 64-Bit processors.


In addition to the fact that the general purpose registers are now 64-bits instead of 32, there are also new registers: r8, r9, r10, r11, r12, r13, r14, and r15. The fact that there are more registers also leads to the fact that most compilers use pass-by-register calling conventions for function calls (except those with varargs), whereas in x86 most compilers push all arguments to the stack.

The x87 FPU is also deprecated, preferring SSE.


While I don't think this is specifically an x86 vs. x64 answer it may be relevant.

On Linux, under x86 the stack is either 4k or 8k, while under x64 it's 16k.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号