Download What is a Stack?

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Dezvoltarea de programe în asamblare
Procedures and the Stack
De citit:
Capitole 5, 16, 10, 17
Chapter 5
S. Dandamudi
Modificat: 25 November 2016
Capitolul 7
1
Capitolul 7
2
What is a Stack?
Outline
• What is stack?
• Pentium implementation
of stack
• Stack instructions
• Uses of stack
• Procedures
∗ Pentium instructions
• Parameter passing
∗ Register method
∗ Stack method
• Stack is a last-in-first-out (LIFO) data structure
• If we view the stack as a linear array of elements,
both insertion and deletion operations are
restricted to one end of the array
• Only the element at the top-of-stack (TOS) is directly
accessible
• Two basic stack operations:
• Examples
∗ Call-by-value
∗ Call-by-reference
∗ Bubble sort
• Procedures with variable
number of parameters
• Local variables
• Multiple source program
modules
• Performance: Procedure
overheads
Capitolul 7
∗ push (insertion)
∗ pop (deletion)
3
Capitolul 7
4
What is a Stack? (cont’d)
What is a Stack? (cont’d)
• Example
• Example
∗ Insertion of data items into the stack
∗ Deletion of data items from the stack
» Arrow points to the top-of-stack
» Arrow points to the top-of-stack
Capitolul 7
5
Capitolul 7
6
1
Pentium Implementation of the Stack
Pentium Stack Instructions
• Stack segment is used to implement the stack
• Pentium provides two basic instructions:
push
pop
∗ Registers SS and ESP are used
∗ SS:ESP represents the top-of-stack
• source and destination can be a
• Pentium stack implementation characteristics are:
∗ Only words (i.e., 16-bit data) or doublewords (i.e., 32-bit
data) are saved on the stack, never a single byte
∗ Stack grows toward lower memory addresses (i.e., stack
grows “downward”)
∗ Top-of-stack (TOS) always points to the last data item
placed on the stack
Capitolul 7
source
destination
∗ 16- or 32-bit general register
∗ a segment register
∗ a word or doubleword in memory
• source of push can also be an immediate operand
of size 8, 16, or 32 bits
7
Pentium Stack Example - 1
Capitolul 7
8
Pentium Stack Instructions: Examples
• On an empty stack, the following sequence of push
instructions
push
21ABH
push
7FBD329AH
results in the stack state shown in (c) in the last figure
• On this stack, executing
pop
EBX
results in the stack state shown in (b) in the next figure
and the register EBX gets the value 7FBD329AH
Capitolul 7
9
Pentium Stack Example - 2
Capitolul 7
10
Additional Pentium Stack Instructions
Stack Operations on Flags
• push and pop instructions cannot be used with the
Flags register
• Two special instructions for this purpose are
pushfd (push 32-bit flags)
popfd (pop 32-bit flags)
• No operands are required
• Use pushfw and popfw for 16-bit flags (FLAGS)
Capitolul 7
11
Capitolul 7
12
2
Additional Pentium Stack Instructions
Uses of the Stack
• Three main uses
Stack Operations on All General-Purpose Registers
• pushad and popad instructions can be used to save and
restore the eight general-purpose registers
» Temporary storage of data
» Transfer of control
» Parameter passing
EAX, ECX, EDX, EBX, ESP, EBP, ESI, and EDI
• Pushad pushes these eight registers in the above order
(EAX first and EDI last)
• popad restores these registers except that ESP value is not
loaded into the ESP register
• Use pushaw and popaw for saving and restoring 16-bit
registers
Capitolul 7
13
Temporary Storage of Data
Example: Exchanging value1 and value2 can be
done by using the stack to temporarily hold data
push
push
pop
pop
Capitolul 7
Uses of the Stack (cont’d)
Transfer of Control
• In procedure calls and interrupts, the return address
is stored on the stack
• Our discussion on procedure calls clarifies this
particular use of the stack
;save EAX & EBX registers on the stack
push
EAX
push
EBX
;EAX and EBX registers can now be used
mov
EAX,value1
mov
EBX,value2
mov
value1,EBX
mov
value2,EAX
;restore EAX & EBX registers from the stack
pop
EBX
pop
EAX
. . .
Parameter Passing
• Stack is extensively used for parameter passing
• Our discussion later on parameter passing describes
how the stack is used for this purpose
15
Procedures
Capitolul 7
16
Pentium Instructions for Procedures
• Pentium provides two instructions: call and ret
• call instruction is used to invoke a procedure
• The format is
• Two types
∗ Call-by-value
» Receives only values
» Similar to mathematical functions
call
proc-name
proc-name is the procedure name
• Actions taken during a near procedure call:
ESP = ESP - 4
; push return address
SS:ESP = EIP
; onto the stack
EIP = EIP + relative displacement
; update EIP to point to the procedure
∗ Call-by-reference
» Receives pointers
» Directly manipulates parameter storage
Capitolul 7
14
Uses of the Stack (cont’d)
• Often used to free a set of registers
Capitolul 7
value1
value2
value1
value2
17
Capitolul 7
18
3
Pentium Instructions for Procedures (cont’d)
• We can specify an optional integer in the ret
instruction
• ret instruction is used to transfer control back to
the calling procedure
∗ The format is
• How will the processor know where to return?
∗ Uses the return address pushed onto the stack as part of
executing the call instruction
∗ Important that TOS points to this return address when
ret instruction is executed
• Actions taken during the execution of ret are:
EIP = SS:ESP
ESP = ESP + 4
; pop return address
; from the stack
Capitolul 7
Pentium Instructions for Procedures (cont’d)
19
ret
ret 8
• Actions taken on ret with optional-integer are:
EIP = SS:ESP
ESP = ESP + 4 + optional-integer
Capitolul 7
20
How Is Program Control Transferred?
Offset(hex)
00000002
00000007
Parameter Passing
machine code(hex)
main:
. . . .
E816000000 call
sum
89C3
mov
EBX,EAX
. . . .
; end of main procedure
• Parameter passing is different and complicated than
in a high-level language
• In assembly language
» You should first place all required parameters in a mutually
accessible storage area
» Then call the procedure
sum:
0000001D
55
push
EBP
. . . .
; end of sum procedure
• Type of storage area used
» Registers (general-purpose registers are used)
» Memory (stack is used)
avg:
00000028
0000002D
. . . .
call
sum
mov
EAX,EBX
. . . .
; end of avg procedure
• Two common methods of parameter passing:
E8F0FFFFFF
89D8
Capitolul 7
» Register method
» Stack method
21
Parameter Passing: Register Method
Capitolul 7
22
Pros and Cons of the Register Method
• Calling procedure places the necessary parameters
in the general-purpose registers before invoking the
procedure through the call instruction
• Examples:
∗ PROCEX1.ASM
• Advantages
∗ Convenient and easier
∗ Faster
• Disadvantages
∗ Only a few parameters can be passed using the register
method
» call-by-value using the register method
» a simple sum procedure
– Only a small number of registers are available
∗ Often these registers are not free
∗ PROCEX2.ASM
– freeing them by pushing their values onto the stack negates
the second advantage
» call-by-reference using the register method
» string length procedure
Capitolul 7
optional-integer
∗ Example:
23
Capitolul 7
24
4
Parameter Passing: Stack Method
Accessing Parameters on the Stack
• Parameter values are buried inside the stack
• All parameter values are pushed onto the stack
before calling the procedure
• Example:
push
push
call
• We can use the following to read number2
mov
number1
number2
sum
EBX,[ESP+4]
Problem: The ESP value changes with push and
pop operations
» Relative offset depends of the stack operations
performed
» Not desirable
• Is there a better alternative?
∗ Use EBP to access parameters on the stack
Capitolul 7
25
Capitolul 7
Using BP Register to Access Parameters
26
Clearing the Stack Parameters
• Preferred method of accessing parameters on the
stack is
mov
mov
EBP,ESP
EAX,[EBP+4]
to access number2 in the previous example
• Problem: BP contents are lost!
∗ We have to preserve the contents of BP
∗ Use the stack (caution: offset value changes)
push
EBP
mov
EBP,ESP
Capitolul 7
Stack state after
saving EBP
27
28
Housekeeping Issues
• Two ways of clearing the unwanted parameters on
the stack:
• Who should clean up the stack of unwanted
parameters?
∗ Use the optional-integer in the ret instruction
∗ Calling procedure
» Use
» Need to update ESP with every procedure call
» Not really needed if procedures use fixed number of parameters
» C uses this method because C allows variable number of
parameters
ret
4
in the previous example
∗ Add the constant to ESP in calling procedure (C uses this
method)
Capitolul 7
Stack state after
executing ret
Capitolul 7
Clearing the Stack Parameters (cont’d)
push
push
call
add
Stack state after
pop EBP
∗ Called procedure
number1
number2
sum
ESP,4
» Code becomes modular (parameter clearing is done in only one
place)
» Cannot be used with variable number of parameters
29
Capitolul 7
30
5
Housekeeping Issues (cont’d)
Housekeeping Issues (cont’d)
• Need to preserve the state (contents of the
registers) of the calling procedure across a
procedure call.
• Who should preserve the state of the calling
procedure?
∗ Calling procedure
» Stack is used for this purpose
» Need to know the registers used by the called procedure
» Need to include instructions to save and restore registers
with every procedure call
» Causes program maintenance problems
• Which registers should be saved?
∗ Save those registers that are used by the calling
procedure but are modified by the called procedure
∗ Called procedure
» Might cause problems as the set of registers used by the
calling and called procedures changes over time
» Preferred method as the code becomes modular (state
preservation is done only once and in one place)
» Avoids the program maintenance problems mentioned
∗ Save all registers by using pusha
» Increased overhead (pusha takes 5 clocks as opposed 1 to
save a register)
Capitolul 7
31
Capitolul 7
Housekeeping Issues (cont’d)
32
Housekeeping Issues (cont’d)
• Need to preserve the state across a procedure
call
» Stack is used for this purpose
• Which registers should be saved?
Stack state after pusha
∗ Save those registers that are used by the calling
procedure but are modified by the called procedure
» Might cause problems
∗ Save all registers (brute force method)
» Done by using pusha
» Increased overhead
– pusha takes 5 clocks as opposed 1 to save a register
Capitolul 7
33
Capitolul 7
Stack Frame Instructions
Stack Frame Instructions (cont’d)
• ENTER instruction
• LEAVE instruction
∗ Facilitates stack frame (discussed later) allocation
enter
bytes,level
∗ Releases stack frame
leave
bytes = local storage space
level = nesting level (we use 0)
∗ Example
enter
» Takes no operands
» Equivalent to
mov
pop
XX,0
Equivalent to
push
mov
sub
Capitolul 7
34
ESP,EBP
EBP
EBP
EBP,ESP
ESP,XX
35
Capitolul 7
36
6
A Typical Procedure Template
Stack Parameter Passing: Examples
• PROCEX3.ASM
proc-name:
∗ call-by-value using the stack method
∗ a simple sum procedure
enter
XX,0
. . . . . .
<procedure body>
. . . . . .
leave
ret
YY
Capitolul 7
• PROCSWAP.ASM
∗ call-by-reference using the stack method
∗ first two characters of the input string are swapped
• BBLSORT.ASM
∗ implements bubble sort algorithm
∗ uses pusha and popa to save and restore registers
37
Variable Number of Parameters
Capitolul 7
38
Variable Number of Parameters (cont’d)
• For most procedures, the number of parameters is
fixed
• To implement variable
number of parameter
passing:
∗ Every time the procedure is called, the same number of
parameter values are passed)
• In procedures that can have variable number of
parameters
∗ Parameter count
should be one of the
parameters passed
∗ This count should be
the last parameter
pushed onto the stack
∗ With each procedure call, the number of parameter
values passed can be different
» C supports procedures with variable number of parameters
∗ Easy to support variable number of parameters using the
stack method
Capitolul 7
39
Capitolul 7
Memory Layout of a Linux Process
40
Local Variables
• Local variables are dynamic in nature
∗ Local variables of a procedure come into existence when
the procedure is invoked and disappear when the
procedure terminates.
• Cannot reserve space for these variable in the data
segment for two reasons:
» Such space allocation is static (remains active even when the
procedure is not)
» It does not work with recursive procedures
• For these reasons, space for local variables is
reserved on the stack
Capitolul 7
41
Capitolul 7
42
7
Local Variables (cont’d)
Local Variables (cont’d)
• The information stored in the stack
»
»
»
»
Example
• N and temp
∗ Two local
variables
parameters
returns address
old BP value
local variables
is collectively called stack frame
• In high-level languages, stack frame is also referred
to as the activation record
∗ Each requires
two bytes of
storage
» Because each procedure activation requires all this information
• The EBP value is referred to as the frame pointer
» Once the EBP value is known, we can access all the data in the
stack frame
Capitolul 7
43
Capitolul 7
Local Variables: Examples
Multiple Module Programs
• PROCFIB1.ASM
∗ For simple procedures, registers can also be used for local
variable storage
∗ Uses registers for local variable storage
∗ Outputs the largest Fibonacci number that is less than the
given input number
• PROCFIB2.ASM
» If a module is modified, only that module needs to be
reassembled (not the whole program)
» Several programmers can share the work
» Making modifications is easier with several short files
» Unintended modifications can be avoided
» GLOBAL and EXTERN
45
GLOBAL Assembler Directive
Capitolul 7
global
.DATA
error_msg
total
» Makes these labels available for other modules of the program
• The format is
label1, label2, . . .
• Almost any label can be made public including
error_msg, total, sample
. . . . .
db
‘Out of range!’,0
dw
0
. . . . .
.CODE
» procedure names
» variable names
» equated labels
. . . . .
sample:
. . . . .
ret
∗ In the GLOBAL statement, it is not necessary to specify
the type of label
Capitolul 7
46
Example: GLOBAL Assembler Directive
• The GLOBAL directive makes the associated labels
public
global
• In multi-module programs, a single program is split
into multiple source files
• Advantages
• To facilitate separate assembly, two assembler
directives are provided:
∗ Uses the stack for local variable storage
∗ Performance implications of using registers versus stack
are discussed later
Capitolul 7
44
47
Capitolul 7
48
8
EXTRN Assembler Directive
EXTERN Assembler Directive (cont’d)
• The EXTERN directive tells the assembler that
certain labels are not defined in the current module
Example
module1.asm
– main procedure
module2.asm
– string length procedure
∗ The assembler leaves “holes” in the object file for the
linker to fill in later on
• The format is
extern
label1, label2, . . .
where label1 and label2 are labels made public
by a GLOBAL directive in some other module
Capitolul 7
49
Performance: Procedure Overheads
Capitolul 7
50
Performance: Procedure Overheads (cont’d)
Stack versus Registers
• No swap procedure (Program 5.5, lines 95-99)
2
[ESI+4],EAX
[ESI],EBX
EDX,UNSORTED
Sort time (seconds)
swap:
mov
mov
mov
• SWAP procedure (replaces the above code)
swap_proc:
mov
[ESI+4],EAX
mov
[ESI],EBX
mov
EDX,UNSORTED
ret
With sort procedure
1.5
1
0.5
Without sort procedure
0
5000
10000
15000
20000
25000
Array size
Capitolul 7
51
Capitolul 7
52
Performance: Local Variable Overhead
Time (seconds)
2
1.5
Recursion
Local variables in stack
1
Chapter 16
S. Dandamudi
Local variables in registers
0.5
0
1
2
3
4
5
6
7
8
9
Number of calls (in millions)
Capitolul 7
53
Capitolul 7
54
9
Introduction
Outline
• A recursive procedure calls itself
∗ Directly, or
∗ Indirectly
• Introduction
• Recursion
• Recursion vs. Iteration
• Some applications can be naturally expressed using
recursion
factorial(0) = 1
factorial (n) = n * factorial(n−1) for n > 0
• From implementation viewpoint
∗ Very similar to any other procedure call
» Activation records are stored on the stack
Capitolul 7
55
Capitolul 7
56
Introduction (cont’d)
Recursion
• Two examples in Pentium and MIPS assembly
languages
∗ Factorial
∗ Quicksort
Example 1
∗ Factorial
factorial(0) = 1
factorial (n) = n * factorial(n−1) for n > 0
• Activation record
∗ Consists of the return address pushed onto the stack by
the call instruction
Capitolul 7
57
Capitolul 7
Recursion (cont’d)
Recursion vs. Iteration
• Recursion
Example 2
• Quicksort
∗ Concise
∗ Better program maintenance
∗ Natural choice for some problems
∗ Sort an N-element array
∗ Basic algorithm
»
»
»
»
»
Capitolul 7
58
• Potential problems
Selects a partition element x
Assume that the final position of x is array[i]
Moves elements less than x into array[0]…array[i−1]
Moves elements greater than x into array[i+1]…array[N−1]
Applies quicksort recursively to sort these two subarrays
∗ Inefficiency
» Call invocation and return overheads
» Duplicate computation
∗ Increased memory requirements
59
Capitolul 7
60
10
Outline
• String representation
• Examples
∗ Using string length
∗ Using a sentinel character
String Processing
∗
∗
∗
∗
∗
∗
• String instructions
Repetition prefixes
Direction flag
String move instructions
String compare
instructions
∗ String scan instructions
∗
∗
∗
∗
Chapter 10
S. Dandamudi
• Illustrative examples
str_len
str-cpy
str_cat
str_cmp
str_chr
str_cnv
• Indirect procedure call
• Performance:
Advantage of string
instructions
∗ LDS and LES instructions
Capitolul 7
61
Capitolul 7
62
String Representation
String Representation (cont’d)
• Two types
• Variable-length strings
∗ Fixed-length
∗ Variable-length
∗ Avoids the pitfalls associated with fixed-length strings
• Two ways of representation
• Fixed length strings
∗ Explicitly storing string length (used in PASCAL)
string
DB
‘Error message’
str_len
DW
$-string
– $ represents the current value of the location counter
$ points to the byte after the last character of string
∗ Each string uses the same length
» Shorter strings are padded (e.g. by blank characters)
» Longer strings are truncated
∗ Selection of string length is critical
∗ Using a sentinel character (used in C)
» Too large ==> inefficient
» Too small ==> truncation of larger strings
Capitolul 7
» Uses NULL character
– Such NULL-terminated strings are called ASCIIZ strings
63
Capitolul 7
64
String Instructions
String Instructions (cont’d)
• Each string instruction
• Five string instructions
LODS
STOS
MOVS
CMPS
SCAS
LOaD String
STOre String
MOVe String
CoMPare String
SCAn String
∗ Can operate on 8-, 16-, or 32-bit operands
∗ Updates index register(s) automatically
source
destination
source & destination
source & destination
destination
» Byte operands: increment/decrement by 1
» Word operands: increment/decrement by 2
» Doubleword operands: increment/decrement by 4
• Direction flag
• Specifying operands
∗ DF = 0: Forward direction (increments index registers)
∗ DF = 1: Backward direction (decrements index
registers)
∗ 32-bit segments:
DS:ESI = source operand
ES:EDI = destination operand
• Two instructions to manipulate DF
∗ 16-bit segments:
DS:SI = source operand
Capitolul 7
std
cld
ES:DI = destination operand
65
Capitolul 7
set direction flag (DF = 1)
clear direction flag (DF = 0)
66
11
Repetition Prefixes
Repetition Prefixes (cont’d)
rep
• String instructions can be repeated by using a
repetition prefix
• Two types
while (ECX ≠ 0)
execute the string instruction
ECX := ECX−1
end while
∗ Unconditional repetition
rep
REPeat
∗ Conditional repetition
repe/repz
• ECX register is first checked
REPeat while Equal
REPeat while Zero
∗ If zero, string instruction is not executed at all
∗ More like the JECXZ instruction
repne/repnz REPeat while Not Equal
REPeat while Not Zero
Capitolul 7
67
Capitolul 7
Repetition Prefixes (cont’d)
Repetition Prefixes (cont’d)
repne/repnz
repe/repz
while (ECX ≠ 0)
execute the string instruction
ECX := ECX−1
if (ZF = 0)
then
exit loop
end if
end while
while (ECX ≠ 0)
execute the string instruction
ECX := ECX−1
if (ZF = 1)
then
exit loop
end if
end while
• Useful with cmps and scas string instructions
Capitolul 7
69
Capitolul 7
String Move Instructions
70
String Move Instructions (cont’d)
movsb --- move a byte string
ES:EDI:= (DS:ESI) ; copy a byte
if (DF=0)
; forward direction
then
ESI := ESI+1
EDI := EDI+1
else
; backward direction
ESI := ESI−1
EDI := EDI−1
end if
Flags affected: none
• Three basic instructions
movs, lods, and stos
• Move a string (movs)
• Format
movs dest_string,source_string
movsb
; operands are bytes
movsw
; operands are words
movsd
; operands are doublewords
• First form is not used frequently
∗ Source and destination are assumed to be pointed by
DS:ESI and ES:EDI, respectively
Capitolul 7
68
71
Capitolul 7
72
12
String Move Instructions (cont’d)
String Move Instructions (cont’d)
Example
Load a String (LODS)
• Copies the value from the source string at DS:ESI to
.DATA
string1
db
'The original string',0
strLen
EQU
$ - string1
.UDATA
string2
resb
80
.CODE
.STARTUP
mov
AX,DS
; set up ES
mov
ES,AX
; to the data segment
mov
ECX,strLen
; strLen includes NULL
mov
ESI,string1
mov
EDI,string2
cld
; forward direction
rep
movsb
Capitolul 7
∗ AL (lodsb)
∗ AX (lodsw)
∗ EAX (lodsd)
• Repetition prefix does not make sense
∗ It leaves only the last value in AL, AX, or EAX register
73
Capitolul 7
String Move Instructions (cont’d)
String Move Instructions (cont’d)
Store a String (STOS)
• Performs the complementary operation
• Copies the value in
lodsb --- load a byte string
AL := (DS:ESI)
; copy a byte
if (DF=0)
; forward direction
» AL (lodsb)
» AX (lodsw)
» EAX (lodsd)
then
ESI := ESI+1
; backward direction
else
74
to the destination string at ES:EDI
ESI := ESI−1
• Repetition prefix can be used if you want to
initialize a block of memory
end if
Flags affected: none
Capitolul 7
75
Capitolul 7
String Move Instructions (cont’d)
String Move Instructions (cont’d)
Example: Initializes array1 with -1
stosb --- store a byte string
ES:EDI := AL ; copy a byte
if (DF=0)
; forward direction
.UDATA
array1
resw
100
.CODE
.STARTUP
mov
AX,DS
mov
ES,AX
mov
ECX,100
mov
EDI,array1
mov
AX,-1
cld
rep
stosw
then
EDI := EDI+1
; backward direction
else
EDI := EDI−1
end if
Flags affected: none
Capitolul 7
76
77
Capitolul 7
; set up ES
; to the data segment
; forward direction
78
13
String Move Instructions (cont’d)
String Compare Instruction
cmpsb --- compare two byte strings
Compare two bytes at DS:ESI and ES:EDI and set
flags
• In general, repeat prefixes are not useful with
lods and stos
• Used in a loop to do conversions while copying
mov
ECX,strLen
mov
ESI,string1
mov
EDI,string2
cld
loop1:
lodsb
or
AL,20H
stosb
loop loop1
done:
if (DF=0)
then
ESI := ESI+1
EDI := EDI+1
else
ESI := ESI−1
EDI := EDI−1
end if
; forward direction
Capitolul 7
; backward direction
Flags affected: As per cmp instruction (DS:ESI)−(ES:EDI)
79
String Compare Instruction (cont’d)
Capitolul 7
80
String Compare Instruction (cont’d)
.DATA
string1
db
'abcdfghi',0
strLen
EQU
$ - string1
string2
db
'abcdefgh',0
.CODE
.STARTUP
mov
AX,DS
; set up ES
mov
ES,AX
; to the data segment
mov
ECX,strLen
mov
ESI,string1
mov
EDI,string2
cld
; forward direction
repe
cmpsb
dec
ESI
dec
EDI
; ESI & EDI pointing to the last character that differs
Capitolul 7
; forward direction
.DATA
string1
db
'abcdfghi',0
strLen
EQU
$ - string1 - 1
string2
db
'abcdefgh',0
.CODE
.STARTUP
mov
AX,DS
; set up ES
mov
ES,AX
; to the data segment
mov
EECX,strLen
mov
ESI,string1 + strLen - 1
mov
EDI,string2 + strLen - 1
std
; backward direction
repne cmpsb
inc
ESI ; ESI & EDI pointing to the first character that matches
inc
EDI ; in the backward direction
81
Capitolul 7
String Scan Instruction
82
String Scan Instruction (cont’d)
Example 1
scasb --- Scan a byte string
Compare AL to the byte at ES:EDI & set flags
if (DF=0)
; forward direction
then
EDI := EDI+1
else
; backward direction
EDI := EDI−1
end if
Flags affected: As per cmp instruction (DS:ESI)−(ES:EDI)
• scasw uses AX and scasd uses EAX instead of AL
Capitolul 7
83
.DATA
string1
db
'abcdefgh',0
strLen
EQU
$ - string1
.CODE
.STARTUP
mov
AX,DS
; set up ES
mov
ES,AX
; to the data segment
mov
ECX,strLen
mov
EDI,string1
mov
AL,'e'
; character to be searched
cld
; forward direction
repne scasb
dec
EDI
; leaves EDI pointing to e in string1
Capitolul 7
84
14
String Scan Instruction (cont’d)
Illustrative Examples
Example 2
.DATA
string1
db
'
abc',0
strLen
EQU
$ - string1
.CODE
.STARTUP
mov
AX,DS
; set up ES
mov
ES,AX
; to the data segment
mov
ECX,strLen
mov
EDI,string1
mov
AL,' '
; character to be searched
cld
; forward direction
repe
scasb
dec
EDI
; EDI pointing to the first non-blank character a
LDS and LES instructions
• String pointer can be loaded into DS/SI or ES/DI
register pair by using lds or les instructions
• Syntax
lds
register,source
les
register,source
∗ register should be a 32-bit register
∗ source is a pointer to a 48-bit memory
operand
» register is typically ESI in lds and EDI in les
Capitolul 7
85
Capitolul 7
Illustrative Examples (cont’d)
Illustrative Examples (cont’d)
• Actions of lds and les
lds
• Seven popular string processing routines are given
as examples
∗ str_len
register := (source)
DS := (source+4)
∗ str-cpy
les
∗ str_cat
register := (source)
ES := (source+4)
∗ str_cmp
∗ str_chr
∗ str_cnv
• Pentium also supports lfs, lgs, and lss to load
the other segment registers
Capitolul 7
87
Capitolul 7
Indirect Procedure Call
88
Performance: of String Instructions
• Direct procedure calls specify the offset of the first
instruction of the called procedure
• In indirect procedure call, the offset is specified
through memory or a register
• Two chief advantages of string instructions
∗ Index registers are automatically updated
∗ Can operate two operands in memory
• Example: Copy data from array1 to array2
∗ If BX contains pointer to the procedure, we can use
call
EBX
∗ If the word in memory at target_proc_ptr contains
the offset of the called procedure, we can use
call
[target_proc_ptr]
cld
rep
movsd
∗ Assumes:
DS:ESI points to array1
ES:EDI points to array2
ECX contains the array size
• These are similar to direct and indirect jumps
Capitolul 7
86
89
Capitolul 7
90
15
Performance: of String Instructions
50,000-element array-to-array copy
Time (seconds)
4
No string
instructions
3
High-Level Language Interface
2
Chapter 17
S. Dandamudi
With string
instructions
1
0
10
20
30
40
50
60
Number of calls (in thousands)
Last slide
Capitolul 7
91
Capitolul 7
92
Why Program in Mixed-Mode?
Outline
• Pros and cons of assembly language programming
• Why program in mixedmode?
∗ Focus on C and assembly
• Overview of compiling
mixed-mode programs
∗ Advantages:
• Illustrative examples
» Access to hardware
» Time-efficiency
» Space-efficiency
• Calling C functions from
assembly
∗ Problems:
» Low productivity
» High maintenance cost
» Lack of portability
• Inline assembly code
• Calling assembly
procedures from C
Parameter passing
Returning values
Preserving registers
Globals and externals
∗
∗
∗
∗
∗
∗
∗
∗
AT&T syntax
Simple inline statements
Extended inline statements
Inline examples
Capitolul 7
• As a result, some programs are written in mixedmodem (e.g., system software)
93
Capitolul 7
Compiling Mixed-Mode Programs
94
Compiling Mixed-Mode Programs
• We use C and assembly mixed-mode programming
• Our emphasis is on the principles
• Can be generalized to any type of mixed-mode
programming
• To compile
nasm –f elf sample2.asm
» Creates sample2.o
gcc –o sample1.out sample1.c sample2.o
» Creates sample1.out executable file
Capitolul 7
95
Capitolul 7
96
16
Calling Assembly Procedures from C
Calling Assembly Procedures from C (cont’d)
Parameter Passing
• Stack is used for parameter passing
• Two ways of pushing arguments onto the stack
Example:
sum(a,b,c,d)
∗ Left-to-right
» Most languages including Basic, Fortran, Pascal use this method
» These languages are called left-pusher languages
∗ Right-to-left
» C uses this method
» These languages are called right-pusher languages
Capitolul 7
97
Calling Assembly Procedures from C (cont’d)
Returning Values
• Registers are used to return values
Return value type
Register used
8-, 16-, 32-bit value
64-bit value
Capitolul 7
98
Calling Assembly Procedures from C (cont’d)
Preserving Registers
• The following registers must be preserved
EBP, EBX, ESI, and EDI
• Other registers
EAX
∗ If needed, should be preserved by the calling function
EDX:EAX
• Floating-point values are discussed in the next
chapter
Capitolul 7
99
Capitolul 7
Calling Assembly Procedures from C (cont’d)
Illustrative Examples
• Example 1
Globals and Externals
• Mixed-mode programming involves at least two
program modules
∗ hll_ex1c.c
∗ hll_test.asm
• Example 2
» One C module and one assembly module
• We have to declare those functions and procedures
that are not defined in the same module as external
» See Section 5.10
∗ hll_minmaxc.c
∗ hll_minmaxa.asm
• Example 3
• Those procedures that are accessed by another
modules as global
Capitolul 7
100
∗ hll_arraysumc.c
∗ hll_arraysuma.asm
101
Capitolul 7
102
17
Calling C Functions from Assembly
Inline Assembly
• Stack is used to pass parameters (as in our previous
discussion)
∗ Similar mechanism is used to pass parameters and to
return values
• Since C makes the calling procedure responsible for
clearing the stack of the parameters, make sure to
clear the parameters after the call instruction as
in
add
ESP,4
on line 31 in the example program on page 494
Capitolul 7
103
• Assembly language statements are embedded into
the C code
» Separate assembly module is not necessary
• Assembly statements are identified by placing the
keyword asm
• We can use ( ) to compound several assembly
statements
asm(
assembly statement
assembly statement
. . .
);
Capitolul 7
Inline Assembly (cont’d)
Inline Assembly (cont’d)
• AT&T Syntax (cont’d)
• AT&T Syntax
∗ Immediate and constant operands
∗ GCC uses this syntax
∗ Register naming
» Prefix the operands with $
movb
$255,%al
movl
$0xFFFFFFFF,%eax
» Prefix with % as in %eax
∗ Source and destination order
∗ Addressing
» Reversed
mov eax,ebx
is written as
movl %ebx,%eax
» Use ( ) rather then [ ]
mov eax,[ebx]
is written as
movl (%ebx),%eax
» Full protected-mode addressing format
imm32(base,index,scale)
Computed as
imm32 + base + index*scale
∗ Operand size
» Explicit using b, w, l for byte, word, and longword operands
Capitolul 7
105
Capitolul 7
Inline Assembly (cont’d)
Extended Inline Statements
%eax”);
• Format
• Multiple statements
asm(”pushl %eax”);
asm(”incl %eax”);
asm(”popl %eax”);
∗ Can be Written as
asm(”pushl %eax; incl
∗ Or as (to add structure)
asm(”pushl %eax”;
”incl %eax”;
”popl %eax”);
Capitolul 7
106
Inline Assembly (cont’d)
Simple Inline Statements
asm(”incl
104
asm(assembly code
:outputs
:inputs
:clobber list);
%eax; popl %eax”);
• Assembly code
∗ Add keyword volatile after asm
» if no compiler optimizations are needed
107
Capitolul 7
108
18
Inline Assembly (cont’d)
Inline Assembly (cont’d)
• Outputs
• Register letters
» Format
”=op-constraint” (C-expression)
Letter
a
b
c
d
S
D
r
» Example
”=r”(sum)
» Output constraints
r = register
m = memory
i
= immediate
rm = register or memory,
ri = register or immediate
g = general
Capitolul 7
109
Register set
EAX register
EBX register
ECX register
EDX register
ESI register
EDI register
Any of the 8 general registers
(EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP)
Capitolul 7
Inline Assembly (cont’d)
110
Inline Assembly (cont’d)
• Inputs
∗ Similar to how the outputs are specified
(with
no = sign)
∗ Operands specified in the output and input parts are
assigned sequence numbers 0, 1, 2, …
• Register letters
Letter
q
Register set
Any of four data registers
(EAX, EBX, ECX, EDX)
A 64-bit value in EAX and EDX
Floating-point registers
Top floating-point register
Second top floating-point register
A
f
t
u
Capitolul 7
» Can be a total of 10 operands
∗ Example
asm(“movl %1,%0”
%0 refers to sum
:”=r” (sum)
/*%1output
*/
to number1
:”r” (number1) /* input */
);
111
Capitolul 7
Inline Assembly (cont’d)
112
Inline Assembly (cont’d)
• Clobber list
• Inline examples
∗ List of registers modified by the assembly code
∗ Lets gcc know of this
∗ Example
asm(“movl %0,%%eax”
: /*no output */
:”r” (number1) /* inputs */
:”%eax”
/* clobber list */
);
∗ Example 1
» hll_ex1_inline.c
∗ Example 2
» Array sum example
» hll_arraysum_inline.c
∗ Example 3
» Second version of the last example
» hll_arraysum_inline2.c
Last slide
Capitolul 7
113
Capitolul 7
114
19