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?

- 15,848
- 18
- 99
- 158

- 1,092
- 2
- 18
- 27
-
2Machine 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 Answers
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.)

- 328,167
- 45
- 605
- 847
-
2Nitpick: 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
-
2Right, 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