Why there is no 16-bit information in ELF magic number? - linux

In ELF-header, value of e_ident[EI_CLASS] can either be 1 or 2, which indicates 32-bit operating or 64-bit operating system. But from history we know that ELF first appeared in Solaris 2.0, which is released in 1993. However, widely used 32-bit processor Pentium Pro didn't appeared until 1995.
So why does ELF header has no information about 16-bit or even 8-bit information?

The first "widely used" 32-bit CPU was the Intel 80386 which was much older.
Then we have the story about SUN and their SPARC architecture from around the same time-frame as the 386.
Solaris was developed by SUN for their machines in the early 1990's, close to when the first 64-bit systems started appearing actually.
ELF (acronym for the Executable and Linkable Format) was developed in the late 1980's, when all major Unix variants ran on pure or hybrid (think Motorola 68000) 32-bit systems.

EI_CLASS doesn't identify an "operating system", but rather the memory model. This setting defines how various address information is encoded in the file, not necessarily how wide the target registers are.
For PC CPUs, the code loader is executed on the same CPU that will execute the program contained in the ELF file, so EI_CLASS matches the the code format. However, ELF files are also used as a portable code / debug format, even on 8-bit and 16-bit controllers. Besides, virtually all 16-bit CPUs can address more than 64 KB of memory, so EI_CLASS cannot be set to ELFCLASS16 for such targets (assuming such a class existed).
To sum up, it's irrelevant how much bits wide pointers are, it's only relevant how much virtual memory you can have. Of course, one could still make ELF files more compact by defining something like ELFCLASS20 (a common value for 16-bit CPUs, including Intel 8086), but, like it was already stated, 32-bit architectures were already widespread in 1993, so nobody bothered to define such a thing.

Related

What "64 bit" means?

I know this question seems obvious, but I don't manage to find a precise answer.
If on my laptop it is written "Windows 8 64 bit", what "64 bit" exactly refers to? (I know that "Windows 8" is just the name and version of the OS).
I have a few interpretations, but none of them make me entirely happy:
The virtual address space of a process is of size 2^64 units (with unit being some small size). This definition does not make me happy, because even with disc storage, the total storage of my computer is far less than that. So I would never be able in a program to initialize an array of size 2^64.
The registers in memory have a capacity of 64 bits. This also does not make me entirely happy, because my machine could have both 64 bit and 32 bit registers, and perhaps registers of smaller size.
The maximum capacity of registers is 64 bits. This definition could be sensible, but looks "iffy".
So could anyone give me a clear definition, or at least tell that one of the above is correct?
"Windows 64 bit" means that the operating system supports 64-bit addressing.
This, in turn, implies that the CPU also supports 64-bit addressing.
The OS and the CPU are two entirely different things.
Runtime binaries (.exes and .dlls for Windows) are yet another "different thing". 32-bit and 64-bit .exe's have different binary formats, are loaded differently by the OS, and use different runtime resources.
You can't run a 64-bit OS on a 32-bit CPU. But you can run a 32-bit OS on a 64-bit CPU. Similarly, you can't use a 64-bit shared library or executable program on a 32-bit OS.
The key aspect of "64-bit" is 64-bit addressing: that both the CPU and the running program can address up to 2^64 bytes of virtual memory:
In practice, a running program will likely be able to address only a portion of that address space.
You can read more here:
https://en.wikipedia.org/wiki/64-bit_computing
PS:
Yes: CPU registers come in all different sizes. For example, ah is 8-bits, ax 16 bits, eax 32 bits and rax is 64 bits. Furthermore, different registers do "different things". For "64-bit computing", we're primarily interested in those registers that load from and store to virtual memory.

Control over memory virtualization on Linux and Windows

