3

While studying on Assembly language programming I came across the terms "Pseudo-op" and "Machin-op".I am not sure what is their functionalities and how they differ from each other?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
james.bondu
  • 1,092
  • 2
  • 18
  • 27
  • 2
    Machine ops are usually assembly instructions that generate specific machine code. Pseudo-ops don't necessarily generate machine code. Often pseudo-ops are also called assembler directives, and as an example these are the directives in _GCC_: https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops – Michael Petch Nov 24 '16 at 06:07

1 Answers1

4

Besides assembler directives, it's common for RISC architectures to have pseudo-ops that expand to multiple instructions.

The most common type is a pseudo-op for the sequence of instructions needed to get a 32-bit constant (e.g. an address) into a register. Since a fixed-with 32-bit instruction doesn't have room for an arbitrary 32-bit immediate, the machine can't do it in one instruction. However, there's usually nothing to gain from separating the pair of instructions with 16-bit immediates, it would be annoying to do it manually. (IIRC, some superscalar in-order CPUs recognize such pairs when executed back-to-back, still running them in parallel even though they modify the same register.) ARM assembler pseudo-instructions MOV32 and ADRL do this.

Another interesting example is ARM's ldr r0, =0x12345678. It always assembles to one instruction, but can choose from two strategies: if the constant can be represented as a immediate (using ARM's barrel shifter), the assembler uses a MOV. If not, it puts the constant into a nearby literal pool and uses a PC-relative load. So this pseudo-op can emit an instruction and data (still in the same section, I think).

(The non-pseudo-op form of the LDR instruction is the normal load-register form supporting ARM's various addressing modes, like ldr r0, [r1, r3, lsl #2] to load from r1 + r3 <<2). So the same mnemonic can be a pseudo-op or machine instruction depending on the operands


MIPS takes pseudo-instructions to the extreme, with the normal ABI reserving at least one of the 32 architectural registers for use as a temporary by assembler-generated pseudo-ops! (I guess the MIPS designers felt that 32 was really more than needed, because in the standard ABI it's normal for interrupt handlers to asynchronously clobber 2 other registers, making them unsafe for use by user-space code. I guess that simplifies the design vs. having the hardware help more in saving/restoring architectural state on interrupts, but I haven't looked at the details.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 2
    Nitpick: This `LDR` form only generates a single instruction, in this case placing a 32-bit constant in a literal pool near which may then be indexed from the load. `MOV32` and `ADRL` do piece together constants from multiple instructions however. – doynax Nov 24 '16 at 11:19
  • @doynax: hrm, I thought LDR could choose different strategies. Is it just that it can choose a MOV if the constant does fit into a single immediate? – Peter Cordes Nov 24 '16 at 14:52
  • 2
    Right, it may choose a single-instruction immediate `MOV` while `ADRL` and `MOV32` always arithmetically compute the address in two instructions. At least that what is the IAR ARM assembler did last time I checked. `ADRL` is especially curious since it only supports assembly-time expressions yet still generates dummy instructions for short distances. A best-effort immediate pseudo-op would certainly be useful but perhaps it was deemed safer to give the programmer explicit control, what with the random flag side-effects on Thumb and such. – doynax Nov 24 '16 at 15:59
  • 1
    @doynax: thanks, corrected my answer to describe LDR accurately. Its constant-pool behaviour is actually another interesting example of a pseudo-op, since it generates both instructions and data. – Peter Cordes Nov 24 '16 at 21:33