Chapter 8. Pseudo Op-Codes (Directives)
Prev |  | Next

## Chapter 8. Pseudo Op-Codes (Directives)

This chapter describes pseudo op-codes (directives). These pseudo op-codes influence the assembler's later behavior.

## Op-Codes

The assembler has the following pseudo op-codes:

Pseudo Op-Codes

Pseudo-Op |  | Description
.`2byte` expression1 [ , expression2 ] ... [ , expressionN] |  | Truncates the expressions in the comma-separated list to 16-bit values and assembles the values in successive locations. The expressions must be absolute or in the form of a label difference ( label1 - label2) if both labels are defined in the same section. This directive optionally can have the form expression1 [ : expression2 ]. The expression2 replicates expression1's value expression2 times. This directive does no automatic alignment. (64-bit and N32 only)
.`4byte` expression1 [ , expression2 ] ... [ , expressionN] |  | Truncates the expressions in the comma-separated list to 32-bit values and assembles the values in successive locations. The expressions must be absolute or in the form of a label difference ( label1 - label2) if both labels are defined in the same section. This directive optionally can have the form expression1 [ : expression2 ]. The expression2 replicates expression1's value expression2 times. This directive does no automatic alignment. (64-bit and N32 only)
.`8byte` expression1 [ , expression2 ] ... [ , expressionN] |  | Truncates the expressions in the comma-separated list to 64-bit values and assembles the values in successive locations. The expressions must be absolute or in the form of a label difference ( label1 - label2) if both labels are defined in the same section. This directive optionally can have the form expression1 [ : expression2 ]. The expression2 replicates expression1's value expression2 times. This directive does no automatic alignment. (64-bit and N32 only)
.`aent` name, `symno` |  | Sets an alternate entry point for the current procedure. Use this information when you want to generate information for the debugger. It must appear inside an `.ent`/`.end` pair.
`.align` expression |  | Advances the location counter to make the expression low order bits of the counter zero. Normally, the `.half`, `.word`, `.float`, and `.double` directives automatically align their data appropriately. For example, `.word` does an implicit `.align 2` (`.double` does an `.align 3`). You disable the automatic alignment feature with `.align 0`. The assembler reinstates automatic alignment at the next .`text`, .`data`, .`rdata`, or .`sdata` directive. Labels immediately preceding an automatic or explicit alignment are also realigned. For example, `foo: .align 3; .word 0` is the same as `.align 3; foo: .word 0`.
`.ascii` string [, string]... |  | Assembles each string from the list into successive locations. The `.ascii` directive does not null pad the string. You must put quotation marks (”) around each string. You can use the backslash escape characters. For a list of the backslash characters, see Chapter 4, “Lexical Conventions”.
`.asciiz` string [, string]... |  | Assembles each string in the list into successive locations and adds a null. You can use the backslash escape characters. For a list of the backslash characters, see Chapter 4, “Lexical Conventions”.
.`byte` expression1 [, expression2 ] ... [, expressionN] |  | Truncates the expressions from the comma-separated list to 8-bit values, and assembles the values in successive locations. The expressions must be absolute. The operands can optionally have the form: expression1 [ : expression2 ]. The expression2 replicates expression1's value expression2 times.
.`comm` name, expression [alignment] |  | Unless defined elsewhere, name becomes a global common symbol at the head of a block of expression bytes of storage. The linker overlays like-named common blocks, using the maximum of the expressions. The 64-bit and N32 assembler also accepts an optional value which specifies the alignment of the symbol.
.`cpadd` reg |  | Emits code that adds the value of “`_gp`” to reg.
.`cpload` reg |  | Expands into the three instructions function prologue that sets up the `$gp` register. This directive is used by position-independent code.
.`cplocal` reg |  | Causes the assembler to use reg instead of $gp as the context pointer. This directive is used by position-independent code. (64-bit and N32 only)
.`cprestore` offset |  | Causes the assembler to emit the following at the point where it occurs: `sw $gp, offset ($sp)` Also, causes the assembler to generate `lw $gp, offset ($sp)` after every JAL or BAL operation. Offset should point to the saved register area as described in Chapter 7, “Writing Assembly Language Code”. This directive is used by position-independent code following the caller-saved `gp` convention.
`.cpreturn` |  | Causes the assembler to emit the following at the point where it occurs: `ld $gp, offset ($sp)` The offset is obtained from the previous `.cpsetup` pseudo-op. (64-bit and N32 only)
.`cpsetup` reg1, {offset | reg2}, label |  | Causes the assembler to emit the following at the point where it occurs: `sd $gp, offset ($sp)` `lui $gp, 0 {label}` `daddiu $gp, $gp, 0 { label }` `daddu $gp, $gp, reg1` `ld $gp, offset ($sp)` This sequence is used by position-independent code following the callee-saved `gp` convention. It stores `$gp` in the saved register area and calculates the virtual address of label and places it in reg1. By convention, reg1 is `$25` (`t9`). If reg2 is used instead of offset, `$gp` is saved and restored to and from this register. (64-bit and N32 only)
`.data` |  | Tells the assembler to add all subsequent data to the data section.
.`double` expression [ , expression2] ...[, expressionN] |  | Initializes memory to 64-bit floating point numbers. The operands optionally can have the form: expression1 [ : expression2 ]. The expression1 is the floating point value. The optional expression2 is a non-negative expression that specifies a repetition count. The expression2 replicates expression1's value expression2 times. This directive aligns its data and any preceding labels automatically to a double-word boundary. You can disable this feature by using .`align0`.
`.dword` expression [ , expression2 ] ...[, expressionN] |  | Truncates the expressions in the comma-separated list to 64-bits and assembles the values in successive locations. The expressions must be absolute. The operands optionally can have the form: expression1 [:expression2]. The expresssion2 replicates expression1's value expression2 number of times. The directive aligns its data and preceding labels automatically to a doubleword boundary. You can disable this feature by using .`align0`.
`.dynsym` name value |  | Specifies an ELF `st_other` value for the object denoted by name (64-bit and N32 only).
.`end` [proc_name] |  | Sets the end of a procedure. Use this directive when you want to generate information for the debugger. To set the beginning of a procedure, see .`ent`.
.`endr` |  | Signals the end of a repeat block. To start a repeat block, see .`repeat`.
.`ent` proc_name |  | Sets the beginning of the procedure proc_name. Use this directive when you want to generate information for the debugger. To set the end of a procedure, see .`end`.
.`extern` name expression |  | name is a global undefined symbol whose size is assumed to be expression bytes. The advantage of using this directive, instead of permitting an undefined symbol to become global by default, is that the assembler can decide whether to use the economical `$gp`-relative addressing mode, depending on the value of the -`G` option. As a special case, if expression is zero, the assembler refrains from using `$gp` to address this symbol regardless of the size specified by -`G`.
.`file` file_number file_name_string |  | Specifies the source file corresponding to the assembly instructions that follow. For use only by compilers, not by programmers; when the assembler sees this, it refrains from generating line numbers for `dbx` to use unless it also sees `.loc` directives.
`.float` expression1 [ , expression2 ] ... [, expressionN] |  | Initializes memory to single precision 32-bit floating point numbers. The operands optionally can have the form: expression1`<_newline>`[ : expression2 ]. The optional expression2 is a non-negative expression that specifies a repetition count. This optional form replicates expression1's value expression2 times. This directive aligns its data and preceding labels automatically to a word boundary. You can disable this feature by using .`align0`.
`.fmask` mask offset |  | Sets a mask with a bit turned on for each floating point register that the current routine saved. The least-significant bit corresponds to register `$f0`. The offset is the distance in bytes from the virtual frame pointer at which the floating point registers are saved. The assembler saves higher register numbers closer to the virtual frame pointer. You must use `.ent` before `.fmask` and only one `.fmask` may be used per `.ent`. Space should be allocated for those registers specified in the `.fmask`.
`.frame` frame-register offset return_pc_register |  | Describes a stack frame. The first register is the frame-register, the offset is the distance from the frame register to the virtual frame pointer, and the second register is the return program counter (or, if the first register is `$0`, this directive shows that the return program counter is saved four bytes from the virtual frame pointer). You must use .`ent` before .`frame` and only one .`frame` may be used per .`ent`. No stack traces can be done in the debugger without .`frame`.
.`globl` name |  | Makes the name external. If the name is defined otherwise (by its appearance as a label), the assembler will export the symbol; otherwise it will import the symbol. In general, the assembler imports undefined symbols (that is, it gives them the UNIX storage class “global undefined” and requires the linker to resolve them).
`.gpvalue` number |  | Sets the offset to use in gp_rel relocations; 0 by default. (64-bit and N32 only).
`.gpword` local-sym |  | This directive is similar to `.word` except that the relocation entry for local-sym has the `R_MIPS_GPREL32` type. After linkage, this results in a 32-bit value that is the distance between local-sym and `gp`. local-sym must be local. This directive is used by the code generator for PIC switch tables.
.`half` expression1 [ , expression2 ] ... {, expressionN] |  | Truncates the expressions in the comma-separated list to 16-bit values and assembles the values in successive locations. The expressions must be absolute. This directive optionally can have the form: expression1 [ : expression2 ]. The expression2 replicates expression1's value expression2 times. This directive automatically aligns its data appropriately. You can disable this feature by using `.align0`.
.`lab` label_name |  | Associates a named label with the current location in the program text. For use by compilers.
.`lcomm` name, expression |  | Makes the name's data type `bss`. The assembler allocates the named symbol to the `bss` area, and the expression defines the named symbol's length. If a .`globl` directive also specifies the name, the assembler allocates the named symbol to external `bss`. The assembler puts `bss` symbols in one of two `bss` areas. If the defined size is smaller than (or equal to) the size specified by the assembler or compiler's -`G` command line option, the assembler puts the symbols in the `sbss` area and uses `$gp` to address the data.
.`loc` file_number line_number [column] |  | Specifies the source file and the line within that file that corresponds to the assembly instructions that follow. For use by compilers. The assembler ignores the file number when this directive appears in the assembly source file. Then, the assembler assumes that the directive refers to the most recent .`file` directive. The 64-bit and N32 assembler also supports an optional value that specifies the column number.
.`mask` mask, offset |  | Sets a mask with a bit turned on for each general purpose register that the current routine saved. For use by compilers. Bit one corresponds to register `$1`. The offset is the distance in bytes from the virtual frame pointer where the registers are saved. The assembler saves higher register numbers closer to the virtual frame pointer. Space should be allocated for those registers appearing in the mask. If bit zero is set it is assumed that space is allocated for all 31 registers regardless of whether they appear in the mask. For N32/64, only bit 31 for `$ra` is utilized; the rest are ignored.
`.nada` |  | Tells the assembler to put in an instruction that has no effect on the machine state. It has the same effect as `nop` (described below), but it produces more efficient code on an R8000. (64-bit and N32 only)
`.nop` |  | Tells the assembler to put in an instruction that has no effect on the machine state. While several instructions cause no-operation, the assembler only considers the ones generated by the `nop` directive to be wait instructions. This directive puts an explicit delay in the instruction stream.
| Note: Unless you use `.set noreorder`, the reorganizer may eliminate unnecessary `nop` instructions.
.`option` options |  | Tells the assembler that certain options were in effect during compilation. (These options can, for example, limit the assembler's freedom to perform branch optimizations.) This option is intended for compiler-generated `.s` files rather than for hand-coded ones.
`.origin` expression |  | Specifies the current offset in a section to the value of expression. (64-bit and N32 only)
.`repeat` expression |  | Repeats all instructions or data between the .`repeat` directive and the .`endr` directive. The expression defines how many times the data repeats. With the .`repeat` directive, you cannot use labels, branch instructions, or values that require relocation in the block. To end a .`repeat`, see .`endr`.
`.restore` reg |  | The following instruction restores the value in reg. This is used to provide correct information for stack unwinding. There must be an earlier `.save` reg that this is following. (64-bit and N32 only)
`.rdata` |  | Tells the assembler to add subsequent data into the `rdata` section.
`.save` reg |  | The following instruction saves the value in reg. This is used to provide correct information for stack unwinding. (64-bit and N32 only)
`.sdata` |  | Tells the assembler to add subsequent data to the `sdata` section.
.`section` name [, section type, section flags, section entry size, section alignment] |  | Instructs the assembler to create a section with the given name and optional attributes. Legal section type values are denoted by variables prefixed by `SHT_ in` <elf.h>. Legal section flags values are denoted by variables prefixed by `SHF_ in` <elf.h>. The section entry size specifies the size of each entry in the section. For example, it is 4 for `.text` sections. The section alignment specifies the byte boundary requirement for the section. For example, it is 16 for `.text` sections. (64-bit and N32 only)
.`set` option |  | Instructs the assembler to enable or to disable certain options. Use .`set` options only for hand-crafted assembly routines. The assembler has these default options: `reorder`, `macro`, and `at`. You can specify only one option for each .`set` directive. You can specify these .`set` options: The `reorder` option lets the assembler reorder machine language instructions to improve performance. The `noreorder` option prevents the assembler from reordering machine language instructions. If a machine language instruction violates the hardware pipeline constraints, the assembler issues a warning message. The `macro` option lets the assembler generate multiple machine instructions from a single assembler instruction. The `nomacro` option causes the assembler to print a warning whenever an assembler operation generates more than one machine language instruction. You must select the `noreorder` option before using the `nomacro` option; otherwise, an error results. The`at` option lets the assembler use the $at register for macros, but generates warnings if the source program uses `$at`. When you use the `noat` option and an assembler operation requires the `$at` register, the assembler issues a warning message; however, the `noat` option does let source programs use `$at` without issuing warnings. The `nomove` option tells the assembler to mark each subsequent instruction so that it cannot be moved during reorganization. Because the assembler can still insert `nop` instructions where necessary for pipeline constraints, this option is less stringent than `noreorder`. The assembler can still move instructions from below the nomove region to fill delay slots above the region or vice versa. The `nomove` option has part of the effect of the “volatile” C declaration; it prevents otherwise independent loads or stores from occurring in a different order than intended. The `move` option cancels the effect of `nomove`. The `notransform` option tells the assembler to mark each subsequent instruction so that it cannot be transformed by `pixie`(1) into an equivalent set of instructions. There are restrictions on the use of this option in order to guarantee `pixie`'s ability to still produce code that will execute correctly with the preceding/following transformed code. The sequence of instructions marked `notransform` must behave like a single basic block (i.e., there is only one entry and exit from the sequences and they are the first and last instructions, respectively). If this restriction cannot be met, correct transformed execution can still be guaranteed if the sequence of instructions does not use any of the saved registers `$16..$23, $30` (s0-s8). The `transform` option cancels the effect of `notransform`.
`.size` name, expression |  | Specifies the size of an object denoted by name to the value of expression.
`.space` expression |  | Advances the location counter by the value of the specified expression bytes. The assembler fills the space with zeros.
.`struct` expression |  | This permits you to lay out a structure using labels plus directives like `.word`, .`byte`, and so forth. It ends at the next segment directive (.`data`, .`text`, etc.). It does not emit any code or data, but defines the labels within it to have values which are the sum of expression plus their offsets from the .`struct` itself.
(symbolic equate) |  | Takes one of these forms: name = expression or name = register. You must define the name only once in the assembly, and you cannot redefine the name. The expression must be computable when you assemble the program, and the expression must involve operators, constants, and equated symbols. You can use the name as a constant in any later statement.
`.text` |  | Tells the assembler to add subsequent code to the text section. (This is the default.)
.`type` name, value |  | Specifies the `elf` type of an object denoted by name to value. Legal `elf` type values are denoted by variables prefixed by `STT_ in` <elf.h>. (64-bit and N32 only)
.`verstamp` major minor |  | Specifies the major and minor version numbers (for example, version 0.15 would be .`verstamp` 0 15).
`.weakext` weak_name [strong_name] |  | Defines a weak external name and optionally associates it with the strong_name.
`.word` expression1 [, expression2 ] ... [, expressionN] |  | Truncates the expressions in the comma-separated list to 32-bits and assembles the values in successive locations. The expressions must be absolute. The operands optionally can have the form: expression1 `<_newline>`[ : expression2 ]. The expression2 replicates expression1's value expression2 times. This directive aligns its data and preceding labels automatically to a word boundary. You can disable this feature by using .`align0`.

The directives listed below are only accepted in `-o32` compiles; they are only meant for compiler-generated code, and should not be used in hand-written assembly code.

`.alias`
`.asm0`
`.bgnb`
`.endb`
`.err`
`.gjaldef`
`.gjallive`
`.gjrlive`
`.livereg`
`.noalias`
`.set bopt/nobopt`
`.vreg`

## PIC Assembly Code

By default, the assembler and compilers generate position-independent code (PIC). This is needed for programs that use dynamic shared libraries. For programs assembled with the `-n32` and `-64` options to `as(1)`, see the MIPSpro 64-Bit Porting and Transition Guide for further information.

If you want to generate PIC with the assembler using the `-o32` option, assemble with the `-KPIC` and `-G0` options, which are enabled by default.

The following assembler directives support PIC generation: `.option pic2`, `.cpload`, `.cprestore`, `.gpword`, and `.cpadd`. See “Op-Codes” for information about the directives. The following example illustrates the use of these directives with the `-o32` option.

Example 8-1. `KPIC` directives example

Consider the following program:

         .option   pic2
         .data
         .align    2
    $$5:
         .ascii    "hello world\X0A\X00"
         .text
         .align    2
    main:
         .set   noreorder
         .cpload   $25
         .set   reorder
         subu $sp, 40
         sw   $31, 36($sp)
         .cprestore     32
         la   $4, $$5
         jal  printf
         move $2, $0
         lw   $31, 36($sp)
         addu $sp, 40
         j    $31

The actual instructions generated by the assembler are as follows:

         lui  gp,0     #
         addiu   gp,gp,0     #generated by .cpload
         addu gp,gp,t9 #
         lw   a0,0(g0) # gp-relative addressing used
         lw   t9,0(gp) # t9 is used for func. call
         addiu   sp,sp,-40
         sw   ra,36(sp)
         sw   gp,32(sp)# from .cprestore
         jalr ra,t9    # jal is changed to jalr
         addiu   a0,a0,0
         lw   ra,36(sp)
         lw   gp,32(sp)# activated by .cprestore
         move v0,zero
         jr   ra
         addiu   sp,sp,40
         nop

The ABI requires that register `t9` (`$25`) be used for indirect function calls, so `.cpload` should always use `$25`; no-reorder mode should also be used. Make sure that `t9` is dead before any function call, because the register is changed (and not restored) during the function call.

If your program uses an indirect jump (`jalr`), you must also use `t9` as the jump register.

If you have an unconditional jump to an external label (`j _cerror`), rewrite it into an indirect jump using `t9`, as in this example:

         la t9,_cerror
         j  t9

If you use branch-and-link (`bal`) instructions and if the target procedure begins with a `.cpload`, specify an alternate entry point, as in this example:

         foo: .set noreorder   #callee
              .cpload   $25
              .set reorder
         $$1: ...              # alternative entry point
              ...
              j   $31          # foo returns
         bar: ...              # caller
              ...
              bal  $$1         # bypass the .cpload
              ...

The alternate entry point is important because `.cpload` assumes register `$25` contains the address of `foo`, but in this case, `$25` is not set up. Because both `foo` and `bar` reside in the same file, they must have the same value for `$gp`. The `.cpload` instructions can be and must be bypassed, but because `foo` can still be called from outside, the `.cpload` is still required.

If you don't want to have an alternate entry point, you can set up register `$25` before the `bal`, as in the following:

         la   t9, foo
         bal  foo

Entries of the address table created by `.gpword` are converted into displacement from the context pointer. To get the correct text address, `.cpadd` should be used to add the value of `gp` back to them. The `gp` is updated by the runtime linker, so the correct text address can be reconstructed regardless of the location of the DSO.

Prev | Table of Contents | Next
Chapter 7. Writing Assembly Language Code |  | Index