NOP (code): Difference between revisions
No edit summary |
Guy Harris (talk | contribs) →C and derivatives: Copyedit, say that C compilers generate no code for null statements or empty blocks rather than that they "ignore" them in some unspecified sense. Don't italicize the "null", but not the "statement", the second time we use the phrase. |
||
(11 intermediate revisions by 7 users not shown) | |||
Line 23: | Line 23: | ||
! Notes |
! Notes |
||
|- |
|- |
||
| [[Intel]] [[x86]] [[central processing unit|CPU]] family |
| rowspan=2 | [[Intel]] [[x86]] [[central processing unit|CPU]] family |
||
| <code>NOP</code> |
| <code>NOP</code> |
||
⚫ | |||
| 1; 1–9 for i686 and x86-64 |
|||
| |
| 0x90<ref name="x86-instruction-set-intel">{{cite web |url=https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html|title=Intel 64 and IA-32 Architectures Software Developer's Manual: Instruction Set Reference A-Z|access-date=2012-03-01}}</ref> |
||
| 0x90 is the one-byte encoding for <code>XCHG AX,AX</code> in 16-bit code and <code>XCHG EAX,EAX</code> in 32-bit code. In long mode, <code>XCHG RAX,RAX</code> requires two bytes, as it would begin with an <code>REX.W</code> prefix, making the encoding 0x48 0x90. However, 0x90 is interpreted as a <code>NOP</code> in long mode regardless of whether it is preceded by 0x48.<ref name="x86-instruction-set-intel" /> |
|||
| 0x90 decodes to "NOP". |
|||
⚫ | |||
Many people believe that "xchg rax,rax"=="NOP", but this is not correct. |
|||
⚫ | |||
`xchg rax,rax` encodes to `0x4887c0`("48" as the prefix for 64-bit numbers, "87" as the opcode for `xchg` and `c0` as the [[ModR/M]] of 2 identical registers of index 0). |
|||
| 2–9 for [[Pentium Pro]] and later Intel processors, and all AMD AMD64 processors |
|||
Most Aseemblers `are` going to encode `xchg rax,rax` into `0x90` though, both for optimization(`xchg` takes more execution time then `nop`), as well as, likely, readability. |
|||
| 0x66 0x90<br /> |
|||
`0x4890` or `0x90` don't decode as "xchg rax,rax" in 64 bit mode, they just mean "(64bit)NOP" or "NOP" respectively. |
|||
0x0F 0x1F 0x00<br /> |
|||
On the other hand, `xchg rax,rax`, while also effectively doing nothing(Exchanging rax with the value of itself), can still be manually assembled and then decodes to `xchg rax,rax`when using objdump on a manually assembled binary. |
|||
0x0F 0x1F 0x40 0x00<br /> |
|||
0x0F 0x1F 0x44 0x00 0x00<br /> |
|||
0x66 0x0F 0x1F 0x44 0x00 0x00<br /> |
|||
0x0F 0x1F 0x80 0x00 0x00 0x00 0x00<br /> |
|||
0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00<br /> |
|||
0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00<ref name="x86-instruction-set-intel" /> |
|||
| 0x66 is the operand-size override prefix. 0x0F 0x1F is a two-byte NOP opcode that takes a ModRM operand upon which no operation is performed; 0x00 is <code>[EAX]</code>, 0x40 0x00 is <code>[EAX + 00H]</code>, 0x44 0x00 0x00 is <code>[EAX + EAX*1 + 00H]</code>, 0x80 0x00 0x00 0x00 0x00 is <code>[EAX + 00000000H]</code>, and 0x84 0x00 0x00 0x00 0x00 0x00 is <code>[EAX + EAX*1 + 00000000H]</code>.<ref name="x86-instruction-set-intel" /> |
|||
|- |
|||
| [[Intel 8008]] |
|||
⚫ | |||
| 1 |
|||
| 0xC0 |
|||
| Load A from A |
|||
|- |
|- |
||
| [[Intel]] [[8051]] / [[MCS-51]] family |
| [[Intel]] [[8051]] / [[MCS-51]] family |
||
Line 38: | Line 57: | ||
| 1 |
| 1 |
||
| 0x00 |
| 0x00 |
||
| |
| |
||
|- |
|||
| [[Intel 8080]], [[Intel 8085]], [[Z80]] |
|||
| <code>NOP</code> |
|||
| 1 |
|||
⚫ | |||
| |
|||
|- |
|- |
||
| [[DEC Alpha]] |
| [[DEC Alpha]] |
||
Line 126: | Line 151: | ||
| 0xFD****** |
| 0xFD****** |
||
| SWYM stands for "Sympathize with your machinery". The * digits can be chosen arbitrarily. |
| SWYM stands for "Sympathize with your machinery". The * digits can be chosen arbitrarily. |
||
|- |
|||
| [[Motorola 6800]] |
|||
| <code>NOP</code> |
|||
| 1 |
|||
| 0x01 |
|||
| |
|||
|- |
|- |
||
| [[Motorola 68000 family]] |
| [[Motorola 68000 family]] |
||
Line 166: | Line 197: | ||
| 12 bits |
| 12 bits |
||
| 0b000000000000 |
| 0b000000000000 |
||
| |
|||
⚫ | |||
|- |
|- |
||
| rowspan=2 | [[RISC-V]] |
| rowspan=2 | [[RISC-V]] |
||
Line 178: | Line 209: | ||
| 0x0001 |
| 0x0001 |
||
| <code>C.ADDI x0, 0</code>. Only available on RISC-V CPUs that support the "C" (compressed instructions) extension.<ref>RISC-V Foundation, [https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf The RISC-V Instruction Set Manual, Volume 1: User-Level ISA], version 2.2, 7 May 2017, p.79.</ref> |
| <code>C.ADDI x0, 0</code>. Only available on RISC-V CPUs that support the "C" (compressed instructions) extension.<ref>RISC-V Foundation, [https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf The RISC-V Instruction Set Manual, Volume 1: User-Level ISA], version 2.2, 7 May 2017, p.79.</ref> |
||
|- |
|||
| [[Signetics 8X300]] |
|||
| <code>MOV AUX, AUX</code> |
|||
| 16 bits |
|||
| 0x0000 |
|||
| Move AUX to AUX with no rotate |
|||
|- |
|- |
||
| [[SPARC]] |
| [[SPARC]] |
||
Line 197: | Line 234: | ||
|url-status = dead |
|url-status = dead |
||
}}</ref> |
}}</ref> |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
| There are some other instructions without any effect (and the same timing): <code>LD A, A</code>, <code>LD B, B</code> etc. |
|||
|- |
|- |
||
| [[PDP-10]] |
| [[PDP-10]] |
||
Line 210: | Line 241: | ||
| Jump never<br>Jump never, set nothing, skip never |
| Jump never<br>Jump never, set nothing, skip never |
||
|- |
|- |
||
| [[PDP-11]] |
| [[PDP-11 architecture|PDP-11]] |
||
| <code>NOP</code> |
| <code>NOP</code> |
||
| |
| 2 |
||
| 000240 (octal) |
| 000240 (octal) |
||
| Clear none of the condition codes |
| Clear none of the condition codes |
||
Line 221: | Line 252: | ||
| 0x01 |
| 0x01 |
||
| Delay is dependent on processor type |
| Delay is dependent on processor type |
||
|- |
|||
⚫ | |||
| <code>NOP</code> |
|||
| 2 |
|||
| 0x0000 |
|||
| |
|||
|} |
|} |
||
Line 233: | Line 270: | ||
=== C and derivatives === |
=== C and derivatives === |
||
The simplest NOP statement in C is the ''null statement'', which is just a semi-colon in a context requiring a statement. |
The simplest NOP statement in C is the ''null statement'', which is just a semi-colon in a context requiring a statement. |
||
Most C compilers generate no code for null statements, which has historical and performance reasons. |
|||
; |
; |
||
An empty block (compound statement) is also a NOP, and may be more legible |
An empty block (compound statement) is also a NOP, and may be more legible, but will still have no code generated for it by the compiler. |
||
{} |
{} |
||
In some cases, such as the body of a function, a block must be used, but this can be empty. In C, statements cannot be empty—simple statements must end with a ; (semicolon) while compound statements are enclosed in {} (braces), which does not itself need a following semicolon. Thus in contexts where a statement is grammatically required, some such null statement can be used. |
In some cases, such as the body of a function, a block must be used, but this can be empty. In C, statements cannot be empty—simple statements must end with a <code>;</code> (semicolon) while compound statements are enclosed in <code>{}</code> (braces), which does not itself need a following semicolon. Thus in contexts where a statement is grammatically required, some such null statement can be used. |
||
The null statement is useless by itself, but it can have a syntactic use in a wider context, e.g., within the context of a loop: |
The null statement is useless by itself, but it can have a syntactic use in a wider context, e.g., within the context of a loop: |
||
Line 255: | Line 294: | ||
(note that the last form may be confusing, and as such generates a warning with some compilers or compiler options, as semicolon usually indicates an end of function call instruction when placed after a parenthesis on the end of line). |
(note that the last form may be confusing, and as such generates a warning with some compilers or compiler options, as semicolon usually indicates an end of function call instruction when placed after a parenthesis on the end of line). |
||
The above code continues calling the function |
The above code continues calling the function <code>getchar()</code> until it returns a <code>\n</code> (newline) character, essentially fast-forwarding the current reading location of standard input to the beginning of next line. |
||
=== Fortran === |
=== Fortran === |
Latest revision as of 08:07, 17 October 2024
Machine code |
---|
General concepts |
Instructions |
In computer science, a NOP, no-op, or NOOP (pronounced "no op"; short for no operation) is a machine language instruction and its assembly language mnemonic, programming language statement, or computer protocol command that does nothing.
Machine language instructions
[edit]Some computer instruction sets include an instruction whose explicit purpose is to not change the state of any of the programmer-accessible registers, status flags, or memory. It often takes a well-defined number of clock cycles to execute. In other instruction sets, there is no explicit NOP instruction, but the assembly language mnemonic NOP represents an instruction which acts as a NOP; e.g., on the SPARC, sethi 0, %g0
.
A NOP must not access memory, as that could cause a memory fault or page fault.
A NOP is most commonly used for timing purposes, to force memory alignment, to prevent hazards, to occupy a branch delay slot, to render void an existing instruction such as a jump, as a target of an execute instruction, or as a place-holder to be replaced by active instructions later on in program development (or to replace removed instructions when reorganizing would be problematic or time-consuming). In some cases, a NOP can have minor side effects; for example, on the Motorola 68000 series of processors, the NOP opcode causes a synchronization of the pipeline.[1]
Listed below are the NOP instruction for some CPU architectures:
CPU architecture | Instruction mnemonic | Bytes | Opcode | Notes |
---|---|---|---|---|
Intel x86 CPU family | NOP
|
1 | 0x90[2] | 0x90 is the one-byte encoding for XCHG AX,AX in 16-bit code and XCHG EAX,EAX in 32-bit code. In long mode, XCHG RAX,RAX requires two bytes, as it would begin with an REX.W prefix, making the encoding 0x48 0x90. However, 0x90 is interpreted as a NOP in long mode regardless of whether it is preceded by 0x48.[2]
|
multi-byte NOP
|
2–9 for Pentium Pro and later Intel processors, and all AMD AMD64 processors | 0x66 0x90 0x0F 0x1F 0x00 0x0F 0x1F 0x40 0x00 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00[2] |
0x66 is the operand-size override prefix. 0x0F 0x1F is a two-byte NOP opcode that takes a ModRM operand upon which no operation is performed; 0x00 is [EAX] , 0x40 0x00 is [EAX + 00H] , 0x44 0x00 0x00 is [EAX + EAX*1 + 00H] , 0x80 0x00 0x00 0x00 0x00 is [EAX + 00000000H] , and 0x84 0x00 0x00 0x00 0x00 0x00 is [EAX + EAX*1 + 00000000H] .[2]
| |
Intel 8008 | LAA
|
1 | 0xC0 | Load A from A |
Intel 8051 / MCS-51 family | NOP
|
1 | 0x00 | |
Intel 8080, Intel 8085, Z80 | NOP
|
1 | 0x00 | |
DEC Alpha | NOP
|
4 | 0x47FF041F | Opcode for BIS r31,r31,r31 , an instruction that bitwise-ORs the always-0 register with itself.
|
AMD 29k | NOP
|
4 | 0x70400101 | Opcode for aseq 0x40,gr1,gr1 , an instruction that asserts that the stack register is equal to itself.[3]
|
ARM A32 | NOP
|
4 | 0x00000000 | This stands for andeq r0, r0, r0 . The assembly instruction nop will most likely expand to mov r0, r0 which is encoded 0xE1A00000 (little-endian architecture).[4]
|
ARM T32 (16 bit) | NOP
|
2 | 0xb000 | Opcode for ADD SP, #0 - Add zero to the stack pointer (No operation). The assembly instruction nop will most likely expand to mov r8, r8 which is encoded 0x46C0.[5]
|
ARM T32 (32 bit) | NOP
|
4 | 0xF3AF 8000 | |
ARM A64 (64 bit) | NOP
|
4 | 0xD503201F | |
AVR | NOP
|
2 | 0x0000 | one clock cycle |
IBM System/360, IBM System/370, IBM System/390, z/Architecture, UNIVAC Series 90 | NOP
|
4 | 0x47000000 or 0x470nnnnn or 0x47n0nnnn where "n" is any 4-bit value. | The NOP ("No-Op") and NOPR ("No-Op Register") are a subset of the "Branch on Condition" or "Branch on Condition Register" instructions, respectively; both versions have two options for generating a NO-OP.
In the case of both the NOP and NOPR instructions, the first 0 in the second byte is the "mask" value, the condition to test such as equal, not equal, high, low, etc. If the mask is 0, no branch occurs. In the case of the NOPR instruction, the second value in the second byte is the register to branch on. If register 0 is chosen, no branch occurs regardless of the mask value. Thus, if either of the two values in the second byte is 0, the branch will not happen. In the case of the NOP instruction, the second value in the second byte is the "base" register of a combined base register, displacement register and offset address. If the base register is also 0, the branch is not taken regardless of the value of the displacement register or displacement address. |
NOPR
|
2 | 0x0700 or 0x070n or 0x07n0 where "n" is any 4-bit value. | ||
SuperH | NOP
|
2 | 0x0009 | |
MIPS | NOP
|
4 | 0x00000000 | Stands for sll r0,r0,0 , meaning: Logically shift register 0 zero bits to the left and store the result in register 0. Writes to register 0 are ignored; it always contains 0.
|
MIPS-X | NOP
|
4 | 0x60000019 | (extended opcode for add r0,r0,r0 )
|
MIX | NOP
|
1 word | ± * * * * 0 | The * bytes are arbitrary, and can be anything from 0 to the maximum byte (required to be in the range 63-99). MIX uses sign-magnitude representation. |
MMIX | SWYM
|
4 | 0xFD****** | SWYM stands for "Sympathize with your machinery". The * digits can be chosen arbitrarily. |
Motorola 6800 | NOP
|
1 | 0x01 | |
Motorola 68000 family | NOP
|
2 | 0x4E71 | This synchronizes the pipeline and prevents instruction overlap.[1] |
Motorola 6809 | NOP
|
1 | 0x12 | |
MOS Technology 65xx (e.g. 6502) | NOP
|
1 | 0xEA | NOP consumes two clock cycles. Undefined opcodes in the NMOS versions of the 65xx family were converted to be NOPs of varying instruction lengths and cycle times in the 65C02.
|
PA-RISC | NOP
|
4 | 0x08000240 | Opcode for OR 0,0,0 .[6]
|
LDI 26,0
|
4 | 0x34000034 | Palindromic NOP - that is, an instruction that executes as NOP regardless of whether byte order is interpreted as little-endian or big-endian. Some PA-RISC system instructions are required to be followed by seven palindromic NOPs.[6] | |
PowerPC | NOP
|
4 | 0x60000000 | (extended opcode for ori r0,r0,0 )
|
PIC microcontroller | NOP
|
12 bits | 0b000000000000 | |
RISC-V | NOP
|
4 | 0x00000013 | ADDI x0, x0, 0
|
C.NOP
|
2 | 0x0001 | C.ADDI x0, 0 . Only available on RISC-V CPUs that support the "C" (compressed instructions) extension.[7]
| |
Signetics 8X300 | MOV AUX, AUX
|
16 bits | 0x0000 | Move AUX to AUX with no rotate |
SPARC | NOP
|
4 | 0x01000000 | Stands for sethi 0, %g0 which zeroes the hardwired-to-zero %g0 register[8]
|
PDP-10 | JFCL 0, (conventional)JUMP, SETA, SETAI, CAI, TRN, TLN
|
1 word | 25500******* (octal) | Jump never Jump never, set nothing, skip never |
PDP-11 | NOP
|
2 | 000240 (octal) | Clear none of the condition codes |
VAX | NOP
|
1 | 0x01 | Delay is dependent on processor type |
WD16 | NOP
|
2 | 0x0000 |
From a hardware design point of view, unmapped areas of a bus are often designed to return zeroes; since the NOP slide behavior is often desirable, it gives a bias to coding it with the all-zeroes opcode.
Code
[edit]A function or a sequence of programming language statements is a NOP or null statement if it has no effect. Null statements may be required by the syntax of some languages in certain contexts.
Ada
[edit]In Ada, the null
statement serves as a NOP.[9] As the syntax forbids that control statements or functions be empty, the null
statement must be used to specify that no action is required. (Thus, if the programmer forgets to write a sequence of statements, the program will fail to compile.)
C and derivatives
[edit]The simplest NOP statement in C is the null statement, which is just a semi-colon in a context requiring a statement.
Most C compilers generate no code for null statements, which has historical and performance reasons.
;
An empty block (compound statement) is also a NOP, and may be more legible, but will still have no code generated for it by the compiler.
{}
In some cases, such as the body of a function, a block must be used, but this can be empty. In C, statements cannot be empty—simple statements must end with a ;
(semicolon) while compound statements are enclosed in {}
(braces), which does not itself need a following semicolon. Thus in contexts where a statement is grammatically required, some such null statement can be used.
The null statement is useless by itself, but it can have a syntactic use in a wider context, e.g., within the context of a loop:
while (getchar() != '\n') {}
alternatively,
while (getchar() != '\n')
;
or more tersely:
while (getchar() != '\n');
(note that the last form may be confusing, and as such generates a warning with some compilers or compiler options, as semicolon usually indicates an end of function call instruction when placed after a parenthesis on the end of line).
The above code continues calling the function getchar()
until it returns a \n
(newline) character, essentially fast-forwarding the current reading location of standard input to the beginning of next line.
Fortran
[edit]In Fortran, the CONTINUE
statement is used in some contexts such as the last statement in a DO loop, although it can be used anywhere, and does not have any functionality.
JavaScript
[edit]The JavaScript language does not have a built-in NOP statement. Many implementations are possible:
- Use the
;
empty statement[10] or the{}
empty block statement the same way as in the C and derivatives examples; - Use the
undefined
or thenull
expression as a complete statement (an expression statement) when the previous methods are not allowed by the syntax.
Alternatives, in situations where a function is required, are:
- Use the
Function.prototype()
built-in function, that accepts any arguments and returnsundefined
;[11] - Use a NOP function available in a third-party library —see below;
- Define a custom NOP function, as in the following example (using the ES6 arrow function syntax):
const noop = () => {};
AngularJS
[edit]The AngularJS framework provides angular.noop function that performs no operations.
jQuery
[edit]The jQuery library provides a function jQuery.noop()
, which does nothing.[12]
Lodash
[edit]The Lodash library provides a function _.noop()
, which returns undefined and does nothing.[13]
Pascal
[edit]As with C, the ; used by itself can be used as a null statement in Pascal. In fact, due to the specification of the language, in a BEGIN / END block, the semicolon is optional before the END statement, thus a semicolon used there is superfluous.
Also, a block consisting of BEGIN END;
may be used as a placeholder to indicate no action, even if placed inside another BEGIN / END block.
Python
[edit]The Python programming language has a pass
statement which has no effect when executed and thus serves as a NOP. It is primarily used to ensure correct syntax due to Python's indentation-sensitive syntax; for example the syntax for definition of a class requires an indented block with the class logic, which has to be expressed as pass
when it should be empty.
Shell scripting (bash, zsh, etc.)
[edit]The ':
' [colon] command is a shell builtin that has similar effect to a "NOP" (a do-nothing operation). It is not technically an NOP, as it changes the special parameter $? (exit status of last command) to 0. It may be considered a synonym for the shell builtin 'true', and its exit status is true (0).[14][15][16]
TeX macro language (ConTeXt, LaTeX, etc.)
[edit]The TeX typographical system's macro language has the \relax
command.[17] It does nothing by itself, but may be used to prevent the immediately preceding command from parsing any subsequent tokens.[18]
NOP protocol commands
[edit]Many computer protocols, such as telnet, include a NOP command that a client can issue to request a response from the server without requesting any other actions. Such a command can be used to ensure the connection is still alive or that the server is responsive. A NOOP command is part of the following protocols (this is a partial list):
Note that unlike the other protocols listed, the IMAP4 NOOP command has a specific purpose—it allows the server to send any pending notifications to the client.
While most telnet or FTP servers respond to a NOOP command with "OK" or "+OK", some programmers have added quirky responses to the client. For example, the ftpd
daemon of MINIX responds to NOOP with the message:[19]
200 NOOP to you too!
Cracking
[edit]NOPs are often involved when cracking software that checks for serial numbers, specific hardware or software requirements, presence or absence of hardware dongles, etc. in the form of a NOP slide. This process is accomplished by altering functions and subroutines to bypass security checks and instead simply return the expected value being checked for. Because most of the instructions in the security check routine will be unused, these would be replaced with NOPs, thus removing the software's security functionality without altering the positioning of everything which follows in the binary.
Security exploits
[edit]The NOP opcode can be used to form a NOP slide, which allows code to execute when the exact value of the instruction pointer is indeterminate (e.g., when a buffer overflow causes a function's return address on the stack to be overwritten).
See also
[edit]- Comment (computer programming) – annotations generally for programmers that are ignored by compilers and interpreters
- Computer architecture
- Filler text
- Halt and Catch Fire – also pauses the CPU
- HLT (x86 instruction) – pauses the CPU
- Identity function – the functional programming equivalent to NOP
- IEFBR14 – mainframe tautology
- xyzzy (computing) – a command sometimes used instead of NOP
- X86 instruction listings#Added in P5/P6-class processors -
NOPL
, the official longNOP
References
[edit]- ^ a b "Motorola 68000 Programmer's Reference Manual" (PDF).
- ^ a b c d "Intel 64 and IA-32 Architectures Software Developer's Manual: Instruction Set Reference A-Z". Retrieved 2012-03-01.
- ^ AMD, Am29050 Microprocessor User's Manual, 1991, pages 223 and 257.
- ^ "4.8.4. NOP ARM pseudo-instruction". RealView Compilation Tools for BREW Assembler Guide.
- ^ "5.6.3. NOP Thumb pseudo-instruction". RealView Compilation Tools for BREW Assembler Guide.
- ^ a b Hewlett-Packard, PA-RISC 2.0 Architecture, 1995, pages 2-21 and 7-103. Archived on Jun 21, 2020.
- ^ RISC-V Foundation, The RISC-V Instruction Set Manual, Volume 1: User-Level ISA, version 2.2, 7 May 2017, p.79.
- ^ Weaver, D. L.; Germond, T., eds. (1994). The SPARC Architecture Manual, Version 9 (PDF). Prentice Hall. ISBN 0-13-825001-4. Archived from the original (PDF) on 2012-01-18. Retrieved 2014-01-09.
Note that NOP is a special case of the SETHI instruction, with imm22 = 0 and rd = 0.
- ^ Ada Reference Manual — null statements. "The execution of a null_statement has no effect."
- ^ MDN JavaScript reference – empty statement. "The empty statement is a semicolon (
;
) indicating that no statement will be executed, even if JavaScript syntax requires one." - ^ ECMAScript Language Specification – Edition 5.1 – Properties of the Function Prototype Object
- ^ jQuery.noop() from jQuery API documentation
- ^ "Lodash Documentation". lodash.com. Retrieved 2017-12-15.
- ^ Advanced Bash-Scripting Guide > Chapter 3. Special Characters
- ^ bash manpage > SHELL BUILTIN COMMANDS
- ^ zsh manpage (zshbuiltins) > SHELL BUILTIN COMMANDS
- ^ Bausum, David (2002). "TeX Primitive Control Sequences". TeX Reference Manual. Kluwer Academic Publishers. Retrieved 1 April 2020.
According to The TeXbook, 'TeX does nothing' when it encounters
\relax
. Actually,\relax
may tell TeX, 'This is the end of what you've been doing'. - ^ TeX wikibook – relax
- ^ "ftpd.c". Retrieved 2016-06-19.