Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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