Essentials of 80x86 Assembly Language

Download Report

Transcript Essentials of 80x86 Assembly Language

Chapter 6
Procedures
6.1 The 80x86 Stack
Hardware Stack
• Allocated with directive, for example
.STACK 4096
allocates 4096 uninitialized memory bytes
– Visual Studio project setting can also be used
to allocate stack space
• Most access is indirect, through the stack
point register ESP
– Operating system initializes ESP to point to
byte above stack
– As program executes, it points to the last item
pushed on the stack
push instruction
• Usual format: push source
– source can in memory, register or immediate
– doubleword or word pushed on the stack
• Formats to use when the assembler
cannot determine operand size
– pushd source
– pushw source
push execution
• ESP decremented by size of operand
• Operand stored in stack where ESP points
after being decremented
• Flags not changed
push Example
pop instruction and execution
• Usual format: pop destination
– doubleword or word destination can in
memory or register
• Operand stored in stack where ESP points
is copied to destination
• ESP incremented by size of operand after
the value is copied
• Flags not changed
pop Example
Pushing/Popping Flags
• pushfd pushes EFLAGS register
contents onto stack
• popfd pops doubleword from top of stack
into EFLAGS
Viewing the Stack with Debugger
• Stop at breakpoint
• View registers
– ESP contains address of byte above stack
• Subtract number of bytes to view from the
address in ESP
• Use this as the starting address at which to view
memory
• Example – if ESP contains 0042FFC4, using
0042FFC4 – 20 = 0042FFA4 lets you see the
top 32 (2016) bytes of the stack
6.2 32-bit Procedures with
Value Parameters
Terminology
• Procedure - a subprogram that is
essentially a self-contained unit
• Main program or another subprogram calls
a procedure
• A procedure may simply do a task or it
may return a value
– value-returning procedure is sometimes called
a function
Procedure Concepts
• Transfer of control from calling program to
procedure and back
• Passing parameter values to procedure
and results back from the procedure
• Having procedure code that is
independent of the calling program
The cdecl protocol provides one standard
implementation scheme
Procedure Definition
• In a code segment with body statements
bracketed by PROC and ENDP directives
giving procedure name
.CODE
procName PROC
; procedure body
...
procName ENDP
Transferring Control to a Procedure
• In the “main” program, use
call procName
• The next instruction executed will be the
first one in the procedure
Returning from a Procedure
• In the procedure, use
ret
• The next instruction executed will be the
one following the call in the “main”
program
How call Works
• The address of the instruction following
the call is pushed on the stack
• The instruction pointer register EIP is
loaded with the address of the first
instruction in the procedure
How ret Works
• The doubleword on the top of the stack is
popped into the instruction pointer register
EIP
• Assuming that this was the address of the
instruction following the call, that
instruction will be executed next
• If the stack has been used for other values
after the call, these must be removed
before the ret instruction is executed
Alternative ret Format
• ret n
• n is added to ESP after the return address
is popped
• This is most often used to logically remove
procedure parameters that have been
pushed onto the stack
– Not used in cdecl protocol
Parameter Terminology
• A procedure definition often includes
parameters (also called formal parameters)
• These are associated with arguments (also
called actual parameters) when the
procedure is called
• For a procedure's in (pass-by-value)
parameters, values of the arguments are
copied to the parameters when the
procedure is called
– These values are referenced in the procedure
using their local names (the identifiers used to
define the parameters)
Implementing Value Parameters
• Parameter values normally passed on the stack
– Pushed in reverse order from argument list
• Example
– Design or high-level code: sum := add2(value1, value2)
– 80x86 implementation:
push
push
call
add
mov
ecx
value1
add2
esp, 8
sum, eax
;
;
;
;
;
assuming value2 in ECX
assuming value1 in memory
call procedure to find sum
remove parameters from stack
sum in memory
• With the cdecl protocol the calling program must
remove parameters from the stack
• A single integer value normally returned in EAX
Procedure Entry Code
• Since the stack pointer ESP may change, a
procedure starts with entry code to set the base
pointer EBP to an address in the stack
– This location is fixed until exit code restores EBP right
before returning
• In the procedure body, parameters are located
relative to EBP
• Entry code also saves contents of registers that
are used locally within the procedure body
– Exit code restores these registers
Example Procedure
add2
PROC
add2
push
mov
mov
add
pop
ret
ENDP
; add two words passed on the stack
; return the sum in the EAX register
ebp
; save EBP
ebp,esp
; establish stack frame
eax,[ebp+8]
; copy first parameter value
eax,[ebp+12]
; add second parameter value
ebp
; restore EBP
; return
parameter 2
parameter 2
parameter 1
return address
addresses
ESP,EBP 
stack upon procedure entry
old value of EBP
ESP 
increasing
return address
parameter 1

