Kaguei Nakueka
Kaguei Nakueka

Reputation: 1128

How different is the Assembly for 32bit Intel processors to the 64bit version?

I have started learning Assembly but got worried with one of the first sentences of this book:

In this book, we focus on the assembly language for the Intel 32-bit processors like the Pentium.

How different is the Assembly for 32-bit to the 64-bit one? Is it worth to learn both or by learning 32-bit I will be fine with 64-bit one?

Upvotes: 1

Views: 295

Answers (5)

Margaret Bloom
Margaret Bloom

Reputation: 44076

64 bit mode introduced some architectural changes.
An incomplete list can be found on chapter 3.2.1 of Manual 1 from Intel

• Address space — A task or program running in 64-bit mode on an IA-32 processor can address linear address space of up to 2^64 bytes (subject to the canonical addressing requirement described in Section 3.3.7.1) and physical address space of up to 2^46 bytes. Software can query CPUID for the physical address size supported by a processor.

[Previously it was only possible to address up to 4 GiB (not all usable for RAM of course), not the current limit is 64 TiB]

•Basic program execution registers — The number of general-purpose registers (GPRs) available is 16. GPRs are 64-bits wide and they support operations on byte, word, doubleword and quadword integers. Accessing byte registers is done uniformly to the lowest 8 bits. The instruction pointer register becomes 64 bits. The EFLAGS register is extended to 64 bits wide, and is referred to as the RFLAGS register. The upper 32 bits of RFLAGS is reserved. The lower 32 bits of RFLAGS is the same as EFLAGS. See Figure 3-2.

[x86 had 8 general purpose registers: EAX, EBX, EBX, EDX, ESI, EDI, EBP, EDI. Each one 32 bits. Now there are 16 GP registers, of 64 bits: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8-R15. The lower 32 bits of these register are the old 32 bit registers. Other register extended and were made addressable, like BPL]

• XMM registers — There are 16 XMM data registers for SIMD operations. See Section 10.2, “SSE Programming Environment,” for more information about these registers.

[Previously there were only 8 XMM0-XMM7 128-bit SIMD registers. Same for YMM with AVX]

• Stack — The stack pointer size is 64 bits. Stack size is not controlled by a bit in the SS descriptor (as it is in non-64-bit modes) nor can the pointer size be overridden by an instruction prefix.

[As expected, the stack pointer is RSP]

• Control registers — Control registers expand to 64 bits. A new control register (the task priority register: CR8 or TPR) has been added. See Chapter 2, “Intel® 64 and IA-32 Architectures,” in this volume.
• Debug registers — Debug registers expand to 64 bits. See Chapter 17, “Debug, Branch Profile, TSC, and Quality of Service,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.

[This is for accommodating for 64 bits pointers]

This is mostly an introductory list, there are other changes:

  • Everything that hold an address is 64 bits now, as rule of thumb.
  • Segmentation is disabled in 64 bit mode (a.k.a. long mode), only FS and GS selected descriptor bases and limits are honored.
  • Some instruction, like one byte form of inc ax are no more encodable (i.e. usable) due the introduction of the REX prefix.
  • Arithmetic operations on the 32 bits registers clear the upper 32 bits of the full 64 bits register (i.e. mov eax, 1 clears the upper DWORD of RAX).
  • At opcode level, most immediate operands are still 32 bits but sign extended. This instructions like add ebx, 0123456789abcdefh are not encodable.
  • Physical addresses must be canonical to avoid aliasing, i.e. be sign extended to 64 bits.
  • A new addressing mode is available: RIP relative, i.e. an offset from the current instruction address can be used to access data. This helps with Position Independent Code.

All this is still preliminary, you can google for related terms if interested or take a look at the Intel manuals.


However what will strike you the most when switching from 32 to 64 bits is the change in the ABI used, you'll need to adapt the calls to the runtime library procedures.

