# Assembly Languages Assembly Languages

## Full text

(1)

### Assembly Languages Assembly Languages

Pu-Jen Cheng

Adapted from the slides prepared by Kip Irvine for the book, Assembly Language for Intel-Based Computers, 5th Ed.

(2)











(3)









(4)

## Stack Parameters





### Which is easier?

p

mov esi,OFFSET array mov ecx,LENGTHOF array mov ebx,TYPE array

push LENGTHOF array push OFFSET array call DumpMem

Register-based Method Stack-based Method

(5)

## Stack Frame









### 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.

(6)



### parameters using constant offsets from EBP.

¾ Example: [ebp + 8]







(7)







RET

¾ RET

¾ RET n



(8)

## Stack Frame Example

.data

sum DWORD ? .code

push 6 ; second argument

push 5 ; first argument

call AddTwo ; EAX = sum mov sum,eax ; save the sum

mov ebp,esp .

.

EBP, ESP [EBP + 4]

[EBP + 8]

[EBP + 12]

EBP

(9)

## Passing Arguments by Reference





### elements:

.data

count = 100

array WORD count DUP(?) .code

push OFFSET array push COUNT

call ArrayFill

(10)

## Passing Arguments by Reference (cont.)

ArrayFill PROC push ebp

mov ebp,esp

offset(array)

count [EBP + 8]

[EBP + 12]

ArrayFill can reference an array without knowing the array's name:

mov esi,[ebp+12]

mov ecx,[ebp+8]

. .

EBP

ESI points to the beginning of the array, so it's easy to use a loop to access each array element.

(11)

## Variable Number of Parameters



### For most procedures, the number of parameters is fixed

¾ Every time the procedure is called, the same number of parameter values are passed



### In procedures that can have variable number of parameters

¾ With each procedure call, the number of parameter values passed can be different

 C supports procedures with variable number of parameters such as printf

¾ Easy to support variable number of parameters using the stack method

(12)

## Variable Number of Parameters (cont.)



### variable number of parameter passing:

¾ Parameter count should be one of the should be one of the parameters passed

¾ This count should be the last parameter pushed onto the stack

(13)

## Local Variables





### locB):

MySub PROC push ebp

mov ebp,esp sub esp,8

mov [ebp-4],123456h ; locA

mov [ebp-8],0 ; locB

. .

(14)

## Local Variables (cont.)



### To clear local variables, set ESP to be EBP

MySub PROC push ebp

mov ebp,esp sub esp 8 sub esp,8

mov [ebp-4],123456h ; locA

mov [ebp-8],0 ; locB

. .

mov esp, ebp pop ebp

ret

(15)

## LEA Instruction



### The LEA instruction returns offsets of both direct and indirect operands.

¾ OFFSET operator can only return constant offsets.



### stack parameter or local variable. For example:

CopyString PROC, count:DWORD

LOCAL temp[20]:BYTE

mov edi,OFFSET count ; invalid operand mov esi,OFFSET temp ; invalid operand

lea edi,count ; ok

lea esi,temp ; ok

(16)

## ENTER and LEAVE



### ENTER instruction creates stack frame for a called procedure

¾ 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

¾ Equivalent to:

 MySub PROC

 push ebp

 mov ebp,esp

 sub esp,8

(17)

## LEAVE

MySub PROC push ebp

mov ebp, esp sub esp, 8

The LEAVE instruction

mov esp,ebp pop ebp

The LEAVE instruction is shorthand for:

(18)

## LOCAL Directive





### The LOCAL directive declares a list of local variables

¾ immediately follows the PROC directive

¾ each variable is assigned a type



 LOCAL varlist

### Example:

MySub PROC

LOCAL var1:BYTE, var2:WORD, var3:SDWORD

(19)

## Using LOCAL

LOCAL flagVals[20]:BYTE ; array of bytes

LOCAL pArray:PTR WORD ; pointer to an array

Examples:

myProc PROC, ; procedure

