8.1: Addresses and Values
- Page ID
- 19904
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)On a 64-bit architecture, addresses require 64-bits.
As noted in the previous chapter, the only way to access memory is with the brackets ([]'s). Omitting the brackets will not access memory and instead obtain the address of the item. For example:
mov rax, qword [var1] ; value of var1 in rax mov rax, var1 ; address of var1 in rax
Since omitting the brackets is not an error, the assembler will not generate error messages or warnings.
When accessing memory, in many cases the operand size is clear. For example, the instruction
mov eax, [rbx]
moves a double-word from memory. However, for some instructions the size can be ambiguous. For example,
inc [rbx] ; error
is ambiguous since it is not clear if the memory being accessed is a byte, word, or double-word. In such a case, operand size must be specified with either the byte, word, or dword, qword size qualifier. For example,
inc byte [rbx] inc word [rbx] inc dword [rbx]
each instruction requires the size specification in order to be clear and legal.
Register Mode Addressing
Register mode addressing means that the operand is a CPU register (eax, ebx, etc.). For example:
mov eax, ebx
Both eax and ebx are in register mode addressing.
Immediate Mode Addressing
Immediate mode addressing means that the operand is an immediate value. For example:
mov eax, 123
The destination operand, eax , is register mode addressing. The 123 is immediate mode addressing. It should be clear that the destination operand in this example cannot be immediate mode.
Memory Mode Addressing
Memory mode addressing means that the operand is a location in memory (accessed via
an address). This is referred to as indirection or dereferencing.
The most basic form of memory mode addressing has been used extensively in the
previous chapter. Specifically, the instruction:
mov rax, qword [qNum]
Will access the memory location of the variable qNum and retrieve the value stored there. This requires that the CPU wait until the value is retrieved before completing the operation and thus might take slightly longer to complete than a similar operation using an immediate value.
When accessing arrays, a more generalized method is required. Specifically, an address can be placed in a register and indirection performed using the register (instead of the variable name).
For example, assuming the following declaration:
lst dd 101, 103, 105, 107
The decimal value of 101 is 0x00000065 in hex. The memory picture would be as follows:
Value |
Address |
Offset |
Index |
|
00 |
0x6000ef |
lst + 15 |
||
00 |
0x6000ee |
lst + 14 |
||
00 |
0x6000ed |
lst + 13 |
||
6b |
0x6000ec |
lst + 12 |
lst[3] |
|
00 |
0x6000eb |
lst + 11 |
||
00 |
0x6000ea |
lst + 10 |
||
00 |
0x6000e9 |
lst + 9 |
||
69 |
0x6000e8 |
lst + 8 |
lst[2] |
|
00 |
0x6000e7 |
lst + 7 |
||
00 |
0x6000e6 |
lst + 6 |
||
00 |
0x6000e5 |
lst + 5 |
||
67 |
0x6000e4 |
lst + 4 |
lst[1] |
|
00 |
0x6000e3 |
lst + 3 |
||
00 |
0x6000e2 |
lst + 2 |
||
00 |
0x6000e1 |
lst + 1 |
||
lst → |
65 |
0x6000e0 |
lst + 0 |
lst[0] |
The first element of the array could be accessed as follows:
mov eax, dword [1st]
Another way to access the first element is as follows:
mov rbx, list mov eax, dword [rbx]
In this example, the starting address, or base address, of the list is placed in rbx (first line) and then the value at that address is accessed and placed in the rax register (second line). This allows us to easily access other elements in the array.
Recall that memory is “byte addressable”, which means that each address is one byte of information. A double-word variable is 32-bits or 4 bytes so each array element uses 4 bytes of memory. As such, the next element (103) is the starting address (lst) plus 4, and the next element (105) is the starting address (lst) 8.
Increasing the offset by 4 for each successive element. A list of bytes would increase by 1, a list of words would increase by 2, a list of double-words would increase by 4, and a list of quadwords would increase by 8.
The offset is the amount added to the base address. The index is the array element number as used in a high-level language.
There are several ways to access the array elements. One is to use a base address and add a displacement. For example, given the initializations:
mov rbx, lst mov rsi, 8
Each of the following instructions access the third element (105 in the above list).
mov eax, dword [lst+8] mov eax, dword [rbx+8] mov eax, dword [rbx+rsi]
In each case, the starting address plus 8 was accessed and the value of 105 placed in the eax register. The displacement is added and the memory location accessed while none of the source operand registers (rbx, rsi) are altered. The specific method used is up to the programmer.
In addition, the displacement may be computed in more complex ways.
The general format of memory addressing is as follows:
[ baseAddr + (indexReg * scaleValue ) + displacement ]
Where baseAddr is a register or a variable name. The indexReg must be a register. The scaleValue is an immediate value of 1, 2, 4, 8 (1 is legal, but not useful). The displacement must be an immediate value. The total represents a 64-bit address.
Elements may be used in any combination, but must be legal and result in a valid address.
Some example of memory addressing for the source operand are as follows:
mov eax, dword [var1] mov rax, qword [rbx+rsi] mov ax, word [lst+4] mov bx, word [lst+rdx+2] mov rcx, qword [lst+(rsi*8)] mov al, byte [buff-1+rcx] mov eax, dword [rbx+(rsi*4)+16]
For example, to access the 3rd element of the previously defined double-word array (which is index 2 since index's start at 0):
mov rsi, 2 ; index=2 mov eax, dword [lst+rsi*4] ; get lst[2]
Since addresses are always qword (on a 64-bit architecture), a 64-bit register is used for the memory mode addressing (even when accessing double-word values). This allows a register to be used more like an array index (from a high-level language).
For example, the memory operand, [lst+rsi*4], is analogous to lst[rsi] from a high-level language. The rsi register is multiplied by the data size (4 in this example since each element is 4 bytes).