Copyright (C) 2000-2012 |
GNU Info (nasm.info)Section 3.33.3. Effective Addresses ======================== An effective address is any operand to an instruction which references memory. Effective addresses, in NASM, have a very simple syntax: they consist of an expression evaluating to the desired address, enclosed in square brackets. For example: wordvar dw 123 mov ax,[wordvar] mov ax,[wordvar+1] mov ax,[es:wordvar+bx] Anything not conforming to this simple system is not a valid memory reference in NASM, for example `es:wordvar[bx]'. More complicated effective addresses, such as those involving more than one register, work in exactly the same way: mov eax,[ebx*2+ecx+offset] mov ax,[bp+di+8] NASM is capable of doing algebra on these effective addresses, so that things which don't necessarily _look_ legal are perfectly all right: mov eax,[ebx*5] ; assembles as [ebx*4+ebx] mov eax,[label1*2-label2] ; ie [label1+(label1-label2)] Some forms of effective address have more than one assembled form; in most such cases NASM will generate the smallest form it can. For example, there are distinct assembled forms for the 32-bit effective addresses `[eax*2+0]' and `[eax+eax]', and NASM will generally generate the latter on the grounds that the former requires four bytes to store a zero offset. NASM has a hinting mechanism which will cause `[eax+ebx]' and `[ebx+eax]' to generate different opcodes; this is occasionally useful because `[esi+ebp]' and `[ebp+esi]' have different default segment registers. However, you can force NASM to generate an effective address in a particular form by the use of the keywords `BYTE', `WORD', `DWORD' and `NOSPLIT'. If you need `[eax+3]' to be assembled using a double-word offset field instead of the one byte NASM will normally generate, you can code `[dword eax+3]'. Similarly, you can force NASM to use a byte offset for a small value which it hasn't seen on the first pass (see *Note Section 3.8:: for an example of such a code fragment) by using `[byte eax+offset]'. As special cases, `[byte eax]' will code `[eax+0]' with a byte offset of zero, and `[dword eax]' will code it with a double-word offset of zero. The normal form, `[eax]', will be coded with no offset field. The form described in the previous paragraph is also useful if you are trying to access data in a 32-bit segment from within 16 bit code. For more information on this see the section on mixed-size addressing (*Note Section 9.2::). In particular, if you need to access data with a known offset that is larger than will fit in a 16-bit value, if you don't specify that it is a dword offset, nasm will cause the high word of the offset to be lost. Similarly, NASM will split `[eax*2]' into `[eax+eax]' because that allows the offset field to be absent and space to be saved; in fact, it will also split `[eax*2+offset]' into `[eax+eax+offset]'. You can combat this behaviour by the use of the `NOSPLIT' keyword: `[nosplit eax*2]' will force `[eax*2+0]' to be generated literally. automatically generated by info2www version 1.2.2.9 |