LOCAL t1:BYTE, ; local variables t2:WORD,

t3:DWORD, t4:PTR DWORD

(20)

## LOCAL Example

BubbleSort PROC

LOCAL temp:DWORD, SwapFlag:BYTE . . .

ret

BubbleSort ENDP

MASM generates the following code:

BubbleSort PROC push ebp

mov ebp,esp

mov esp,ebp pop ebp

ret

BubbleSort ENDP

(21)

## LOCAL Example (cont.)

Diagram of the stack frame for the BubbleSort procedure:

EBP EBP

EBP EBP

[EBP - 4]

ESP

temp

SwapFlag [EBP - 8]

(22)

## Non-Doubleword Local Variables





### How created in the stack by LOCAL directive:

¾ 8-bit: assigned to next available byte

¾ 16-bit: assigned to next even (word) boundary

¾ 32 bit: assigned to next doubleword boundary

¾ 32-bit: assigned to next doubleword boundary

(23)

## Local Byte Variable

Example1 PROC

LOCAL var1:BYTE

mov al,var1 ; [EBP - 1]

ret

Example1 ENDP Example1 ENDP

(24)







(25)

## What is Recursion?



### The process created when . . .

¾ A procedure calls itself

¾ Procedure A calls procedure B, which in turn calls procedure A



A

B

D E

C

(26)

## Recursively Calculating a Sum

CalcSum PROC

cmp ecx,0 ; check counter value

jz L2 ; quit if zero

The CalcSum procedure recursively calculates the sum of an array of integers. Receives: ECX = count. Returns: EAX = sum

dec ecx ; decrement counter

call CalcSum ; recursive call L2: ret

CalcSum ENDP

Stack frame:

(27)

## Calculating a Factorial

int function factorial(int n) {

if(n == 0) return 1

5! = 5 * 4! 5 * 24 = 120 recursive calls backing up

This function calculates the factorial of integer n. A new value of n is saved in each stack frame:

return 1;

else

return n * factorial(n-1);

}

4! = 4 * 3!

3! = 3 * 2!

2! = 2 * 1!

1! = 1 * 0!

0! = 1

(base case)

1 * 1 = 1 2 * 1 = 2 3 * 2 = 6 4 * 6 = 24

1 = 1

As each call instance returns, the product it returns is multiplied by the previous value of n.

(28)

## Calculating a Factorial (cont.)

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)

push eax ; Factorial(n 1)

call Factorial

; Instructions from this point on execute when each

; recursive call returns.

ReturnFact:

mov ebx,[ebp+8] ; get n

mul ebx ; eax = eax * ebx

L2: pop ebp ; return EAX

ret 4 ; clean up stack

Factorial ENDP

(29)

## Calculating a Factorial (cont.)

12 n

n-1 ReturnMain

ebp0 11 ReturnFact

ebp1

Suppose we want to calculate 12!

This diagram shows

the first few stack p1

10 ReturnFact

ebp2 9 ReturnFact

ebp3

n-2

n-3

(etc...)

the first few stack frames created by recursive calls to Factorial

Each recursive call

uses 12 bytes of stack space.

(30)

## Reserving Stack Space





### Sub1calls Sub2, Sub2 calls Sub3

Sub1 PROC

1[ ] b

LOCAL array1[50]:DWORD ; 200 bytes

Sub2 PROC

LOCAL array2[80]:WORD ; 160 bytes

Sub3 PROC

LOCAL array3[300]:WORD ; 300 bytes

(31)











(32)

## .MODEL Directive





### Syntax:

 .MODEL memorymodel [,modeloptions]



### memorymodel can be one of the following:

¾ tiny, small, medium, compact, large, huge, or flat



### modeloptions includes the language specifier:

¾ procedure naming scheme

¾ parameter passing conventions

(33)

## Memory Models







### Protected mode supports only the flat model.

Small model: code < 64 KB, data (including stack) <

64 KB. All offsets are 16 bits.

