What Is The Rsp Register
In the previous department, we traced through simple functions in assembly. In this section, we discuss the interaction between multiple functions in assembly in the context of a larger program. We too innovate some new instructions involved with function management.
Allow'southward begin with a refresher on how the phone call stack is managed. Recall that %rsp
is the stack pointer and always points to the meridian of the stack. The register %rbp
represents the base pointer (besides known equally the frame arrow) and points to the base of operations of the current stack frame. The stack frame (likewise known as the activation frame or the activation record) refers to the portion of the stack allocated to a single function call. The currently executing function is always at the peak of the stack, and its stack frame is referred to as the agile frame. The active frame is bounded by the stack pointer (at the tiptop of stack) and the frame pointer (at the bottom of the frame). The activation record typically holds local variables for a function.
Effigy 1 shows the stack frames for main
and a function information technology calls named fname
. We will refer to the principal
function as the caller role and fname
as the callee office.
In Figure i, the current active frame belongs to the callee office (fname
). The memory between the stack pointer and the frame pointer is used for local variables. The stack pointer moves equally local values are pushed and popped from the stack. In contrast, the frame pointer remains relatively abiding, pointing to the beginning (the lesser) of the current stack frame. As a result, compilers similar GCC unremarkably reference values on the stack relative to the frame pointer. In Figure 1, the active frame is divisional below by the base pointer of fname
, which is stack address 0x418. The value stored at address 0x418 is the "saved" %rbp
value (0x42c), which itself is an address that indicates the bottom of the activation frame for the main
part. The height of the activation frame of master
is divisional past the render address, which indicates where in the main
role program execution resumes once the callee function fname
finishes executing.
Tabular array 1 contains several boosted instructions that the compiler uses for basic function management.
For instance, the leaveq
instruction is a shorthand that the compiler uses to restore the stack and frame pointers as it prepares to get out a function. When the callee function finishes execution, leaveq
ensures that the frame pointer is restored to its previous value.
The callq
and retq
instructions play a prominent role in the procedure where ane function calls another. Both instructions modify the didactics arrow (register %rip
). When the caller function executes the callq
didactics, the electric current value of %rip
is saved on the stack to represent the render address, or the program address at which the caller resumes executing once the callee function finishes. The callq
instruction also replaces the value of %rip
with the address of the callee function.
The retq
instruction restores the value of %rip
to the value saved on the stack, ensuring that the program resumes execution at the program address specified in the caller role. Any value returned by the callee is stored in %rax
or one of its component registers (e.one thousand., %eax
). The retq
educational activity is usually the last pedagogy that executes in any function.
seven.five.i. Role Parameters
Different IA32, office parameters are typically preloaded into registers prior to a role call. Tabular array 2 lists the parameters to a function and the register (if whatsoever) that they are loaded into prior to a function telephone call.
Parameter | Location |
---|---|
Parameter 1 | %rdi |
Parameter 2 | %rsi |
Parameter iii | %rdx |
Parameter 4 | %rcx |
Parameter v | %r8 |
Parameter half-dozen | %r9 |
Parameter 7+ | on call stack |
The first six parameters to a function are loaded into registers %rdi
, %rsi
, %rdx
, %rcx
, %r8
, and %r9
, respectively. Any additional parameters are successively loaded into the call stack based on their size (4 byte offsets for 32-bit information, 8 byte offsets for 64-bit data).
seven.5.ii. Tracing Through an Example
Using our knowledge of role management, allow'due south trace through the code example showtime introduced at the beginning of this chapter. Note that the void
keyword is added to the parameter list of each function definition to specify that the functions have no arguments. This alter does not modify the output of the program; however, it does simplify the corresponding assembly.
#include <stdio.h> int assign(void) { int y = twoscore; render y; } int adder(void) { int a; return a + two; } int main(void) { int 10; assign(); x = adder(); printf("ten is: %d\n", x); return 0; }
We compile this code with the command gcc -o prog prog.c
and use objdump -d
to view the underlying associates. The latter control outputs a pretty big file that contains a lot of data that we don't demand. Utilize less
and the search functionality to extract the adder
, assign
, and main
functions:
0000000000400526 <assign>: 400526: 55 push %rbp 400527: 48 89 e5 mov %rsp,%rbp 40052a: c7 45 fc 28 00 00 00 movl $0x28,-0x4(%rbp) 400531: 8b 45 fc mov -0x4(%rbp),%eax 400534: 5d pop %rbp 400535: c3 retq 0000000000400536 <adder>: 400536: 55 push %rbp 400537: 48 89 e5 mov %rsp,%rbp 40053a: 8b 45 fc mov -0x4(%rbp),%eax 40053d: 83 c0 02 add $0x2,%eax 400540: 5d popular %rbp 400541: c3 retq 0000000000400542 <main>: 400542: 55 push %rbp 400543: 48 89 e5 mov %rsp,%rbp 400546: 48 83 ec 10 sub $0x10,%rsp 40054a: e8 e3 ff ff ff callq 400526 <assign> 40054f: e8 d2 ff ff ff callq 400536 <adder> 400554: 89 45 fc mov %eax,-0x4(%rbp) 400557: 8b 45 fc mov -0x4(%rbp),%eax 40055a: 89 c6 mov %eax,%esi 40055c: bf 04 06 40 00 mov $0x400604,%edi 400561: b8 00 00 00 00 mov $0x0,%eax 400566: e8 95 fe ff ff callq 400400 <printf@plt> 40056b: b8 00 00 00 00 mov $0x0,%eax 400570: c9 leaveq 400571: c3 retq
Each office begins with a symbolic label that corresponds to its declared proper name in the program. For example, <chief>:
is the symbolic characterization for the master
function. The address of a part label is as well the address of the first instruction in that function. To save infinite in the figures below, we truncate addresses to the lower 12 $.25. So, program address 0x400542 is shown as 0x542.
7.5.3. Tracing Through main
Figure 3 shows the execution stack immediately prior to the execution of primary
.
Figure three. The initial state of the CPU registers and call stack prior to executing the chief function
Recall that the stack grows toward lower addresses. In this instance, %rbp
initially is stack accost 0x830, and %rsp
initially is stack accost 0xd48. Both of these values are made up for this example.
Since the functions shown in the previous case utilize integer information, we highlight component registers %eax
and %edi
, which initially incorporate junk values. The red (upper-left) arrow indicates the currently executing didactics. Initially, %rip
contains address 0x542, which is the program memory address of the first line in the primary
part.
The first teaching saves the current value of %rbp
by pushing 0x830 onto the stack. Since the stack grows toward lower addresses, the stack pointer %rsp
is updated to 0xd40, which is 8 bytes less than 0xd48. %rip
advances to the adjacent teaching in sequence.
The next instruction (mov %rsp, %rbp
) updates the value of %rbp
to be the aforementioned as %rsp
. The frame pointer (%rbp
) now points to the showtime of the stack frame for the chief
office. %rip
advances to the next education in sequence.
The sub
education subtracts 0x10 from the accost of our stack arrow, which substantially causes the stack to "grow" by xvi bytes, which we represent by showing two 8-byte locations on the stack. Register %rsp
therefore has the new value of 0xd30. %rip
advances to the next instruction in sequence.
The callq <assign>
teaching pushes the value inside register %rip
(which denotes the address of the next instruction to execute) onto the stack. Since the next didactics afterwards callq <assign>
has an address of 0x55f, that value is pushed onto the stack as the return address. Recall that the return address indicates the plan accost where execution should resume when program execution returns to main
.
Adjacent, the callq
instruction moves the address of the assign
part (0x526) into annals %rip
, signifying that program execution should continue into the callee function assign
and non the next instruction in main
.
The first two instructions that execute in the assign
function are the usual book-keeping that every function performs. The first instruction pushes the value stored in %rbp
(retention address 0xd40) onto the stack. Remember that this address points to the starting time of the stack frame for principal
. %rip
advances to the second instruction in assign
.
The next pedagogy (mov %rsp, %rbp
) updates %rbp
to betoken to the top of the stack, marking the commencement of the stack frame for assign
. The instruction pointer (%rip
) advances to the next didactics in the assign
function.
The mov
instruction at address 0x52a moves the value $0x28
(or 40) onto the stack at address -0x4(%rbp)
, which is four bytes in a higher place the frame pointer. Think that the frame pointer is commonly used to reference locations on the stack. However, proceed in mind that this operation does not change the value of %rsp
— the stack pointer still points to address 0xd20. Annals %rip
advances to the next instruction in the assign
function.
The mov
educational activity at accost 0x531 places the value $0x28
into register %eax
, which holds the render value of the function. %rip
advances to the pop
instruction in the assign
function.
At this point, the assign
function has almost completed execution. The next instruction that executes is pop %rbp
, which restores %rbp
to its previous value, or 0xd40. Since the pop
instruction modifies the stack arrow, %rsp
updates to 0xd28.
The last instruction in assign
is a retq
instruction. When retq
executes, the return address is popped off the stack into register %rip
. In our example, %rip
now advances to signal to the callq
didactics in master
at address 0x55f.
Some important things to discover at this juncture:
-
The stack pointer and the frame arrow have been restored to their values prior to the call to
assign
, reflecting that the stack frame formain
is in one case again the active frame. -
The old values on the stack from the prior active stack frame are not removed. They notwithstanding be on the call stack.
Dorsum in main
, the call to adder
overwrites the old return address on the stack with a new render address (0x554). This return address points to the next instruction to be executed after adder
returns, or mov %eax, -0x4(%rbp)
. Register %rip
updates to point to the starting time educational activity to execute in adder
, which is at address 0x536.
The first instruction in the adder
function saves the caller's frame arrow (%rbp
of primary
) on the stack.
The next pedagogy updates %rbp
with the current value of %rsp
, or accost 0xd20. Together, these final two instructions plant the start of the stack frame for adder
.
Pay shut attending to the side by side instruction that executes. Call back that $0x28
was placed on the stack during the call to assign
. The mov $-0x4(%rbp), %eax
instruction moves an old value that is on the stack into register %eax
! This would not have occurred if the programmer had initialized variable a
in the adder
function.
The add
instruction at address 0x53d adds 2 to register %eax
. Think that when a 32-bit integer is being returned, x86-64 utilizes component annals %eax
instead of %rax
. Together the final two instructions are equivalent to the post-obit lawmaking in adder
:
Later on pop
executes, the frame pointer over again points to the kickoff of the stack frame for primary
, or accost 0xd40. The stack pointer now contains the address 0xd28.
The execution of retq
pops the return address off the stack, restoring the teaching pointer dorsum to 0x554, or the address of the adjacent instruction to execute in chief
. The address contained in %rsp
is now 0xd30.
Back in main
, the mov %eax, -0x4(%rbp)
educational activity places the value in %eax
at a location four bytes above %rbp
, or at address 0xd3c. The next instruction replaces it back into register %eax
.
Skipping ahead a picayune, the mov
instruction at accost 0x55a copies the value in %eax
(or 0x2A) to register %esi
, which is the 32-bit component register associated with %rsi
and typically stores the second parameter to a function.
The next didactics (mov $0x400604, %edi
) copies a abiding value (an address in code segment memory) to annals %edi
. Recall that register %edi
is the 32-fleck component register of %rdi
, which typically stores the start parameter to a function. The code segment memory address 0x400604 is the base accost of the string "x is %d\northward"
.
The next instruction resets annals %eax
with the value 0. The instruction pointer advances to the telephone call to the printf
office (which is denoted with the label <printf@plt>
).
The side by side instruction calls the printf
function. For the sake of brevity, we will not trace the printf
part, which is part of stdio.h
. However, we know from the transmission page (man -s3 printf
) that printf
has the following format:
int printf(const char * format, ...)
In other words, the start argument is a arrow to a string specifying the format, and the 2nd argument onward specify the values that are used in that format. The instructions specified by addresses 0x55a - 0x566 stand for to the following line in the main
function:
When the printf
function is chosen:
-
A return address specifying the instruction that executes afterwards the call to
printf
is pushed onto the stack. -
The value of
%rbp
is pushed onto the stack, and%rbp
is updated to indicate to the top of the stack, indicating the offset of the stack frame forprintf
.
At some bespeak, printf
references its arguments, which are the cord "x is %d\n"
and the value 0x2A. The first parameter is stored in component annals %edi
, and the second parameter is stored in component register %esi
. The return address is located directly below %rbp
at location %rbp+eight
.
For any part with n arguments, GCC places the first 6 arguments in registers, equally shown in Tabular array ii, and the remaining arguments onto the stack below the return address.
Later on the call to printf
, the value 0x2A is output to the user in integer format. Thus, the value 42 is printed to the screen!
Afterwards the call to printf
, the last few instructions make clean up the stack and prepare a clean exit from the main
function. First, the mov
instruction at address 0x56b ensures that 0 is in the render register (since the terminal matter master
does is render 0).
The leaveq
teaching prepares the stack for returning from the role telephone call. Remember that leaveq
is coordinating to the following pair of instructions:
In other words, the CPU overwrites the stack pointer with the frame pointer. In our case, the stack arrow is initially updated from 0xd30 to 0xd40. Side by side, the CPU executes popular %rbp
, which takes the value located at 0xd40 (in our example, the address 0x830) and places information technology in %rbp
. Afterwards leaveq
executes, the stack and frame pointers revert to their original values prior to the execution of main
.
The last instruction that executes is retq
. With 0x0 in the return register %eax
, the programme returns zip, indicating correct termination.
If y'all have advisedly read through this section, you should understand why our plan prints out the value 42. In essence, the program inadvertently uses former values on the stack to cause it to behave in a fashion that we didn't await. This example was pretty harmless; all the same, we discuss in future sections how hackers have misused function calls to make programs misbehave in truly malicious ways.
What Is The Rsp Register,
Source: https://diveintosystems.org/book/C7-x86_64/functions.html
Posted by: macdonaldwheng1940.blogspot.com
0 Response to "What Is The Rsp Register"
Post a Comment