Microsoft PowerPoint – 22_X86_Assembly_Language_Part3
O
SU
C
SE
2
42
1
J.E.Jones
Required Reading: Computer Systems: A Programmer’s Perspective, 3rd
Edition Chapter 3, Section 3.5 through 3.5.4 (inclusive)
O
SU
C
SE
2
42
1
J. E. Jones
In-Class Labs Homework Mid-Term Final Final Grade
98.81% 102.67% 92.29% 58% 104% 88.25% (B+)
Have you been doing well on the assignment exercises?
Are you willing to work hard to successfully complete Assembler Labs? There will
be three of them.
How about Homework? Are you willing to spend the time on the Homework?
Can you put a slam-dunk on the final?
(I’ve seen it happen time and time again.)
Bottom line: You should ask yourself “Are you willing to put in the effort?” The student
above was willing, did and reaped the reward.
O
SU
C
SE
2
42
1
J. E. Jones
.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
have any read/write data on the heap)
.text
◦ Changes or sets the current section to the text (or code) section
(required)
O
SU
C
SE
2
42
1
J. E. Jones
.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.
O
SU
C
SE
2
42
1
J. E. Jones
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,
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
.string
◦ Specifies that the ASCII characters enclosed in quotation marks are to be stored
in memory, terminated by a null byte
O
SU
C
SE
2
42
1
J. E. Jones
.file “first.s”
.section .rodata
.data
.align 8
Orange:
.quad 0x6f
.quad 0x84
.globl main
.type main, @function
.text
int main(){
static long Orange[2]={0x6f, 0x84};
long *reg_rax = Orange;
long reg_rdx = 55, reg_rbx;
reg_rbx=reg_rax;
*reg_rax = %reg_rbx;
reg_rcx=*reg_rax;
}
main:
pushq %rbp
movq %rsp, %rbp
movq $55,%rdx
movq %rdx, %rbx
movq $Orange, %rax
movq %rbx, (%rax)
movq (%rax),%rcx
leave
ret
.size main, .-main
Don’t forget this! Program won’t run.
O
SU
C
SE
2
42
1
J. E. Jones
.file “first.s”
.section .rodata
.data
.align 4
Orange:
.long 0x6f
.long 0x84
.globl main
.type main, @function
.text
main:
pushq %rbp
movq %rsp, %rbp
movl $55,%edx
movl %edx, %ebx
movq $Orange, %rax
movl %ebx, (%rax)
movl (%rax),%ecx
leave
ret
.size main, .-main
O
SU
C
SE
2
42
1
J. E. Jones
.file “second.s”
.section .rodata
.data
.align 8
Orange:
.quad 0x6f
.quad 0x84
.quad 0x55
.quad 0x44
.globl main
.type main, @function
.text
main:0x600040
pushq %rbp
movq %rsp, %rbp
movq $55,%rdx
movq %rdx, %rbx
movq $0x33, %r8
movq $Orange, %rax
movq %rbx,8(%rax)
movq $3, %r9
movq %r8, 24(%rax)
movq %rax,(%rax)
movq (%rax),%rcx
leave
ret
.size main, .-main
O
SU
C
SE
2
42
1
J. E. Jones
Two Operand Instructions:
Format Computation
addX Src, Dest #Dest = Dest + Src
subX Src, Dest #Dest = Dest Src
imulX Src, Dest #Dest = Dest * Src signed multiply
salX Src, Dest #Dest = Dest << Src Also called shl
sarX Src, Dest #Dest = Dest >> Src Arithmetic (fills w/copy of sign bit)
shrX Src, Dest #Dest = Dest >> Src Logical (fills with 0s)
xorX Src, Dest #Dest = Dest ^ Src
andX Src, Dest #Dest = Dest & Src
orX Src, Dest #Dest = Dest | Src
Watch out for argument order
Replace X with the appropriate suffix for each of these instructions
based on Src/Dest size
The unsigned multiply (mulX) instruction is unique, and the divide
instruction is a completely different animal. We’ll look at them later.
O
SU
C
SE
2
42
1
J. E. Jones
Format Computation
addq %rax,%rcx # %rcx = %rax + %rcx 8-byte values
addl %eax, %ecx # %ecx = %eax + %ecx 4-byte values
subw %ax, %cx # %cx = %cx %ax 2-byte values
subb %al, %cl # %cl = %cl – %al 1-byte values
imulq %rax,%rcx # %rcx = %rcx * %rax 8-byte values
imull %eax, %ecx # %ecx = %ecx * %eax 4-byte values
sarw $3, %cx # %cx = %cx >> 3 2-byte values
andl 0x0f0f0f0f, %ecx # %ecx = %ecx & 0x0f0f0f0f 4-byte values
O
SU
C
SE
2
42
1
J. E. Jones
One Operand Instructions
incX Dest #Dest = Dest + 1
decX Dest #Dest = Dest 1
negX Dest #Dest = Dest
notX Dest #Dest = ~Dest
See book for more instructions (Figure 3.10)
Obviously, X must be replaced in each of these
instructions with the appropriate suffix based on the
Destination size
O
SU
C
SE
2
42
1
J. E. Jones
One Operand Instructions
incq %rax # %rax = %rax + 1
decl %eax # %eax = %eax 1
negw %ax # %ax = %ax
notb %al # %al = ~%al
O
SU
C
SE
2
42
1
J. E. Jones
long arith(long x, long y, long z)
{
long t1, t2, t3, t4, t5, rval;
t1 = x+y;
t2 = z+t1;
t3 = x+4;
t4 = y * 48;
t5 = t3 + t4;
rval = t2 * t5;
return rval;
}
arith:
leaq (%rdi,%rsi), %rax # t1 = x+y
addq %rdx, %rax # t2 = z + t1
leaq (%rsi,%rsi,2),%rdx # %rdx = 3y
salq $4, %rdx # %rdx * 16=48y=t4
leaq 4(%rdi,%rdx), %rcx # x + t4 + 4=t5
imulq %rcx, %rax # t2=t2*t5
ret
Register Use(s)
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax t1, t2, rval
%rdx t4
%rcx t5
Interesting Instructions
leaq: address computation
salq: shift arithmetic left
imulq: signed multiply
But, only used once
O
SU
C
SE
2
42
1
J. E. Jones
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.
O
SU
C
SE
2
42
1
J. E. Jones
Stack top address always held in
register %rsp
Stack grows towards lower addresses
Where is %rbp???
◦ That depends…
%rsp
•
•
•
Increasing
Addresses
Stack “Bottom”
Stack “Top”
O
SU
C
SE
2
42
1
J. E. Jones
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)
O
SU
C
SE
2
42
1
J. E. Jones
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
pushX
pushX
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.
O
SU
C
SE
2
42
1
J. E. Jones
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
pushX
pushX
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.
IMPORTANT: Use alternate push/pop values
at your peril.
O
SU
C
SE
2
42
1
J. E. Jones
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
popX
Examples
popw %ax – copy 2 bytes from stack into %ax and add 2 bytes to %rsp.
popq %rax – copy 8 bytes from stack into %rax and add 8 bytes to %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: popl and popb are not valid instructions in x86-64, although they are valid on
32-bit processors.
O
SU
C
SE
2
42
1
J. E. Jones
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.
O
SU
C
SE
2
42
1
J. E. Jones
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
O
SU
C
SE
2
42
1
J. E. Jones
call Dest
Dest is a label which has been placed in the assembly language
source code at the address of the function 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.
O
SU
C
SE
2
42
1
J. E. Jones
call Swap_it
instruction after call
…
Some stack value
Before executing the call
instruction
%rsp
%rbp
Lower
Addresses
Higher
Addresses
Address of
instruction after call
%rip
O
SU
C
SE
2
42
1
J. E. Jones
call Swap_it
instruction after call
…
Caller Ret Address
8-byte value
Some stack value
After executing the call
instruction
%rsp
%rbp
Lower
Addresses
Higher
Addresses
Address of Swap_it
%rip
O
SU
C
SE
2
42
1
J. E. Jones
Part 1:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of every program your
write 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 any program
you write.
O
SU
C
SE
2
42
1
J. E. Jones
Part 1:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of every program your write 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 any program you write.
If there is a leave instruction, why isn’t there an enter instruction?
O
SU
C
SE
2
42
1
J. E. Jones
Part 1:
pushq %rbp # Save caller’s base pointer
movq %rsp, %rbp # Set my base pointer
Put these two instructions at the beginning of every program your write 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 any program you write.
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
O
SU
C
SE
2
42
1
J. E. Jones
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
Caller’s %rbp
8-byte value
Caller Ret Address
8-byte value
After pushq %rbp :
%rsp
%rbp
Lower
Addresses
Higher
AddressesSome stack value
O
SU
C
SE
2
42
1
J. E. Jones
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
Caller’s %rbp
8-byte value
Caller Ret Address
8-byte value
After movq %rsp, %rbp:
%rsp
%rbp
Lower
Addresses
Higher
Addresses
O
SU
C
SE
2
42
1
J. E. Jones
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.
O
SU
C
SE
2
42
1
J. E. Jones
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
leave equivalent to:
movq %rbp,%rsp
popq %rbp
ret
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
When we are getting ready to finish up:
%rsp
%rbp
Lower
Addresses
Higher
Addresses
O
SU
C
SE
2
42
1
J. E. Jones
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
leave equivalent to:
movq %rbp,%rsp
popq %rbp
ret
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
%rsp
%rbp
Lower
Addresses
Higher
Addresses
O
SU
C
SE
2
42
1
J. E. Jones
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.
O
SU
C
SE
2
42
1
J. E. Jones
Swap_it:
pushq %rbp
movq %rsp, %rbp
…
leave equivalent to:
movq %rbp,%rsp
popq %rbp
ret
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
%rsp
%rbp
Lower
Addresses
Higher
Addresses
Caller Ret Address
8-byte value
%rip
O
SU
C
SE
2
42
1
J. E. Jones
call Swap_it
instruction after call
…
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
%rsp
%rbp
Lower
Addresses
Higher
Addresses
Some stack value