Flat model: single segment for code and data, up to 4 GB. All offsets are 32 bits.

(34)

## Language Specifiers

 C

¾ procedure arguments pushed on stack in reverse order (right to left)

¾ calling program cleans up the stack PASCAL

 PASCAL

¾ procedure arguments pushed in forward order (left to right)

¾ called procedure cleans up the stack

 STDCALL

¾ procedure arguments pushed on stack in reverse order (right to left)

¾ called procedure cleans up the stack

(35)











(36)













(37)

## INVOKE Directive





### Syntax:

 INVOKE procedureName [, argumentList]





### Arguments can be:

¾ immediate values and integer expressions

¾ variable names

¾ register names

(38)

## INVOKE Examples

.data

byteVal BYTE 10 wordVal WORD 1000h .code

; direct operands:

INVOKE Sub1,byteVal,wordVal i

; register name, integer expression:

INVOKE Sub3,eax,(10 * 20)

INVOKE Sub4,[ebx]

(39)

## INVOKE Example

.data

val1 DWORD 12345h val2 DWORD 23456h .code

push val1 push val2 call AddTwo

(40)

• 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

.data

myWord WORD ? .code

• Simple example:

(41)

## Your Turn . . .



### Following is a sample call:

push 14 ; first argument

push 30p ; second argument; g

call Difference ; EAX = 16

Difference PROC push ebp

mov ebp,esp

mov eax,[ebp + 8] ; second argument sub eax,[ebp + 12] ; first argument pop ebp

ret 8

Difference ENDP

(42)

## Passing by Value

 When a procedure argument is passed by value, a copy of a 16-bit or 32-bit integer is pushed on the stack.

Example:

.data

myData WORD 1000h .code

main PROC

INVOKE Sub1, myData

push myData call Sub1

MASM generates the following code:

(43)

## Passing by Reference

 When an argument is passed by reference, its address is pushed on the stack. Example:

.data

myData WORD 1000h .code

main PROC

push OFFSET myData call Sub1

MASM generates the following code:

(44)

## PROC Directive





### Syntax:

label PROC paramList





paramName : type

(45)

## PROC Directive (cont.)



### Alternate format permits parameter list to be on one or more separate lines:

label PROC, paramList

comma required



### 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

(46)

## PROC Examples

FillArray PROC,

pArray:PTR BYTE, fillVal:BYTE arraySize:DWORD

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.

y

mov ecx,arraySize mov esi,pArray mov al,fillVal L1: mov [esi],al

inc esi loop L1 ret

FillArray ENDP

(47)

## PROC Examples (cont.)

Swap PROC,

pValX:PTR DWORD, pValY:PTR DWORD . . .

Swap ENDP

pBuffer:PTR BYTE

LOCAL fileHandle:DWORD . . .

(48)

## PROTO Directive





### Syntax:

¾ label PROTO paramList





(49)

## PROTO Directive

 Standard configuration: PROTO appears at top of the program listing, INVOKE appears in the code segment, and the procedure implementation occurs later in the program:

MySub PROTO ; procedure prototype MySub PROTO ; procedure prototype .code

INVOKE MySub ; procedure call

MySub PROC ; procedure implementation .

.

MySub ENDP

(50)

## PROTO Example



### Prototype for the ArraySum procedure, showing its parameter list:

ArraySum PROTO,

ptrArray:PTR DWORD, ; points to the array szArray:DWORD ; array size

szArray:DWORD ; array size

(51)

## WriteStackFrame Procedure



### Displays contents of current stack frame

¾ Prototype:

WriteStackFrame PROTO,

numParam:DWORD, ; number of passed parameters numLocalVal: DWORD ; number of DWordLocal variables numLocalVal: DWORD, ; number of DWordLocal variables numSavedReg: DWORD ; number of saved registers

(52)

