11

Recently I decided that it was worth getting a try on basic x86 assembly so that it would be easier to debug programs, etc, etc. So I started (about a week ago) learning x86 assembly, in that time, I upgraded my computer to 8GB ram, so obviusly my x86 Windows XP installation was wasting up all that memory, now, I'm running a x64 Windows 7 copy, so the question is:

Is it possible to work with x86 assembly on a x64 operating system? Will it run properly in the emulator? Or should I learn x64 assembly?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • I'd like to freeload a bit on this question (seems quite relevant and non-hijacking to do so): there are lots of resources for x86-32 out in the world. It seems like there is not very many differences between 32/64 at the assembly level. Considering the wealth of 32 material, is it worth ferreting out the 64 resources and really just concentrating on 64 at this point (assuming one wants to learn 64) or, since it (at least seems) that the important conceptual stuff is all in 32 and only things such as 64 bit registers are really important that it's just fine limiting myself to 32 for just casua – Kevin Won Jan 24 '10 at 04:54
  • Not so much. However it changes if you go to compilers. Calling conventions and ABI differs, and the mandatory SSE2 on X86_64 means that it is actually used. Also stuff like PIC are quite different. Still these differences are manageble though. – Marco van de Voort Jan 24 '10 at 17:27
  • Marco, I'm not quite sure I understand: are you saying that you think that the conceptual differences are so trivial for 64 compared to 32 that someone learning assembly can safely ignore them and just concentrate on 32 without fear of having to un-learn the 'old' way when moving to 64? – Kevin Won Jan 24 '10 at 19:35
  • There isn't really anything you need to *unlearn*. Learning both stack-args (legacy 32-bit) and register-args (64-bit) calling conventions will both make sense, and 64-bit calling conventions do have to use stack args once they run out of registers, e.g. for functions with more than 6 integer args. Learning 32-bit first isn't a bad plan; some things are simpler there. (But maintaining 16-byte stack alignment for modern calling conventions is uglier in units of 4 bytes vs. 8-byte pushes in 64-bit.) – Peter Cordes Jun 08 '19 at 01:33

3 Answers3

19

Is it possible to work with x86 assembly on a x64 operating system? Will it run properly in the emulator?

Yes it is possible & it will run properly. Instruction Set Architecture is always backwards compatible.

Registers in x86-64:

alt text
(source: usenix.org)

For example: Here you can see that rax is the new 64 General Purpose register but you still can use eax as it refers to lower 32 bits of rax.

Or should I learn x64 assembly?

x86-32 architecture is subset of x86-64. Its like first you learnt x86 then go & find whats new in x86-64 assembly. Once you learn x86 asm. Then this will be a useful resource: http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
claws
  • 52,236
  • 58
  • 146
  • 195
  • What does r in rax stand for? I know e stands for extended – kizzx2 Nov 04 '10 at 00:42
  • 1
    @kizzx2: `r` stands for register. `e` stands for extended. If you go to other ISAs you'll find register names like r1,r2,r3... – claws Nov 04 '10 at 01:52
  • 1
    Visuals always makes an answer better. – Mert Akcakaya Jul 06 '13 at 15:24
  • Nice answer with understandable figure. – weefwefwqg3 Oct 12 '16 at 02:55
  • The *x86* ISA is always backwards compatible because that is its key feature / selling-point (and the existence of fast x86-64 CPUs also keeps it going). Some AArch64 chips have dropped support for ARM32 mode. So it's not true in general that *Instruction Set Architecture is always backwards compatible.* MIPS64r6 even re-organized some opcodes within existing modes, so it's a separate incompatible CPU that's only compatible with earlier MIPS at the asm source level. – Peter Cordes Jun 08 '19 at 01:28
14

Yes, of course. Most programs are still 32 bit and run fine on 64-bit Windows systems. Those programs are machine language, which has a one-to-one mapping with assembly (and can be easily disassembled into x86 assembly code).

Max Shawabkeh
  • 37,799
  • 10
  • 82
  • 91
2

Linux explicitly implements 32 bit support if the compilation option:

CONFIG_IA32_EMULATION=y

is set.

This is done by most sane distros, including Ubuntu 14.04.

32-bit emulation is of course only possible because x86-64 processors are designed to be backwards compatible with 32-bit executables via a 32-bit emulation mode which the kernel knows how to use.

Another thing you have to worry about is the libraries: to compile 32-bit programs, you need 32-bit libraries. On Ubuntu 14.04 AMD64:

sudo apt-get install gcc-multilib

Then we can easily test it out with a hello world:

#include <stdio.h>
#include <stdlib.h>

int main() {
    puts("hello world");
    return EXIT_SUCCESS;
}

and:

gcc -m32 hello_world.c
./a.out

Which prints:

hello world

And:

file a.out

confirms that it is 32 bit:

ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=358f7969deeb2f24a8dd932a0d296887af4eae30, not stripped
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Windows Subsystem for Linux does *not* do this; the emulation layer inside the Windows kernel behaves like Linux with `CONFIG_IA32_EMULATION=n`. It can't run 32-bit binaries, or 32-bit `int 0x80` system calls from 64-bit code (which nobody should do in the first place, but hand-written asm by novices sometimes does). – Peter Cordes Jun 08 '19 at 01:30