How To Get The Rax Register Into Variable
For a first expect at x64 assembly, nosotros modify the adder function from Chapter half-dozen to simplify its behavior. The modified function (adder2) is shown below:
#include <stdio.h> //adds two to an integer and returns the outcome int adder2(int a) { render a + two; } int chief(){ int 10 = 40; x = adder2(x); printf("10 is: %d\n", 10); render 0; } To compile this lawmaking, use the following command:
Next, let's view the respective assembly of this code past using the objdump command:
$ objdump -d adder > output $ less output
Search for the lawmaking snippet associated with adder2 by typing /adder2 while examining the file output using less. The section associated with adder2 should look similar to the following:
Assembly output for the adder2 part
0000000000400526 <adder2>: 400526: 55 push %rbp 400527: 48 89 e5 mov %rsp,%rbp 40052a: 89 7d fc mov %edi,-0x4(%rbp) 40052d: 8b 45 fc mov -0x4(%rbp),%eax 400530: 83 c0 02 add $0x2,%eax 400533: 5d pop %rbp 400534: c3 retq
Don't worry if you don't understand what's going on just nonetheless. Nosotros will cover assembly in greater particular in later sections. For now, let's study the structure of these individual instructions.
Each line in the preceding example contains an pedagogy's 64-scrap address in plan memory, the bytes corresponding to the instruction, and the plaintext representation of the instruction itself. For example, 55 is the automobile code representation of the instruction button %rbp, and the education occurs at address 0x400526 in programme memory. Note that 0x400526 is an abbreviation of the full 64-bit address associated with the button %rbp instruction; the leading zeroes are ignored for readability.
It is important to note that a single line of C code oftentimes translates to multiple instructions in assembly. The functioning a + 2 is represented past the ii instructions mov -0x4(%rbp), %eax and add $0x2, %eax.
| Your assembly may look dissimilar! If you are compiling your code along with us, you may find that some of your assembly examples look dissimilar from what is shown in this volume. The precise associates instructions that are output by whatever compiler depend on that compiler's version and the underlying operating system. Well-nigh of the assembly examples in this book were generated on systems running Ubuntu or Ruddy Hat Enterprise Linux (RHEL). In the examples that follow, we exercise non apply any optimization flags. For example, we compile any example file ( |
7.i.1. Registers
Recall that a register is a give-and-take-sized storage unit located directly on the CPU. There may be split registers for data, instructions, and addresses. For example, the Intel CPU has a total of 16 registers for storing 64-chip data:
%rax, %rbx, %rcx, %rdx, %rdi, %rsi, %rsp, %rbp, and %r8-%r15. All the registers salvage for %rsp and %rbp hold general-purpose 64-bit data. While a program may translate a register's contents as, say, an integer or an address, the annals itself makes no stardom. Programs can read from or write to all sixteen registers.
The registers %rsp and %rbp are known every bit the stack pointer and the frame pointer (or base pointer), respectively. The compiler reserves these registers for operations that maintain the layout of the program stack. For instance, register %rsp always points to the top of the stack. In earlier x86 systems (eastward.chiliad., IA32), the frame arrow commonly tracked the base of the agile stack frame and helped to reference parameters. However, the base arrow is less frequently used in x86-64 systems. Compilers typically store the first six parameters in registers %rdi, %rsi, %rdx, %rcx, %r8 and %r9, respectively. Annals %rax stores the return value from a function.
The last register worth mentioning is %rip or the didactics pointer, sometimes called the plan counter (PC). Information technology points to the side by side instruction to be executed by the CPU. Unlike the 16 registers mentioned previously, programs cannot write straight to register %rip.
vii.1.ii. Advanced Register Notation
Since x86-64 is an extension of the 32-bit x86 architecture (which itself was an extension of an earlier sixteen-bit version), the ISA provides mechanisms to access the lower 32 bits, 16 bits, and lower bytes of each register. Table 1 lists each of the 16 registers and the ISA notations to access their component bytes.
| 64-chip Register | 32-chip Register | Lower 16 Bits | Lower 8 Bits |
|---|---|---|---|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
The first eight registers (%rax, %rbx, %rcx, %rdx, %rdi, %rsi, %rsp, and %rbp) are 64-fleck extensions of 32-fleck registers in x86 and accept a common mechanism for accessing their lower 32 bits, lower xvi bits, and least-significant byte. To access the lower 32 bits of the first eight registers, simply replace the r in the register name with e. Thus, the register corresponding to the lower 32 bits of annals %rax is register %eax. To access the lower 16 bits of each of these eight registers, reference the last two letters of the register's name. So, the mechanism to admission the lower two bytes of register %rax is %ax.
Figure 1. The names that refer to subsets of register %rax.
The ISA provides a separate mechanism to access the viii-chip components within the lower xvi $.25 of the first four listed registers. Figure 1 depicts the access mechanisms for annals %rax. The college and lower bytes within the lower 16 bits of the outset four listed registers tin can exist accessed by taking the terminal ii letters of the register name and replacing the last letter with either an h (for higher) or an l (for lower) depending on which byte is desired. For example, %al references the lower eight-bits of register %ax, whereas %ah references the college eight-bits of register %ax. These viii-chip registers are commonly used for storing unmarried-byte values for certain operations, such equally bitwise shifts (a 32-bit register cannot be shifted more than than 32 places, and the number 32 requires merely a single byte of storage).
| Compiler may cull component registers depending on blazon When reading assembly code, keep in mind that the compiler typically uses the 64-fleck registers when dealing with 64-bit values (e.g., pointers or |
The last eight registers (%r8-%r15) were not part of the IA32 ISA. Notwithstanding, they likewise accept mechanisms to access their unlike byte components. To admission the lower 32 bits, 16 bits, or byte of the terminal eight registers, append the letter d, w, or b, respectively, to the end of the annals's name. Thus, %r9d accesses the lower 32 bits of register %r9, whereas %r9w accesses the lower xvi bits, and %r9b accesses the lowest byte of register %r9.
7.i.3. Instruction Structure
Each instruction consists of an operation code (or opcode) that specifies what it does, and one or more operands that tell the instruction how to do it. For instance, the teaching add together $0x2, %eax has the opcode add and the operands $0x2 and %eax.
Each operand corresponds to a source or destination location for a specific performance. Ii operand instructions typically follow the source, destination (S, D) format, where the first operand specifies a source register, and the second operand specifies the destination.
In that location are multiple types of operands:
-
Constant (literal) values are preceded by the
$sign. For example, in the instructionadd $0x2, %eax,$0x2is a literal value that corresponds to the hexadecimal value 0x2. -
Register forms refer to private registers. The education
mov %rsp, %rbpspecifies that the value in the source register (%rsp) should exist copied to the destination location (register%rbp). -
Retention forms correspond to some value inside main retentiveness (RAM) and are commonly used for address lookups. Retentivity address forms tin can contain a combination of registers and constant values. For example, in the instruction
mov -0x4(%rbp),%eax, the operand-0x4(%rbp)is an example of a retention form. Information technology loosely translates to "add -0x4 to the value in annals%rbp(i.e., subtract 0x4 from%rbp), and then perform a retention lookup." If this sounds similar a pointer dereference, that's because information technology is!
7.ane.4. An Example with Operands
The best style to explicate operands in item is to present a quick example. Suppose that retentiveness contains the following values:
| Address | Value |
|---|---|
| 0x804 | 0xCA |
| 0x808 | 0xFD |
| 0x80c | 0x12 |
| 0x810 | 0x1E |
Allow'southward also presume that the following registers contain the values shown:
| Annals | Value |
|---|---|
| %rax | 0x804 |
| %rbx | 0x10 |
| %rcx | 0x4 |
| %rdx | 0x1 |
And so the operands in Table 2 evaluate to the values shown at that place. Each row of the table matches an operand with its form (e.thousand., constant, annals, retentiveness), how it is translated, and its value. Notation that the notation K[x] in this context denotes the value at the retention location specified by address ten.
| Operand | Form | Translation | Value |
|---|---|---|---|
| %rcx | Register | %rcx | 0x4 |
| (%rax) | Retention | 1000[%rax] or M[0x804] | 0xCA |
| $0x808 | Constant | 0x808 | 0x808 |
| 0x808 | Memory | Thousand[0x808] | 0xFD |
| 0x8(%rax) | Memory | One thousand[%rax + 8] or M[0x80c] | 0x12 |
| (%rax, %rcx) | Memory | M[%rax + %rcx] or M[0x808] | 0xFD |
| 0x4(%rax, %rcx) | Memory | M[%rax + %rcx + 4] or M[0x80c] | 0x12 |
| 0x800(,%rdx,4) | Memory | M[0x800 + %rdx*iv] or M[0x804] | 0xCA |
| (%rax, %rdx, 8) | Memory | K[%rax + %rdx*viii] or M[0x80c] | 0x12 |
In Table 2, the notation %rcx indicates the value stored in register %rcx. In contrast, M[%rax] indicates that the value within %rax should be treated every bit an address, and to dereference (expect up) the value at that address. Therefore, the operand (%rax) corresponds to Thou[0x804] which corresponds to the value 0xCA.
A few important notes earlier continuing. Although Table two shows many valid operand forms, not all forms can be used interchangeably in all circumstances. Specifically:
-
Constant forms cannot serve as destination operands.
-
Memory forms cannot serve as both the source and destination operand in a unmarried instruction.
-
In cases of scaling operations (meet the last 2 operands in Tabular array two), the scaling gene is a third parameter in the parentheses. Scaling factors can be i of 1, two, 4, or 8.
Table two is provided equally a reference; withal, understanding primal operand forms will aid meliorate the reader'southward speed in parsing assembly language.
7.1.5. Instruction Suffixes
In several cases in upcoming examples, common and arithmetic instructions have a suffix that indicates the size (associated with the type) of the data existence operated on at the lawmaking level. The compiler automatically translates code to instructions with the appropriate suffix. Table 3 shows the common suffixes for x86-64 instructions.
| Suffix | C Type | Size (bytes) |
|---|---|---|
| b | | one |
| westward | | 2 |
| l | | iv |
| s | | iv |
| q | | 8 |
| d | | 8 |
Note that instructions involved with conditional execution have different suffixes based on the evaluated condition. We cover instructions associated with conditional execution in a afterward section.
How To Get The Rax Register Into Variable,
Source: https://diveintosystems.org/book/C7-x86_64/basics.html
Posted by: waddellconory.blogspot.com

0 Response to "How To Get The Rax Register Into Variable"
Post a Comment