Presentation is loading. Please wait.

Presentation is loading. Please wait.

Assembly Language Programming Chapter 8

Similar presentations

Presentation on theme: "Assembly Language Programming Chapter 8"— Presentation transcript:

1 Assembly Language Programming Chapter 8
Advanced Procedures Assembly Language Programming Chapter 8

2 Programming is: Exploring the problem space – Knowing what the problem is (10%) - Requirements Understanding the problem – Knowing what to program (10%) - Specification Solving the problem – Knowing how to program it (20%) Design = Data + Algorithms + Users (I/O) Implementing the solution – Coding (20%) Evaluating the solution – Testing (40%) Unit, Integration, Performance/Stress, Usability, Security

3 This list is endless and grows with experience!
Things to Consider Limitations, Constraints, Trade-offs Performance (Efficiency), Space/Size Data – Encoding, representation, size, portability Architecture, Algorithm, Programming language Libraries, Tools, Networks, Platform Users, Security, Privacy Faults, fault tolerance, error recovery, error handling, failures, downtime, overflow, underflow This list is endless and grows with experience!

4 Program Design Techniques
Top-Down Design (functional decomposition) involves the following: design your program before starting to code break large tasks into smaller ones use a hierarchical structure based on procedure calls test individual procedures separately The Problems … Assumes programmer has a strong understanding of the necessary and correct architecture Important decisions made early – mistakes thus costly Assumes hierarchical structure is actually possible All initial work on design, none on coding, nothing to show for large periods of time Highly likely to fail or be ineffective on large projects

5 Program Design, Alternatively
Bottom-Up Design (functional synthesis) involves the following: Pick one small part of the program, write a procedure to perform it Repeat until a collection of small parts is formed Write a procedure to join several small parts Continue until all the parts implemented and joined Build some Lego blocks, connect them, build some more … Some comments … Design tends to emerge, not necessarily planned Gets parts working sooner, easier to spot programming road- blocks Hard to know how big the parts should be Can ignore some parts if time runs out (and they are not important) Not good for teams as no plan exists Generally safer, but less overall structure

6 Reality of Programming
A mixture of bottom-up and top-down approachs Top-down design – Some planning needed before you start Bottom-up implementation – Don't over plan Iterative methodologies – Get it to work then refine and improve Opportunistic approaches – do what works, when it works Much personal preference exists (strong sex-based differences as well)

7 Creating Procedures Large problems can be divided into smaller tasks to make them more manageable A procedure is the ASM equivalent of a Java Method, C/C++ Function, Basic Subroutine, or Pascal Procedure Same thing as what is in the Irvine32 library The following is an assembly language procedure named sample: sample PROC … Code for procedure goes here … ret sample ENDP

8 CALL and RET The CALL instruction calls a procedure
pushes offset of next instruction on the stack (saves the value of the instruction pointer) copies the address of the called procedure into EIP (puts the address of the procedure into the instruction pointer) Begins to execute the code of the procedure The RET instruction returns from a procedure pops top of stack into EIP (over-writes instruction pointer with the value of the instruction after the call)

9 CALL-RET Example main PROC 00000020 call MySub 00000025 mov eax,ebx .
main ENDP MySub PROC mov eax,edx ret MySub ENDP is the offset of the instruction immediately following the CALL instruction is the offset of the first instruction inside MySub

10 (stack shown before RET executes)
CALL-RET in Action The CALL instruction pushes onto the stack, and loads into EIP CALL = PUSH eip MOV EIP, OFFSET proc The RET instruction pops from the stack into EIP RET = POP eip (stack shown before RET executes)

11 Nested Procedure Calls
By the time Sub3 is called, the stack contains all three return addresses:

12 MASM generates the code shown in gold
USES Operator Lists the registers that are used by a procedure MASM inserts code that will try to preserve them ArraySum PROC USES esi ecx mov eax,0 ; set the sum to zero etc. MASM generates the code shown in gold ArraySum PROC push esi push ecx . pop ecx pop esi ret ArraySum ENDP

