Today’s topics Parameter passing on the system stack Register indirect and base-indexed addressing modes “Random” numbers Intro to arrays CALL and RET Instructions The CALL instruction calls a procedure Pushes the offset of the next instruction onto the stack copies the address of the called procedure into EIP The RET instruction returns from a procedure pops top of stack into EIP Nested procedure calls Any procedure might call another procedure Return addresses are “stacked” (LIFO) ret instructions must follow the order on the stack One very good reason not to jmp out of a procedure! It is essential that the stack be properly aligned when the RET instruction is executed !! Parameters Definitions: Argument (actual parameter) is a value or reference passed to a procedure. Parameter (formal parameter) is a value or reference received by a procedure Register vs. Stack Parameters Register parameters require dedicating a register to each parameter. Stack parameters make better use of system resources Example: two ways of calling Summation procedure. Method 1 (parameters in registers): Method 2 pushad ;save registers mov ebx,low mov ecx,high call Summation popad ;restore registers (parameters on stack): push low push high call Summation Register vs. Stack Parameters Of course, methods of calling a procedure and passing parameters depend on the procedure implementation … and viceversa. some “setup” is involved (in the calling procedure) some “bookkeeping” is involved (in the called procedure) Parameters in registers require register management Parameters on the system stack require stack management RET Instruction Pops stack into the instruction pointer (EIP) Transfers control to the target address. Syntax: RET RET n Optional operand n causes n to be added to the stack pointer after EIP is assigned a value. Equivalent to popping the return address and n additional bytes off the stack Parameter Classifications An input parameter is data passed by a calling program to a procedure. An output parameter is created by passing the address of a variable when a procedure is called. 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. The “address of” a variable is the same thing as a “pointer to” or a “reference to” the variable. In MASM, we use OFFSET. The procedure does not use any existing data from the variable, but it fills in new contents before it returns. An input-output parameter is the address of a variable which contains input that will be both used and modified by the procedure. The content is modified at the memory address passed by the calling procedure. Stack Frame Also known as an activation record Area of the stack used for a procedure's return address, passed parameters, saved registers, and local variables Created by the following steps: Calling program pushes arguments onto the stack and calls the procedure. The called procedure pushes EBP onto the stack, and sets EBP to ESP. Addressing modes Immediate Direct Register Register indirect Set register to a constant “array” element, using offset in register Indexed Base-indexed Stack Memory area specified and maintained as a stack; stack pointer in register Offset (branch) “goto” address; may be computed Set register to address of global Use register as operand Access memory through address in a register Start address in one register; offset in another, add and access memory Register indirect mode [reg] means “contents of memory at the address in reg ” It’s OK to add a constant (named or literal) Example: mov [edx+12], eax We have used register indirect with esp to reference the value at the top of the system stack NOTE: register indirect is a memory reference There are no memory-memory instructions E.G., mov [edx],[eax] is WRONG! Explicit Access to Stack Parameters A procedure can explicitly access stack parameters using constant offsets from EBP. Example: [ebp + 8] EBP is often called the base pointer or frame pointer because it is (should be) set to the base address of the stack frame. EBP does not change value during the procedure. EBP must be restored to its original value when a procedure returns. Explicit Access to Stack Parameters Remember that the return address is pushed onto the stack after the parameters are pushed. Programmer is responsible for managing the stack. Stack Frame Example .data SYSTEM STACK x DWORD 175 y DWORD 37 Z DWORD ? [ESP] Return .code address main PROC [ESP+4] @z push x push y [ESP+8] 37 push OFFSET z [ESP+12] 175 call SumTwo ... Note: @ means “address of” Stack Frame Example SumTwo PROC push ebp mov ebp,esp mov eax,[ebp+16] ;175 in eax add eax,[ebp+12] ;175+37 = 212 in eax mov ebx,[ebp+8] ;@z in ebx mov [ebx],eax ;store 212 in z pop ebp ret 12 SumTwo ENDP SYSTEM STACK [EBP] old EBP [EBP+4] Return address [EBP+8] @z [EBP+12] 37 [EBP+16] 175 Note: @ means “address of” Trouble-Shooting Tips Save and restore registers when they are modified by a procedure. Except a register that returns a function result Do not pass an immediate value to a procedure that expects a reference parameter. Dereferencing its address will likely cause a general-protection fault. Random Numbers Irvine library has random integer generator "pseudo-random" numbers Randomize procedure Initializes sequence based on system clock (random seed) Call once at the beginning of the program Without Randomize, program gets the same sequence every time it is executed. Limiting random values RandomRange procedure Accepts N > 0 in eax Returns random integer in [0 .. N-1] in eax To generate a random number in [lo .. hi]: Find number of integers possible in [lo .. hi] : range = hi – lo +1 Put range in eax, and call RandomRange Result in eax is in [0 .. range -1] Add lo to eax. RandomRange Example Get a random integer in range [18 .. 31] mov sub inc call add eax,hi eax,lo eax RandomRange eax,lo ;31 ;31-18 = 13 ;14 ;eax in [0..13] ;eax in [18..31] Questions on random numbers? Arrays in MASM Declaration (in data segment) MAX_SIZE = 100 .data list DWORD MAX_SIZE DUP(?) Defines an array of 100 uninitialized 32bit integers Array elements are in contiguous memory Arrays in MASM Declaration MAX_SIZE = 100 .data list DWORD count DWORD DUP(?) What happens (in HLL) if we reference list[100] ? MAX_SIZE 0 Compile-time error What happens in MASM if we go beyond the end of the array? Not predictable Array address calculations Array declaration defines a name for the first element only All other elements are accessed by calculating the actual address General formula for array address calculation: HLLs reference it as list[0] address of list[k] = list + (k * sizeof element) Example: address of 4th element (list [3]) is address of list + (3 * sizeof DWORD) Array references in MASM Several methods indexed base-indexed others Addressing modes Immediate Direct Register Register indirect Set register to a constant “array” element, using offset in register Indexed Base-indexed Stack Memory area specified and maintained as a stack; stack pointer in register Offset (branch) “goto” address; may be computed Set register to address of global Use register as operand Access memory through address in a register Start address in one register; offset in another, add and access memory Indexed addressing Array element, using offset in register Examples: mov mov add mov edi,0 list[edi],eax edi,4 list[edi],ebx ;high-level notation ;list[0] ;see note below ;list[1] This means "add the value in [ ] to address of list " Note: Add 4 because these array elements are DWORD if BYTE, add 1 if WORD, add 2 if QWORD, add 8 etc. Base-indexed addressing Start address in one register; offset in another, then add the registers to access memory Examples: mov mov mov mov mov mov edx,OFFSET list ecx,12 eax,[edx+ecx] ebx,4 eax,[edx+ebx] [edx+ecx],eax Processing Arrays in MASM Example: Display an array of integers Assumptions: Already initialized Number of elements is stored in count Assume global declarations Assume elements are DWORD (32-bit) Many possible solutions Display: version 0.1 (register indirect) display PROC mov esi,OFFSET list ;@list mov ecx,count ;ecx is loop control more: mov call call add loop endMore: display ret ENDP eax,[esi] ;get current element PrintDec Crlf esi,4 ;next element more Display: version 0.2 (indexed) display PROC mov esi,0 ;esi is “index” mov ecx,count ;ecx is loop control more: mov call call add loop endMore: display ret ENDP eax,list[esi] ;get current elt. PrintDec Crlf esi,4 ;next element more Display: version 0.3 (base-indexed) display PROC mov mov mov ebx,OFFSET list ecx,count edx,0 mov call call add loop eax,[ebx+edx] WriteDec Crlf edx,4 more more: endMore: display ret ENDP ;@list ;ecx is loop control ;edx is element ptr Questions?