4 ms·
> The x86 addressing modes are a lot simpler than the 680x0. Anything but simpler and completely irrational to someone coming from the orthogonal ISA design pe
by inkyoto 3y ago
> The x86 addressing modes are a lot simpler than the 680x0.
Anything but simpler and completely irrational to someone coming from the orthogonal ISA design persepective.
For a start, on x86, the loading of an address is a separate instruction with its own, dedicated opcode.
On m68k (and its spiritual predecessor PDP-11), it is «mov» (00ssssss) – the same instruction is used to move the data around and to load addresses. Logically, there is no distinction between the two as an address and a numeric constant are the same thing for the CPU (the execution context defines the semantics of the number loaded into the CPU register), so why bother with making an explicit distinction?
Having 2x separate instruction for loading addresses and moving the data around would have made more sense if data and address registers were 2x distinct register files, which m68k had and x86 did not, and speaking of the registers x86 was completely starved of general purpose registers anyway effectively having five of them (index registers are semi-general purpose anyway so they do not count). Even x86-64 today has 16x kinda general purpose registers which is very poor. AMD29k, as another extreme, could have 256 general purpose registers and 32x has been the sweet spot for many ISA's for a long time.
Secondly, there was the explicitly segmented memory model with near and far addresses. Intel unceremoniously threw the programmer under the bus with having to explicitly manage segments and offsets within each segment to calculate the actual address, and the address could not cross a 64kB segment. Memory segments have been a commonplace and predate x86, yet the complexity of handling them is typically hidden in the supervisor (kernel) level. m68k, on other hand, has had a flat memory space since day 1 that only really, for all practical reasons, took off with Windows 2000 on x86 – almost 2 decades later after m68k got it.
Lastly, comparing max instruction sizes for m68k and x86 is a bit cheeky. m68k has fixed size instruction encodings that allow the CPU to use a simple lookup table to route the processing flow as well as the extracting addressing mode(s) from the opcode could instantly give an indication of the total instruction length
Whereas x86 has had the variadic ones requiring a state machine within a CPU to decode them, especially as the x86 ISA grew in size, often stalling the opcode decoder pipeline due to the non-deterministic nature of the x86 opcode encoding.
- rep_lodsb 3y agoAddresses are normally loaded with MOV on x86 too. LEA is intended to compute an address from base/index registers, using the same addressing modes that can be used to access that memory location. For example, if you had an array of 32 bit integers on the stack, an instruction like "MOV EAX,[ESP+offset+ESI*4]" would load the value of the element indexed by ESI. Change that MOV to LEA, and it would instead give you a pointer to that element that can be passed around to another function. Without LEA, this operation would require two extra additions and one shift instruction. Microsoft Assembler syntax confused this issue by being designed to make some operations more convenient, "type safe", and familiar to high-level programmers, while clumsier at getting to the raw memory addresses. That led to people using "LEA reg,MyVar" when it wasn't necessary, simply because it was shorter to type than "MOV reg,OFFSET MyVar" :)
- ddingus 3y agoThank you. I was here to write what you did and more poorly. LEA is also present on the 68K and has the same uses.