after EBP established
Stack frame
upon entry to
procedure add2
and after EBP
established in
entry code
Accessing Parameters in a Procedure
• Use based addressing
• Since the value is actually on the stack,
[EBP+n] references the value
• Example:
mov eax,[ebp+8]
copies the last parameter pushed to EAX
Saving/Restoring Registers
• Push registers in entry code after EBP is
established
• Exit code pops registers in the opposite
order
• Calling program’s flag values from can be
saved with pushfd/popfd
Entry and Exit Code Summary
• Entry code:
push
mov
push
...
push
pushfd
ebp
ebp, esp
...
; establish stack frame
; save registers
...
; save flags
• Exit code:
popfd
pop
...
pop
pop
ret
...
...
ebp
; restore flags
; restore registers
; restore EBP
; return
Procedure Call Summary
calling program code


procedure code
push arguments on stack in right-to-left order
call procedure








add number of bytes of parameters to ESP
for value-returning procedure, use value in EAX
save EBP and establish stack frame
save registers used by procedure
access parameter values using based
addressing in procedure body
return value, if any, goes in EAX
restore saved registers and EBP
return
6.3 Additional 32-bit
Procedure Options
Reference Parameters
• The address of the argument instead of its
value is passed to the procedure
• Reference parameters are used:
– To send a large argument (for example, an
array or a structure) to a procedure
– To send results back to the calling program as
argument values
Passing an Address
• lea instruction can put address of an
argument in a register, and then the
contents can be pushed on the stack
lea eax, minimum ; 3rd parameter
push eax
Returning a Value in a Parameter
• Get address from stack
• Use register indirect addressing
mov
...
mov
ebx, [ebp+16] ; get addr of min
[ebx], eax
; min := a[i]
Allocating Local Variable Space
•
•
•
•
•
•
•
•
•
save EBP and establish stack frame
subtract number of bytes of local space from ESP
save registers used by procedure
Access both parameters and local variables in
procedure body using based addressing
return value, if any, goes in EAX
restore saved registers
New entry and exit
copy EBP to ESP
code actions are bold
restore EBP
return
Recursive Procedure
• Calls itself, directly or indirectly
• Many algorithms are very difficult to
implement without recursion
• A recursive call is coded just like any other
procedure call
Separate Assembly
• Procedure code can be in a separate file
from the calling program
• File with call has an EXTERN directive to
describe procedure that is defined in
another file
• Example
EXTERN minMax:PROC
64-bit procedures
Stack Usage
• Normally push and pop quadwords
• call pushes a 64-bit address on the
stack
• ret pops a 64-bit address into RIP
• Calling procedure’s entry code must
reserve space on the stack for arguments.
– Typical code includes sub rsp,120
64-bit protocol
• Different from cdecl
• First four arguments passed in registers
Argument
1
2
3
4
Register
RCX
RDX
R8
R9
• Later arguments copied to stack
• Fifth argument is copied to [RSP+32]
Register Usage
• RAX, RCX, RDX, and R8-R11 are called
volatile
– A called procedure is free to change them
• RBX, RDI, RSI, RBP, RSP and R12-R15
are called nonvolatile
– A called procedure has the responsibility of
preserving them
• In practice, it is safest to preserve any
register that you don’t want destroyed by a
called procedure
Procedure to Add Five Integers
; void add5(int x1,int x2,int x3,int x4,int x5);
; returns sum of arguments
add5
PROC
mov eax, ecx
; x1
add eax, edx
; x2
add eax, r8d
; x3
add eax, r9d
; x4
add eax, DWORD PTR [rsp+40]
; x5
ret
; return
add5
ENDP
6.5 Macro Definition and
Expansion
Macro
• Expands to the statements it represents
– Expansion then assembled
• Resembles a procedure call, but is
different
– Each time a macro appears in code, it is
expanded
– There is only one copy of procedure code
Macro Definition
name
MACRO list of parameters
assembly language statements
ENDM
• Parameters in the MACRO directive are
ordinary symbols, separated by commas
• The assembly language statements may
use the parameters as well as registers,
immediate operands, or symbols defined
outside the macro
Macro Example 1
Given the definition
add2
MACRO nbr1, nbr2
; put sum of two doubleword parameters in EAX
mov eax, nbr1
add eax, nbr2
ENDM
the macro call
add2 value, 30
; value + 30
expands to
; put sum of two doubleword parameters in EAX
mov eax, value
add eax, 30
Macro Example 2
Given the definition
add2
MACRO nbr1, nbr2
; put sum of two doubleword parameters in EAX
mov eax, nbr1
add eax, nbr2
ENDM
the macro call
add2 eax, ebx
; sum of two values
expands to
; put sum of two doubleword parameters in EAX
mov eax, eax
add eax, ebx
Macro Example 3
Given the definition
add2
MACRO nbr1, nbr2
; put sum of two doubleword parameters in EAX
mov eax, nbr1
add eax, nbr2
ENDM
the macro call
add2 value
expands to
; put sum of two doubleword parameters in EAX
mov eax, value
add
eax,
(won’t assemble)
Macros in IO.H
• Each expands to a statement that calls a
procedure, for example
atod
MACRO
lea
push
call
add
ENDM
source
;
;
eax,source ;
eax
;
atodproc
;
esp, 4
;
convert ASCII string
to integer in EAX
source address to AX
source parameter on stack
call atodproc(source)
remove parameter