## WriteStackFrame Example

 main PROC

 mov eax, 0EAEAEAEAh

 mov ebx, 0EBEBEBEBh

 INVOKE aProc, 1111h, 2222h

 exit

 main ENDP

 aProc PROC USES eax ebx,

 x: DWORD, y: DWORD

 LOCAL a:DWORD, b:DWORD

 PARAMS = 2

 LOCALS = 2

 SAVED_REGS = 2

 mov a,0AAAAh

 mov b,0BBBBh

 INVOKE WriteStackFrame, PARAMS, LOCALS, SAVED_REGS

(53)

## Parameter Classifications

 An input parameter is data passed by a calling program to a procedure.

¾ The called procedure is not expected to modify the

corresponding parameter variable, and even if it does, the modification is confined to the procedure itself.

A t t t i t d b i i t t

• An input-output parameter is a pointer to a variable containing input that will be both used and modified by the procedure.

• The variable passed by the calling program is modified.

• An output parameter is created by passing a pointer to a variable when a procedure is called.

• The procedure does not use any existing data from the variable, but it fills in a new value before it returns.

(54)

## Example: Exchanging Two Integers

Swap PROC USES eax esi edi,

pValX:PTR DWORD, ; pointer to first integer

The Swap procedure exchanges the values of two 32-bit integers. pValX and pValY do not change values, but the integers they point to are modified.

p , ; p g

pValY:PTR DWORD ; pointer to second integer mov esi,pValX ; get pointers

mov edi,pValY

mov eax,[esi] ; get first integer xchg eax,[edi] ; exchange with second mov [esi],eax ; replace first integer ret

Swap ENDP

(55)

## Trouble-Shooting Tips

 Save and restore registers when they are modified by a procedure.

¾ Except a register that returns a function result

• When using INVOKE, be careful to pass a pointer to the correct data type.

• For example, MASM cannot distinguish between a DWORD argument and a PTR BYTE argument.

• Do not pass an immediate value to a procedure that expects a reference parameter.

• Dereferencing its address will likely cause a general-protection fault.

(56)











(57)

## Multimodule Programs







### All OBJ files belonging to the same program are linked using the link utility into a single EXE file.

¾ This process is called static linking

(58)

 Large programs are easier to write, maintain, and debug when divided into separate source code modules.

• When changing a line of code, only its enclosing module needs to be assembled again. Linking assembled modules requires little time.

• A module can be a container for logically related code and data (think object-oriented here...)

• encapsulation: procedures and variables are automatically hidden in a module unless you declare them public

(59)

## Creating a Multimodule Program



### Here are some basic steps to follow when creating a multimodule program:

¾ Create the main module

¾ Create a separate source code module for each procedure or set of related procedures each procedure or set of related procedures

¾ Create an include file that contains procedure prototypes for external procedures (ones that are called between modules)

¾ Use the INCLUDE directive to make your procedure prototypes available to each module

(60)

## Example: ArraySum Program

Summation Program (main)

Clrscr PromptForIntegers ArraySum DisplaySum

WriteString

Each of the four white rectangles will become a module.

(61)

## Sample Program output

Enter a signed integer: -25 Enter a signed integer: 36 Enter a signed integer: 42

The sum of the integers is: +53

(62)

## INCLUDE File

INCLUDE Irvine32.inc

PromptForIntegers PROTO,

ptrPrompt:PTR BYTE, ; prompt string

The sum.inc file contains prototypes for external functions that are not in the Irvine32 library:

ptrArray:PTR DWORD, ; points to the array arraySize:DWORD ; size of the array ArraySum PROTO,

ptrArray:PTR DWORD, ; points to the array count:DWORD ; size of the array DisplaySum PROTO,

ptrPrompt:PTR BYTE, ; prompt string theSum:DWORD ; sum of the array

(63)

## Main.asm

TITLE Integer Summation Program INCLUDE sum.inc

.code

main PROC

call Clrscr

...

call Crlf

INVOKE ExitProcess,0 main ENDP

END main

(64)

Updating...

## References

Related subjects :