Search code examples
algorithmassemblyx86real-mode

use of multi register to work with large numbers


how to use of multi register to work with large numbers?


assuming you need to do some calculation of large numbers that can not fit in 32 bit register and the only way to solve your problem is use registers, the memory solution is not available


like multiplication and deviation:

we have edx:eax

is there is a way or an algorithm or an instruction to put your value directly in reg1:reg2:reg3...regn ?

like if you have dq in memory how to store it in two register of 32 bit in one shout if it is possible


Solution

  • With old 8080 and Z80 CPUs there was direct support for multi-register operations, although only with pre-selected pairs of registers, like the Z80 had 8 bit registers a, b, c, d, e, h, l and instructions like add hl,de operating with 16b pairs of them (but for example this 16b add does not update flags, contrary to 8 bit add d,e, etc. and they are somewhat slower than 8 bit variants, so there's still some penalty for using 16 bit values, although usually 16b pairs are more efficient than same task written with 8 bit instructions only.

    This feature of 8080 was inspiration (I guess, no facts) of 8086 ah:al = ax 8b registers forming 16b registers and having instructions operating not only with 8 bit registers but also with the pre-selected pairs. Although 8086 is lot more like native 16b CPU, so this feature is rather "let support the breakdown of 16b registers to 8b for making migration of 8b SW easier", than "let support pairing two 8b registers for 16b math".

    After that with 80386 this practice was abandoned, and the 32 bit extension of a register called eax didn't add new alias for upper 16b part, making it harder to access it separately (the low 16b is aliased by original ax, which is needed for backward compatibility with 8086/186/286 any way).

    Because those extra 16b registers of upper parts of eax, ebx, ... would bump up the number of registers considerably, making the old instruction encoding not feasible any more, and actually with the nature of x86 instruction set it would be quite difficult to keep basic instructions mostly 2 bytes long, the extra combinations would probably raise that average toward 3 bytes.

    Now your idea of supporting many more multi-register combinations would explode the required opcodes even more and faster, so such ISA would need probably about 4-6 bytes per instruction on average.

    While basically it took quite some decade before people did start to feel seriously limited by 16b math (having values from 0 to 65535 did look to me as quite a lot, back when I was doing some programs on ZX Spectrum with Z80 CPU), and the 32b was true breakthrough, even most of the real-life human math task like prices in shop/etc. can be done with 32b integers easily. It took another decade+ to hit this limit more often (than just in special cases), like when whole movies did start to be encoded on disk, and disks generally went over gigabytes size.

    So what you are asking is usually not needed at all (pushed even much further by the 64b options today, which covers insane range of values), and when one eventually needs that, it's very simple to build that from separate instructions... like for example 80386+ code to add eax:ebx:ecx with esi:edi:edx:

        ; eax:ebx:ecx += esi:edi:edx  (96b integer addition)
        add  ecx, edx
        adc  ebx, edi
        adc  eax, esi
    

    Simple enough to not justify the above mentioned explosion of opcode sizes for putting such thing directly into the CPU.