13 Terminology int sum (int x, int y) { return (x+y); } …
printf(“%d\n”, sum(2,3)); x, y are the parameters of the procedure called sum 2, 3 are the arguments for a specific call, invocation, instance of sum

14 Stack Frame Also known as an activation record
Area of the stack set aside for a procedure's return address, passed parameters, saved registers, and local variables Created by the following steps: Calling program pushes arguments on the stack and calls the procedure The called procedure pushes EBP on the stack, and sets EBP to ESP If local variables are needed, a constant is subtracted from ESP to make room on the stack Registers are saved if they will be altered

Calling a Proc Push arguments (parameter values) on stack Call proc (and push the return address on the stack) Push EBP on the stack Set EBP equal to ESP (points to its own location on stack) Add stack space for local variables (“push space on stack") Push registers to save on the stack MEMORISE THIS SET OF STEPS!

16 Stack after the CALL This is what we must build
Val/Address Arg 2: EBP + 12 Val/Address Arg 1: EBP + 8 Return Address Old/Saved EBP Local Variable 1: EBP - 4 Local Variable 2: EBP - 8 EAX (saved) EDX (saved) Empty Space EBP ESP

17 Stack Parameters Sometimes more convenient than register parameters
Any number of values can be pushed/passed Values are in memory and don’t need to be moved there later Two possible ways of calling DumpMem pushad mov esi,OFFSET array mov ecx,LENGTHOF array mov ebx,TYPE array call DumpMem popad push TYPE array push LENGTHOF array push OFFSET array call DumpMem

18 Passing Args Push arguments on stack Call the called-procedure
Suggestion: Use only 32-bit values in protected mode to keep the stack aligned – Don’t push random length strings! By Value: Push the values on the stack By Reference: Push the address (offsets) on the stack Call the called-procedure Put return value in eax Return Remove arguments from the stack if the called-procedure did not remove them

19 Example: Pass by Value (val2) 6 (val1) 5 ESP Stack prior to CALL .data
val1 DWORD 5 val2 DWORD 6 .code push val2 push val1 (val2) (val1) ESP Stack prior to CALL

20 Example: Pass by Reference
.data val1 DWORD 5 val2 DWORD 6 .code push OFFSET val2 push OFFSET val1 (offset val2) (offset val1) ESP Stack prior to CALL

21 Stack after the CALL This is what we must build
Val/Address Arg 2: EBP + 12 Val/Address Arg 1: EBP + 8 Return Address Old/Saved EBP Local Variable 1: EBP - 4 Local Variable 2: EBP - 8 EAX (saved) EDX (saved) Empty Space EBP ESP

22 Simple Example The ArrayFill procedure fills an array with 16-bit random integers The calling program passes the address of the array, along with a count of the number of array elements: .data count = 100 array WORD count DUP(?) .code push OFFSET array push COUNT call ArrayFill

23 Passing an Array ArrayFill can reference an array without knowing the arrays name ArrayFill PROC push ebp mov ebp,esp pushad mov esi,[ebp+12] mov ecx,[ebp+8] . ESI points to the beginning of the array, so it's easy to use a loop to access each array element

24 Stack Parameters (C/C++)
C and C++ functions access stack parameters using constant offsets from EBP Example: [ebp + 8] EBP is called the base pointer or frame pointer because it holds the base address of the stack frame. EBP does not change value during the function. EBP must be restored to its original value when a function returns.

25 RET Instruction Return from subroutine
Pops stack into the instruction pointer (EIP or IP) -- Control transfers to the target address Syntax: RET RET n Optional operand n causes n bytes to be added to the stack pointer after EIP (or IP) is assigned a value Adding n bytes to ESP “deletes” the pushed arguments from the stack

26 Stack after the CALL All this has to go …
Val/Address Arg 2: EBP + 12 Val/Address Arg 1: EBP + 8 Return Address Old/Saved EBP Local Variable 1: EBP - 4 Local Variable 2: EBP - 8 EAX (saved) EDX (saved) Empty Space EBP ESP

27 Deleting Parameters In the Windows StdCall Model the called procedure uses ret n to remove the parameters In C/C++ Model, the calling procedure removes them after the call has returned either by Popping them off the stack Adding n to ESP

28 Example Procedure Difference subtracts the first argument from the second one Sample call: push 14 ; first argument push 30 ; second argument call Difference ; EAX = -16 Difference PROC push ebp mov ebp,esp mov eax,[ebp + 12] ; first argument sub eax,[ebp + 8] ; second argument pop ebp ret 8 ; remove the 2 args Difference ENDP

29 Passing 8/16-bit Arguments
Cannot push 8-bit values on stack Pushing 16-bit operand may cause page fault or ESP alignment problem -- also incompatible with Windows API functions Expand smaller arguments into 32-bit values, using MOVZX or MOVSX .data charVal BYTE 'x' .code movzx eax,charVal push eax call Uppercase

30 Passing Multiword Arguments
Push high-order values on the stack first and work backward in memory Results in little-endian ordering of data Example: .data longVal DQ ABCDEFh .code push DWORD PTR longVal + 4 ; high doubleword push DWORD PTR longVal ; low doubleword call WriteHex64

31 Saving & Restoring Registers
Push registers on stack just after assigning ESP to EBP to save registers that are modified inside the procedure Remember: Don't overwrite the register containing the return value when you restore the registers! MySub PROC push ebp mov ebp,esp push ecx ; save local registers push edx

32 Local Variables Only statements within subroutine can view or modify local variables Storage used by local variables is released when subroutine ends local variable name can have the same name as a local variable in another function without creating a name clash Essential when writing recursive procedures, as well as procedures executed by multiple execution threads

33 Creating LOCAL Variables
Example - create two DWORD local variables: Say: int x=10, y=20; ret address saved ebp EBP 10 (x) [ebp-4] MySub PROC (y) [ebp-8] push ebp mov ebp,esp sub esp,8 ;create 2 DWORD variables mov DWORD PTR [ebp-4],10 ;[ebp-4] = x = 10 mov DWORD PTR [ebp-8],20 ;[ebp-8] = y = 20

34 A Complete Procedure int swap (string s, index i1, index i2) {
char c = s[i1]; s[i1] = s[i2]; s[i2] = c; return; } (Address of) s: EBP+16 I1: EBP+12 I2: EBP+8 Return Address Saved EBP (of main) C: EBP-4 ESI EDI EAX Empty Space

35 A Complete Procedure swap PROC push ebp mov ebp,esp sub esp,4 push esi
(Address of) s: EBP+16 I1: EBP+12 I2: EBP+8 Return Address Saved EBP (of main) C: EBP-4 ESI EDI EAX Empty Space swap PROC push ebp mov ebp,esp sub esp,4 push esi push edi push eax ;c = s[i1]; ;s[i1] = s[i2]; ;s[i2] = c; pop eax pop edi pop esi add esp,4 push OFFSET sbuf pop ebp push 0 ret push (SIZE sbuf) - 1 swap ENDP call swap

36 A Complete Procedure ;esi = address of str[index1] mov esi,[ebp+16]
add esi,[ebp+12] ;edi = address of str[index2] mov edi,[ebp+16] add edi,[ebp+8] ;c = str[index1] mov al,BYTE PTR [esi] mov [ebp-4],eax ;str[index1] = str[index2] mov al, BYTE PTR [edi] mov BYTE PTR [esi],al ;str[index2] = c mov eax,[ebp-4] mov BYTE PTR [edi],al swap PROC push ebp mov ebp,esp sub esp,4 push esi push edi push eax ;do the swap pop eax pop edi pop esi add esp,4 pop ebp ret 12 swap ENDP

37 ENTER Instruction ENTER partially creates a stack frame for a called proc pushes EBP on the stack sets EBP to the base of the stack frame reserves space for local variables Example: MySub PROC enter 8,0 ;0 = nesting level (not used here) Equivalent to: push ebp mov ebp,esp sub esp,8

38 LEAVE Instruction Partially removes the stack frame for a procedure
Equivalent operations push ebp mov ebp,esp sub esp, ; 2 local DWORDs MySub PROC enter 8,0 ... leave ret MySub ENDP mov esp,ebp ; free local space pop ebp

39 A Simpler Proc swap PROC enter 4,0 pushad ;c = s[i1]; ;s[i1] = s[i2];
;s[i2] = c; popad leave ret 12 swap ENDP push OFFSET sbuf push 0 push (SIZE sbuf) -1 call swap (Address of) s: EBP+16 I1: EBP+12 I2: EBP+8 Return Address Saved EBP (of main) C: EBP-4 EAX ... EDI Empty Space

40 LOCAL Directive The LOCAL directive declares a list of local variables
immediately follows the PROC directive each variable is assigned a type replaces ENTER and LEAVE Syntax: LOCAL varlist Example: MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD

41 Casts the contents of esi to a byte
Using LOCAL Examples: LOCAL t1:BYTE ; single character LOCAL flagVals[20]:BYTE ; array of bytes LOCAL pArray:PTR WORD ; pointer to an array Note: inc BYTE PTR [esi] Casts the contents of esi to a byte Different use of PTR!

42 Example MASM generates the following code: BubbleSort PROC
LOCAL temp:DWORD, SwapFlag:BYTE . . . ret BubbleSort ENDP MASM generates the following code: BubbleSort PROC push ebp mov ebp,esp add esp,0FFFFFFF8h ; add -8 to ESP . . . mov esp,ebp pop ebp ret BubbleSort ENDP

43 Non-Doubleword Local Variables
Local variables can be different sizes 8-bit: assigned to next available byte 16-bit: assigned to next even (word) boundary 32-bit: assigned to next doubleword boundary Be very careful – you can save space but it can add complexity and make code difficult to maintain and understand Generally not worth the hassle

44 LEA Instruction LEA returns offsets of direct and indirect operands
OFFSET operator only returns constant offsets LEA required when obtaining offsets of stack parameters and local variables (anything that isn't in the .data segment) Example CopyString PROC, LOCAL count:DWORD, temp[20]:BYTE ;mov edi,OFFSET count <<ERROR: invalid operand>> ;mov esi,OFFSET temp <<ERROR: invalid operand>> lea edi,count ; ok lea esi,temp ; ok

45 LEA Example Suppose you have a Local variable at [ebp-8]
And you need the address of that local variable in ESI You cannot use this: mov esi, OFFSET [ebp-8] ; error  Use this instead: lea esi, [ebp-8] ; YAY!  Why? Because OFFSET uses assembly time info and you need lea to access runtime information

46 What is Recursion? The process created when either:
A procedure calls itself A cycle exists: i.e., Procedure A calls procedure B, which in turn calls procedure A Using a graph in which each node is a procedure and each edge is a procedure call, recursion forms a cycle:

47 Calculating a Sum CalcSum PROC cmp ecx,0 ;check counter value
The CalcSum procedure recursively calculates the sum of an array of integers. Receives: ECX = count. Returns: EAX = sum CalcSum PROC cmp ecx, ;check counter value jz L ;quit if zero add eax,ecx ;otherwise, add to sum dec ecx ;decrement counter call CalcSum ;recursive call L2: ret CalcSum ENDP Call# pre 1 2 3 4 5 6 post ecx eax 9 12 14 15

48 Calculating a Factorial
This function calculates the factorial of integer n. A new value of n is saved in each stack frame: int factorial(int n) { if (n == 0) { return(1); } else { return(n*factorial(n-1)); } } /*end factorial*/ When each call instance returns, the product it returns is multiplied by the previous value of n.

49 Calculating a Factorial
Factorial PROC push ebp mov ebp,esp mov eax,[ebp+8] ; get n cmp eax,0 ; n < 0? ja L1 ; yes: continue mov eax,1 ; no: return 1 jmp L2 L1: dec eax push eax ; Factorial(n-1) call Factorial ; Instructions from this point on execute when each ; recursive call returns. mov ebx,[ebp+8] ; get n mul ebx ; eax = eax * ebx L2: pop ebp ; return EAX ret 4 ; clean up stack Factorial ENDP

50 Calculating a Factorial
Suppose we want to calculate 12! This diagram shows the first few stack frames created by recursive calls to Factorial Each recursive call uses 12 bytes of stack space This is NOT how you should use recursion!!! A loop would use less memory, have fewer procedure calls, and run much, much, faster

51 INVOKE Directive The INVOKE directive is a replacement for Intel’s CALL instruction that lets you pass multiple arguments Syntax: INVOKE procedureName [, argumentList] ArgumentList is an optional comma-delimited list of procedure arguments Arguments can be: immediate values integer expressions variable names address and ADDR expressions register names

52 INVOKE Examples .data byteVal BYTE 10 wordVal WORD 1000h .code
; direct operands: INVOKE Sub1,byteVal,wordVal ; address of variable: INVOKE Sub2,ADDR byteVal ; register name, integer expression: INVOKE Sub3,eax,(10 * 20) ; address expression (indirect operand): INVOKE Sub4,[ebx]

53 ADDR Operator .data myWord WORD ? .code INVOKE mySub,ADDR myWord
Returns a near or far pointer to a variable, depending on which memory model your program uses: Small model: returns 16-bit offset Large model: returns 32-bit segment/offset Flat model: returns 32-bit offset YUCK! It is better practice to be EXPLICIT and to not rely on the assembler to "get it right" for you! Many of these directives (INVOKE, ENTER, LEAVE) hide details and inspire mistakes. Example: .data myWord WORD ? .code INVOKE mySub,ADDR myWord

54 PROC Revealed … The PROC directive declares a procedure with an optional list of named parameters. Syntax: label PROC paramList paramList is a list of parameters separated by commas. Each parameter has the following syntax: paramName : type type must either be: one of the standard ASM types (BYTE, SBYTE, WORD, etc.) a pointer (offset/address) to one of these types

55 PROC Directive Alternate format permits parameter list to be on one or more separate lines: label PROC, paramList The parameters can be on the same line . . . param-1:type-1, param-2:type-2, . . ., param-n:type-n Or they can be on separate lines: param-1:type-1, param-2:type-2, . . ., param-n:type-n comma required

56 PROC Example 1 AddTwo PROC, val1:DWORD, val2:DWORD mov eax,val1
The AddTwo procedure receives two integers and returns their sum in EAX AddTwo PROC, val1:DWORD, val2:DWORD mov eax,val1 add eax,val2 ret AddTwo ENDP

57 PROC Example 2 FillArray PROC,
FillArray receives a pointer to an array of bytes, a single byte fill value that will be copied to each element of the array, and the size of the array FillArray PROC, pArray:PTR BYTE, fillVal:BYTE, arraySize:DWORD mov ecx,arraySize mov esi,pArray mov al,fillVal L1: mov [esi],al inc esi loop L1 ret FillArray ENDP

58 PROC Example 3 Swap PROC, pValX:PTR DWORD, pValY:PTR DWORD . . .
Swap ENDP ReadFile PROC, pBuffer:PTR BYTE, LOCAL fileHandle:DWORD . . . ReadFile ENDP

59 PROTO Directive Creates a procedure prototype
Syntax: label PROTO paramList Every procedure called by the INVOKE directive must have a prototype A complete procedure definition can also serve as its own prototype

60 PROTO Directive Standard configuration:
PROTO appears at top of the program listing INVOKE appears in the code segment the procedure implementation occurs later in the program MySub PROTO ;procedure prototype .code INVOKE MySub ;procedure call MySub PROC ;procedure implementation ; Does Stuff … MySub ENDP

61 PROTO Example Prototype for the ArraySum procedure, showing its parameter list: ArraySum PROTO, ptrArray:PTR DWORD, ; points to the array szArray:DWORD ; array size

62 And they all wrote assembly language happily ever after ...
The End And they all wrote assembly language happily ever after ...

Download ppt "Assembly Language Programming Chapter 8"

Similar presentations

Ads by Google