OSU CSE 2421
Required Reading: Computer Systems: A Programmer’s Perspective, 3rd Edition Chapter 3, Section 3.5 through 3.5.4 (inclusive)
J.E.Jones
OSU CSE 2421
.file
◦ Allows a name to be assigned to the assembly language source code file.
(optional, but a really good idea)
.section
◦ This makes the specified section the current section. (required)
.rodata
◦ Specifies that the following data is to be placed in the read only memory portion of the executable (required, if you have any read-only data)
.data
◦ Changes or sets the current section to the data section (required, if you
.text
have any read/write data on the heap)
◦ Changes or sets the current section to the text (or code) section (required)
J. E. Jones
OSU CSE 2421
.globl
◦ A directive needed by the linker for symbol resolution: followed by
name of function (required)
.type
◦ Needed by the linker to identify the label as one associated with a
function, as opposed to data (required)
.size
◦ Needed by the linker to identify the size of the text for the program
(required)
.align alignment_value
◦ Needed if we want to declare values on the heap to start at an address that has a particular byte alignment. alignment_value is 1, 2, 4 or 8. (optional, but almost always used)
Note: labels (for functions or data) in assembly language source code are followed by a colon.
J. E. Jones
OSU CSE 2421
What if I want to “declare” static class variables??? In the .data or .rodata section of your program use: .quad value
◦ Places the given value, (0x prefix for hex, no prefix for decimal) in memory, encoded in 8 bytes
.long value
◦ Places the given value, (0x prefix for hex, no prefix for decimal) in memory,
.string
encoded in 4 bytes
.word value
◦ Places the given value, (0x prefix for hex, no prefix for decimal) in memory,
encoded in 2 bytes
.byte value
◦ Places the given value, (0x prefix for hex, no prefix for decimal) in memory,
encoded in 1 byte
◦ Specifies that the ASCII characters enclosed in quotation marks are to be stored in memory, terminated by a null byte
J. E. Jones
OSU CSE 2421
.file “first.s” .section .rodata .data
.align 8
main:
pushq %rbp
movq %rsp, %rbp
Array: .quad 0x6f .quad 0x84 .globl main
movq $55,%rdx movq %rdx, %rbx movq $Array, %rax movq %rbx, 8(%rax) movq (%rax),%rcx
.type main, @function .text
leave
ret
.size main, .-main
{
static long Array[2]={0x6f, 0x84}; long *p = Array;
long reg_rax = 55, reg_rcx; reg_rcx=reg_rax;
*(p+1)=reg_rax;
reg_rcx = *Array; /* or Array[0]; */ }
Don’t forget this! Program won’t run.
J. E. Jones
OSU CSE 2421
.file “second.s” .section .rodata .data
.align 8
main:
pushq %rbp
movq %rsp, %rbp
Array: .quad 0x6f .quad 0x84 .quad 0x55 .quad 0x44 .globl main
movq $55,%rdx movq %rdx, %rbx movq $0x33, %r8 movq $Array, %rax movq %rbx,8(%rax) movq %r8, 24(%rax) movq %rax,(%rax) movq (%rax),%rcx
.type main, @function .text
leave
ret
.size main, .-main
J. E. Jones
OSU CSE 2421
Two Operand Instructions:
Format
Computation
add Src,Dest sub Src,Dest imul Src,Dest sal Src,Dest sar Src,Dest shr Src,Dest xor Src,Dest and Src,Dest or Src,Dest
#Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest #Dest = Dest
+ Src
Src
* Src signed multiply
<< Src Also called shl
>> Src Arithmetic (fills w/copy of sign bit) >> Src Logical (fills with 0s)
^ Src
& Src
| Src
Watch out for argument order!
Don’t forget to include a suffix for each of these instructions.
The unsigned multiply (mulX) instruction is unique, and the divide instruction is a completely different animal. We’ll look at them later.
J. E. Jones
OSU CSE 2421
Format
Computation
addq %rax,%rcx addl %eax, %ecx
# %rcx = %rax + %rcx # %ecx = %eax + %ecx
subw %ax, %cx subb %al, %cl
# %cx = %cx %ax # %cl = %cl – %al
imulq %rax,%rcx imull %eax, %ecx
# %rcx = %rcx * %rax # %ecx = %ecx * %eax
sarw$3,%cx
andl 0x0f0f0f0f, %ecx
#%cx =%cx>>3
# %ecx = %ecx & 0x0f0f0f0f
J. E. Jones
OSU CSE 2421
One Operand Instructions
inc Dest dec Dest neg Dest not Dest
#Dest = Dest + 1 #Dest = Dest 1 #Dest = Dest #Dest = ~Dest
See book for more instructions (Figure 3.10)
Obviously, each of these instructions must use the appropriate suffix based on the Destination size
J. E. Jones
OSU CSE 2421
One Operand Instructions
incq %rax decl %eax negw %ax notb %al
# %rax = %rax + 1 # %eax = %eax 1 # %ax = %ax
# %al = ~%al
J. E. Jones
OSU CSE 2421
long arith(long x, long y, long z)
{ arith:
long t1, t2, t3, t4, t5, rval; t1 = x+y;
t2 = z+t1;
t3 = x+4;
leaq (%rdi,%rsi), %rax addq %rdx,%rax
leaq (%rsi,%rsi,2),%rdx salq $4, %rdx
# t1 = x+y #t2=z+t1
# %rdx = 3y
# %rdx * 16=48y=t4 # x + t4 + 4=t5
# t2=t2*t5
}
%rdi %rsi %rdx %rax %rdx %rcx
Argument x Argument y Argument z t1, t2, rval t4
t4 = y * 48; t5 = t3 + t4; rval = t2 * t5; return rval;
leaq 4(%rdi,%rdx), %rcx imulq %rcx, %rax
ret
Interesting Instructions
leaq: address computation salq: shift arithmetic left imulq: signed multiply
But, only used once
t5
Register
Use(s)
J. E. Jones
OSU CSE 2421
The program stack is divided conceptually into frames.
Each procedure or function (main and any functions called from main or from another function) has its own part of the stack to use, which is called its stack frame.
The stack frame goes from the stack address pointed to by %rbp in that procedure(this is called the frame (or base) pointer) to %rsp, which points to the top of the stack while the procedure is running.
This implies that the address pointed to by %rbp is different in different procedures: %rbp must be set when the procedure is entered.
J. E. Jones
OSU CSE 2421
Stack top address always held in register %rsp
Stack “Top”
%rsp
Stack grows towards lower addresses
•
Increasing Addresses
Where is %rbp??? ◦ That depends…
• •
Stack “Bottom”
J. E. Jones
OSU CSE 2421
Save the caller’s %rbp (frame pointer) before setting our own frame pointer;
Before calling another function, to preserve values needed (use push/pop);
To pass parameters to another function (only if there are more than 6 parameters to pass);
To store the return address when a call instruction is executed (call/ret instructions do this);
If we need more temp data than available registers, (i.e., automatic, block scope variables)
J. E. Jones
OSU CSE 2421
pushX source, where X is the suffix q or the suffix w
What it does:
◦ Decrement %rsp by number of bytes specified by opcode suffix and write bytes (of size specified by opcode suffix), to memory address in %rsp. This puts the value on top of the stack
Note: Because operands of different sizes can be pushed, the number of bytes which is subtracted from the stack pointer depends on the operand size suffix. Since %rbp and %rsp contain stack addresses, they are always referenced as an 8-byte value.
Syntax
pushX
# we can push the value of a register (must match size of suffix) # we can push a value from memory to the stack
# we can push a constant to the stack
Examples
pushq %rax – subtract 8 bytes from the value in %rsp, and then copy the value in
%rax onto the stack at the address pointed to by %rsp.
pushw %ax – subtract 2 bytes from the value in %rsp, and then copy the value in %ax
onto the stack at the address pointed to by %rsp.
To avoid data alignment calculations/confusion with respect to the stack, we will only be pushing/popping 8-byte values for this class.
Note: pushl and pushb are not valid instructions in x86-64, although they are valid on 32-bit processors.
J. E. Jones
OSU CSE 2421
pushX source, where X is the suffix q or the suffix w
What it does:
◦ Decrement %rsp by number of bytes specified by opcode suffix and write bytes (of size specified by opcode suffix), to memory address in %rsp. This puts the value on top of the stack
Note: Because operands of different sizes can be pushed, the number of bytes which is subtracted from the stack pointer depends on the operand size suffix. Since %rbp and %rsp contain stack addresses, they are always referenced as an 8-byte value.
Syntax
pushX
# we can push the value of a register (must match size of suffix) # we can push a value from memory to the stack
# we can push a constant to the stack
Examples
pushq %rax – subtract 8 bytes from the value in %rsp, and then copy the value in
%rax onto the stack at the address pointed to by %rsp.
pushw %ax – subtract 2 bytes from the value in %rsp, and then copy the value in %ax
onto the stack at the address pointed to by %rsp.
To avoid data alignment calculations/confusion with respect to the stack, we will only be pushing/popping 8-byte values for this class.
IMPORTANT: Use alternate push/pop values at your peril.
Note: pushl and pushb are not valid instructions in x86-64, although they are valid on 32-bit processors.
J. E. Jones
OSU CSE 2421
popX destination, where X is the suffix q or the suffix w
Read the number of bytes specified by the suffix from the address in %rsp and store it in destination; increment %rsp by number of bytes specified by opcode suffix so that %rsp now points to the next value on the stack.
Syntax
popX
Examples popw %ax
– copy 2 bytes from stack into %ax and add 2 bytes to %rsp. – copy 8 bytes from stack into %rax and add 8 bytes to %rsp.
popq %rax
To avoid data alignment calculations/confusion with respect to the stack, we will
only be pushing/popping 8-byte values for this class.
Note: popl and popb are not valid instructions in x86-64, although they are valid on 32-bit processors.
J. E. Jones
OSU CSE 2421
To use function calls and returns in our X86 program, we must manage the program stack and program registers correctly.
Two different aspects to this:
◦ Maintain the stack pointer, frame pointer and associated data in relation to each function call and return. (The OS initializes these values upon system start.)
◦ Place appropriate values in “some” registers as expected by a calling or caller program. More on this later.
J. E. Jones
OSU CSE 2421
The initial value for the register %rsp is assigned by the OS during initial boot of the system. This sets up the system stack.
In X86 programs, we must set up the stack frame in our assembly language source code.
There are three things to do: ◦ At the start of a function:
1. Set %rbp to point to the bottom of the current stack frame.
2. Set %rsp to point to the current top of the stack (the same address as
the stack bottom initially). ◦ At the end of a function:
3. Put them back
J. E. Jones
OSU CSE 2421
call Dest
Dest is a label which has been placed in the assembly language
source code at the address of the procedure to be called. call instruction does 2 things:
1. the address of the instruction immediately after the call instruction is pushed onto the stack (that is, the return address is pushed), and
2. the Dest (remember it’s an address) is assigned to the PC (%rip) register.
This means that, when the called function begins execution, the return address to the calling function is the last thing that has been pushed onto the stack.
J. E. Jones
OSU CSE 2421
call Swap_it
instruction after call
…
Before executing the call instruction
%rsp %rbp
Some stack value
Higher Addresses
Lower Addresses
%rip
Address of instruction after call
J. E. Jones
OSU CSE 2421
call Swap_it
instruction after call
…
After executing the call instruction
%rsp %rbp
Caller Ret Address 8-byte value
Some stack value
Higher Addresses
Lower Addresses
%rip Address of Swap_it
J. E. Jones
OSU CSE 2421
Part 1:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of your program before any other statements!
* Notice that, since %rbp equals %rsp, the stack frame is empty. * We are now ready to use the stack!
Part 2:
leave # set caller’s stack frame back up
Put this statement directly before the ret instruction of your program.
J. E. Jones
OSU CSE 2421
Part 1:
Part 2:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of your program before any other statements!
* Notice that, since %rbp equals %rsp, the stack frame is empty. * We are now ready to use the stack!
leave # set caller’s stack frame back up Put this statement directly before the ret instruction of your program.
If there is a leave instruction, why isn’t there an enter instruction?
J. E. Jones
OSU CSE 2421
Part 1:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of your program before any other statements!
* Notice that, since %rbp equals %rsp, the stack frame is empty. * We are now ready to use the stack!
Part 2:
leave # set caller’s stack frame back up Put this statement directly before the ret instruction of your program.
If there is a leave instruction, why isn’t there an enter instruction?
There is, but it has been measured for speed and is sorely lacking. leave instruction is fast. https://stackoverflow.com/questions/5959890/enter-vs-push-ebp-mov-ebp-esp-sub- esp-imm-and-leave-vs-mov-esp-ebp
https://stackoverflow.com/questions/5959890/enter-vs-push-ebp-mov-ebp-esp-sub- esp-imm-and-leave-vs-mov-esp-ebp
J. E. Jones
OSU CSE 2421
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
After pushq %rbp : %rsp
Caller’s %rbp 8-byte value
%rbp
Caller Ret Address 8-byte value
Some stack value
Higher Addresses
J. E. Jones
Lower Addresses
OSU CSE 2421
Swap_it:
Lower Addresses
pushq %rbp
movq %rsp, %rbp
…
After movq %rsp, %rbp: %rsp
%rbp Caller Ret Address 8-byte value
Higher Addresses
Caller’s %rbp 8-byte value
J. E. Jones
OSU CSE 2421
leave
Sets stack pointer to the base frame address
Pops what is at top of stack into %rbp (this adds 8 bytes to %rsp)
Prepares the stack for return instruction
Syntax
leave
leave – equivalent to: movq %rbp, %rsp
popq %rbp
Don’t use both leave and movq/popq in same program ◦ nasty result.
J. E. Jones
OSU CSE 2421
Swap_it:
Lower Addresses
pushq %rbp
movq %rsp, %rbp …
leave
equivalent to:
ret
movq %rbp,%rsp
popq %rbp
When we are getting ready to finish up: %rsp
Value used by Swap_it
%rbp
Caller Ret Address 8-byte value
Higher Addresses
Value used by Swap_it
Value used by Swap_it
Caller’s %rbp 8-byte value
J. E. Jones
OSU CSE 2421
Swap_it:
Lower Addresses
pushq %rbp
movq %rsp, %rbp …
leave
equivalent to:
ret
movq %rbp,%rsp
popq %rbp
%rsp %rbp
Value used by Swap_it
Value used by Swap_it
Value used by Swap_it
Caller’s %rbp 8-byte value
Caller Ret Address 8-byte value
Higher Addresses
J. E. Jones
OSU CSE 2421
ret
The ret instruction does 2 things:
1. the address of the instruction immediately after the call instruction that got us here is popped from the stack, and
2. that address is assigned to the PC (%rip) register.
J. E. Jones
OSU CSE 2421
Swap_it:
Lower Addresses
pushq %rbp
movq %rsp, %rbp …
leave
equivalent to:
ret
Caller Ret Address 8-byte value
movq %rbp,%rsp popq %rbp
%rip
%rsp %rbp
Value used by Swap_it
Value used by Swap_it
Value used by Swap_it
Caller’s %rbp 8-byte value
Caller Ret Address 8-byte value
Higher Addresses
J. E. Jones
OSU CSE 2421
call Swap_it
instruction after call …
%rsp %rbp
Caller’s %rbp 8-byte value
Value used by Swap_it
Value used by Swap_it
Value used by Swap_it
Caller Ret Address 8-byte value
Higher Addresses
Some stack value
Lower Addresses
J. E. Jones