2

This is more of a general theoretical question.

I am learning some assembly languages and have noticed that some software, such as MARS for MIPS, implements abstractions that don't exist in the architecture's real instruction set which seem to be called pseudoinstrucions, and example of which being li, and other confortable abstractions such as neat array creation and etc.

My questions are:

  • Is there some reason for me to avoid these confy abstractions if I wish to be a professional assembly programmer?
  • Is professional assembly programming devoid of this type of abstraction?

I am a little suspicious that it only exists for educational purposes, but have not found any information on this.

zx485
  • 28,498
  • 28
  • 50
  • 59
Lara
  • 89
  • 7
  • 2
    I am afraid this question will elicit answers that are largely opinion-based, which would make it off-topic here. I have used assembly language fairly extensively in a professional context (especially x86, ARM, SPARC plus a smattering of other architectures) and have used available pseudoinstructions since they tend to enhance readability and clarity (the function of code is not only to communicate with a machine but also with other humans that read the code). (IMHO) in rare circumstances performance requirements may make it advisable to refrain from the use of pseudoinstructions. – njuffa Feb 11 '21 at 21:16
  • I see... next time I will seek such answers elsewhere. Thanks for sharing your experience though. – Lara Feb 11 '21 at 21:40

1 Answers1

4

As a "professional assembly programmer", you would be remiss to use the obscure 3-operand forms that can move a value from one register to another instead of the easy to read move pseudo instruction, same with using the obscure 3-operand forms to move an immediate into a register instead of the easy to read li pseudo instruction.

The main reason to avoid pseudo instructions is if your instructor says you can't use them.

However, in using them, we should understand them, and that they can result in unexpected inefficiencies.  Many pseudo instructions (but not all) expand into 2 or 3 real hardware instructions.  Using them hides opportunities for optimization.

For one example, branches comparing register to immediate (not supported directly by hardware) have an expansion that requires loading an immediate value into a register so as to use the register to register comparisons.  If you are aware of that, then doing this in a loop, we might instead load the immediate into a register outside/before the loop to save that instruction & its cycles inside the loop.

Further, in general, MIPS assemblers support pseudo instructions expanded and interconnected using a CPU register $at.  Thus, assembly programmers are admonished not to use this register; calling conventions describe $at as "reserved for the assembler".  However, CPU registers are valuable resources, and this dedicated reservation is a waste.  (Note that compilers are not bound to this reservation, and can freely use $at as a scratch register [call clobbered].)

RISC V and its assemblers have eliminated this "assembler reservation" register (giving it back to the programmers) and only supports pseudo instructions that can be done without an assembler-dedicated register.  While the various lw $regtrg, label($regsrc) forms (ugly as they are) are still supported, the similar sw forms are not because those would require an additional register!  RISC V has also removed the two $k registers (reserved for operating system), giving those back to user mode code, and, also extended the calling convention to pass more parameters in registers.  These changes make RISC V use the scarce resources (CPU registers) quite a bit more efficiently.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53