As an example of changes:
Parameters are now passed on the registers (the first fours), the stack must be aligned, vector registers are used for floating point, a red zone/dump zone is available on the stack.

Each platform has its own ABI, you can check, for example, the SysV ABI for a full list.

Upvotes: 4

Mike Robinson
Mike Robinson

Reputation: 8945

(As a second-answer, yes ...) I would also like to interject into this exchange the pragmatic observation that “straight assembly-language is not used too much anymore.”   When it is, it is most-likely to be found as asm{ ...} sections within a higher-level language (“C...”) program.

... and, many times these days, it is probably unnecessary, because the compiler is often able to generate object-code as good or better (maybe, significantly better ...) than what you can do by hand.   Certainly, this was not always the case.

An excellent example to look at would be the /arch subtrees of the Linux Kernel source-code.   Aside from the so-called “trampoline” sections, which are used by certain architectures at boot-time when, literally, “nothing else exists yet,” most of the architecture-specific assembly code consists of very targeted subroutines.   Some of these are not only “architecture-class specific” (e.g. “x86”), but manufacturer-specific (“AMD ...”), but, let the record clearly show that these things are the exception, rather than the rule.

Yes, I agree that you do need to know how various CPU architectures operate “at the bare metal,” but I can count on the fingers of two-hands the number of times that I thought that I could do a better job than the compiler could.   (Excluding those few years when I labored for my daily bread on a highly-modified mainframe OS that was built mostly-entirely in assembler.   Ick ...)

Upvotes: 0

Peter Cordes
Peter Cordes

Reputation: 364503

The ABI is different, but the actual instruction set is extremely similar. See this quick guide to what's different in x86-64 linked from the tag wiki.

In modern OSes, the same system call APIs are available in 32 and 64bit, although there are differences in the ABI (e.g. int 0x80 vs. syscall).

But by learning 32bit code you won't be wasting your time learning DOS system calls that are only useful for DOS programs.


IDK if learning 64bit code right away is easier or not. You can often write functions that don't have to really use the stack for anything; maybe just a push / pop to save/restore something. In some ways this is a good thing. You can put off learning how to use the stack while you wrap your head around other basics like getting your branch logic correct.

The 32bit ABI basically forces you to learn the stack layout right away, because args are always passed on the stack.

If you want to write really efficient 64bit code (that doesn't waste instruction bytes on REX prefixes when 32bit operand-size is sufficient), that's one more thing to think about. But while you're learning, just settling for correctness is fine; and you only occasionally need to worry about sign-extending a 32bit signed int to 64bit for use as an offset in an addressing mode.

Upvotes: 0

ElderBug
ElderBug

Reputation: 6145

Beside the fact that x64 processor can execute 32-bit x86 as is, the x86 instruction set is mostly compatible with the x64 one. add ebx, eax is still valid in x64. There are some differences though. For example, push es isn't valid, and pointers are 64-bit : mov dword ptr[esi], eax is valid but will likely not work because you probably truncate the pointer in rsi.

This means that there isn't a big difference between learning 32-bit x86 or 64-bit x64. You will be fine with either. If you have the choice, my opinion would be to learn x64 : it's like learning both with little additional work.

Upvotes: 2

Mike Robinson
Mike Robinson

Reputation: 8945

Believe it or not, the “Intel x86” processor architecture goes all the way back to (koff, koff ... wheeze ... “these KIDS today” ...) the Intel 8008 (Calculator-controller for the masses ...).   Thence, to the Intel 8080 (the chip that first began to Make Bill Gates™ Rich).

In every processor-incarnation since then ... the 8086 ... the 80x86 ... Intel has dutifully attempted to “accommodate the Past” by a rather-increasing(!) number of “backwards-compatible ‘Processor Modes.’”

Each of these “modes,” of course, has been an effort to shield existing software from the potential side-effects of advancements that did not yet exist at the time their software was written.

Upvotes: 1

Related Questions