This is semi-theoretic question.
Can I specify the virtualization mode for memory (pure segmentation/segmentation+paging/just paging) while compiling for Windows (e.g., MSVS12 C++) and for Linux (e.g. g++)?
I have read all MSVS linker+compiler options, and found no point of control in there.
For g++ the manual is quite too complex for such question.
The source of this question is this - link
I know from theory and practice that these should either be possible or restricted by OS policy at some level cause core i7 supports all three modes I mentioned above.
Practical background:
The piece of code that created lots of data is here, function Init - and it exhausted my memory if I wanted to have over 2-3G primes on heap.
Intel x86 CPUs always use some form segmentation that can't be turned off. In 64-bit mode code segmentation is limited, but it's still there. Paging is required for both Windows and Linux to work on Intel CPUs (though Linux doesn't use paging on certain other CPU architectures). Paging is also required to enable 64-bit mode on Intel CPUs.
So in other words on Windows and Linux the OS always uses segmentation and paging, and so do any applications run on them, though this is largely transparent. It's not possible to "compiled+linked for 'segmentation without paging'" as you said in the answer you linked. Maybe the book you referenced is referring to ancient 16-bit versions of Windows (3.1 or earlier) which could be run in a mode that supported 80286 CPUs which didn't have paging. Though even then that normally didn't make any difference in how you compiled and linked your applications.
What you are describing is not a function of a compiler, or even a linker.
When you run your program, you get the memory model that is already running on the system. Your compiled code does not care abut the underlying memory mode.
However, your program itself can change the memory model IF it starts running in an unprotected processor mode.

What is the difference between x64 and IA-64?

I was on Microsoft's website and noticed two different installers, one for x64 and one for IA-64. Reference:Installing the .NET Framework 4.5, 4.5.1
My understanding is that IA-64 is a subclass of x64, so I'm curious why it would have a separate installer.
x64 is used as a short term for the 64 bit extensions of the "classical" x86 architecture; almost any "normal" PC produced in the last years have a processor based on such architecture.
AMD invented the AMD64 extensions; Intel was more or less forced to implement them, and called them first IA-32e, then EM64T and finally Intel 64 (actually, the AMD and Intel extensions aren't exactly the same, but they are almost identical).
Many people also call this stuff x86-64, to have a vendor-independent name and to stress the fact that it's the 64 bit evolution of the x86 architecture. All the "regular" PCs that are sold with "64 bit processors" run on x86-64 architecture.
IA-64 (Intel Architecture 64) is an almost completely unrelated 64 bit architecture (also known as Itanium), developed by Intel initially for high-end servers. It was said that Itanium could have been a replacement for the x86 architecture, but this architecture didn't have much success (for various reasons), so it's unlikely that you'll ever need the IA-64 installers.
For more information, you may have a look at the wikipedia articles on x86-64 and Itanium.
IA-64 is the Intel Itanium Architecture. This is a Very Long Instruction Word (VLIW) processor instruction set.
x86_64 is the normal 64-bit architecture that is used by processors inside every laptop / desktop in today's computers. This processor is a dynamic processor.
The main difference between these two is that
In VLIW, the compiler resolves the dependencies between instructions and schedules them appropriately. The processor merely executes them.
With a dynamic processor, the compiler just schedules the instructions without worrying about dependencies. The processor takes care of dependencies, reorders them and executes them appropriately.
VLIW code is dependent on each chip's internal architecture. The compiler needs to know that information. The advantage of them is that it can extract much more parallelism than dynamic processors can give.
The code is independent on each chip's internal architecture for dynamic processors. It just needs to follow the instruction set. So code compiled on one machine can run on other machines very easily. The disadvantage though is that limited parallelism can be exploited from dynamic processors. And the internal logic and design is very complex and intricate than VLIW.
Nevertheless, dynamic processors are used today mostly by consumers (individuals), so they can run code compiled / generated on any machine. VLIW processors are used by servers and enterprises because of the parallelism they can produce.
they are different
IA-64 is itanium - an architecture for servers
x64 is what 64bit intel core and amd cpus implement
x64 is short for x86-64 which is an extension of the x86 instruction set.
IA-64 is for the Itanium 64 bit Architecture (by Intel)
IA-64 is for computers running Intel Itanium 64 bit processors. They do not support running 32 bit applications like x64 processors do. A special version of Windows is needed to run on these processors, thus the two different installers.
They have different instruction set, this is the key point.

How to programatically detect a 64 bit or 32 bit machine?

I don't understand what 32 bit and 64 bit means. It seems that people say 64 bit computers run faster - but why? Does it mean that there are 64 bit integers instead of 32? If it's something like that, is there a way to write a program to determine if we're on a 32 bit or 64 bit machine?
On 64-bit machines pointers are 8 bytes (64 bits). On 32-bit machines they are 4 bytes (32 bits). Thus we can determine by the size of a pointer what we are dealing with, in it's simplest form:
#define IS_64BIT (sizeof(void *) == 8)
The only drawback is that a 64 bit computer running in 32 bit mode will register as 32 bit. Of course, this isn't actually important as for all intents and purposes a 32 bit OS on a 64 bit computer will be a 32 bit computer.
There's actually several different things your asking here.
First of all there's the CPU. Most modern day CPUs (within the past 5-years approx) will support 64-bit.
Now just because the CPU supports it doesn't mean the OS supports it, that's where you have either 64-bit OS or 32-bit OS (32-bit is also known as x86, there's small technical differences in the x86 refers to the CPU instruction set, but for most common usage x86 and 32-bit are interchangeable)
Even if the OS supports it, it doesn't mean the specific program you're running supports 64-bit. What most (if not all?) 64-bit OS's do is they have a 32-bit emulation mode so you can still run 32-bit programs.
Now for your question of how to determine which architecture you're running on, the most reliable way is to ask the OS through some API call.
As for why 64-bit is sometimes considered faster, it because with 32-bits it is only possible to address 4GB of memory, whereas with 64-bit the limit imposed by address space is much higher (as in about 4 billion times higher) and the limiting factor is hardware not address space. As to when and why more memory is faster, that's a separate topic altogether.
64-bit machines do not run faster than 32-bit machines except in cases where 64-bit math is being done or in cases where more than 4 GB of RAM is needed.
64-bit AMD (and later Intel) machines run faster than 32-bit x86 machines because when AMD designed the new instruction set they added more CPU registers and made SSE math the default.
32-bit x86 systems can waste a lot of CPU time pushing data around in RAM, while a x86_64 system can store that data in CPU registers instead. Registers are much faster than level-1 CPU cache. Having more registers also saves CPU instructions that otherwise need to store the old value of a register in RAM, load in a different value from RAM, then load the original value back from RAM.
In some especially register-starved cases the extra registers can gain 30% speed for a program. The benefit is usually much less than that.
The speed benefits from assuming SSE2 are many. In 32-bit CPUs SSE instructions may or may not exist, so to use them the software needs to have clumsy test code and two (or more!) implementation of the math functions. Most software just doesn't care enough and so it never bothers, always falling back on x87 FPU math from the 486 days. The 64-bit CPUs made SSE2 a required part of the instruction set, so all x86_64 programs are free to assume it exists and use it in all cases.
64bit computers do not run faster, per se. It just can support higher precision (larger integers, more precise floats).
In some rare cases, libraries might jam two 32bit numbers into 64bits to perform a large number of parallel operations, possibly resulting in potentially up to 2x speedup. This might occur for some highly optimized scientific/numeric libraries, or in special applications that (for some reason or another) have been highly optimized at a very low level. For example, some multimedia software. It should be noted that such applications could always have made this tradeoff even in 32bit mode, but chose not to; they are merely trading away precision (which they may not need) for parallelism.
Operating system benchmarks which reveal faster performance (maybe <10% improvement) are not necessarily related to 64bit-related optimizations. 64bit architectures may be correlated with having for example more registers or advanced features that programs can take aware of [citation: http://www.tuxradar.com/content/ubuntu-904-32-bit-vs-64-bit-benchmarks ], which may be the cause of a performance difference (as well as other variables).
How to determine whether a CPU is 32bit or 64bit depends on what OS you are using. For example on Linux, you can call uname -a, though there's probably a better way to do so. If you're using C/C++, see the other answer for a way to determine it in a program.

What are the advantages of a 64-bit processor?

Obviously, a 64-bit processor has a 64-bit address space, so you have more than 4 GB of RAM at your disposal. Does compiling the same program as 64-bit and running on a 64-bit CPU have any other advantages that might actually benefit programs that aren't enormous memory hogs?
I'm asking about CPUs in general, and Intel-compatible CPUs in particular.
There's a great article on Wikipedia about the differences and benefits of 64bit Intel/AMD cpus over their 32 bit versions. It should have all the information you need.
Some on the key differences are:
16 general purpose registers instead of 8
Additional SSE registers
A no execute (NX) bit to prevent buffer overrun attacks
The main advantage of a 64-bit CPU is the ability to have 64-bit pointer types that allow virtual address ranges greater than 4GB in size. On a 32-bit CPU, the pointer size is (typically) 32 bits wide, allowing a pointer to refer to one of 2^32 (4,294,967,296) discrete addresses. This allows a program to make a data structure in memory up to 4GB in size and resolve any data item in it by simply de-referencing a pointer. Reality is slightly more complex than this, but for the purposes of this discussion it's a good enough view.
A 64-bit CPU has 64-bit pointer types that can refer to any address with a space with 2^64 (18,446,744,073,709,551,616) discrete addresses, or 16 Exabytes. A process on a CPU like this can (theoretically) construct and logically address any part of a data structure up to 16 Exabytes in size by simply de-referencing a pointer (looking up data at an address held in the pointer).
This allows a process on a 64-bit CPU to work with a larger set of data (constrained by physical memory) than a process on a 32 bit CPU could. From the point of view of most users of 64-bit systems, the principal advantage is the ability for applications to work with larger data sets in memory.
Aside from that, you may get a native 64-bit integer type. A 64 bit integer makes arithmetic or logical operations using 64 bit types such as C's long long faster than one implemented as two 32-bit operations. Floating point arithmetic is unlikely to be significantly affected, as FPU's on most modern 32-bit CPU's natively support 64-bit double floating point types.
Any other performance advantages or enhanced feature sets are a function of specific chip implementations, rather than something inherent to a system having a 64 bit ALU.
This article may be helpful:
http://www.softwaretipsandtricks.com/windowsxp/articles/581/1/The-difference-between-64-and-32-bit-processors
This one is a bit off-topic, but might help if you plan to use Ubuntu:
http://ubuntuforums.org/showthread.php?t=368607
And this pdf below contains a detailed technical specification:
http://www.plmworld.org/access/tech_showcase/pdf/Advantage%20of%2064bit%20WS%20for%20NX.pdf
Slight correction. On 32-bit Windows, the limit is about 3GB of RAM. I believe the remaining 1GB of address space is reserved for hardware. You can still install 4GB, but only 3 will be accessable.
Personally I think anyone who hasn't happily lived with 16K on an 8-bit OS in a former life should be careful about casting aspersions against some of today's software starting to become porcine. The truth is that as our resources become more plentiful, so do our expectations. The day is not long off when 3GB will start to seem ridiculously small. Until that day, stick with your 32-bit OS and be happy.
About 1-3% of speed increase due to instruction level parallelism for 32-bit calculations.
Just wanted to add a little bit of information on the pros and cons of 64-bit CPUs. https://blogs.msdn.microsoft.com/joshwil/2006/07/18/should-i-choose-to-take-advantage-of-64-bit/
The main difference between 32-bit processors and 64-bit processors is the speed they operate. 64-bit processors can come in dual core, quad core, and six core versions for home computing (with eight core versions coming soon). Multiple cores allow for increase processing power and faster computer operation. Software programs that require many calculations to function operate faster on the multi-core 64-bit processors, for the most part. It is important to note that 64-bit computers can still use 32-bit based software programs, even when the Windows operating system is a 64-bit version.
Another big difference between 32-bit processors and 64-bit processors is the maximum amount of memory (RAM) that is supported. 32-bit computers support a maximum of 3-4GB of memory, whereas a 64-bit computer can support memory amounts over 4 GB. This is important for software programs that are used for graphical design, engineering design or video editing, where many calculations are performed to render images, drawings, and video footage.
One thing to note is that 3D graphic programs and games do not benefit much, if at all, from switching to a 64-bit computer, unless the program is a 64-bit program. A 32-bit processor is adequate for any program written for a 32-bit processor. In the case of computer games, you'll get a lot more performance by upgrading the video card instead of getting a 64-bit processor.
In the end, 64-bit processors are becoming more and more commonplace in home computers. Most manufacturers build computers with 64-bit processors due to cheaper prices and because more users are now using 64-bit operating systems and programs. Computer parts retailers are offering fewer and fewer 32-bit processors and soon may not offer any at all.

Resources