Today's topics Multi-dimensional arrays Multi-dimensional arrays String processing String processing Macros Macros
2-dimensional arrays Example declaration: Example declaration: Matrix DWORD 5 DUP(3 DUP(?)) ; 15 elements Row major order Row major order Row index first (5 rows, 3 columns) Row index first (5 rows, 3 columns) i.e., 5 rows, 3 elements per row i.e., 5 rows, 3 elements per row In HLLs, reference Matrix[0][2] In HLLs, reference Matrix[0][2] Last element in first row … etc. Last element in first row … etc. In assembly language, it’s just a set of contiguous memory locations In assembly language, it’s just a set of contiguous memory locations
2-dimensional arrays An element’s address is calculated as the base address plus an offset An element’s address is calculated as the base address plus an offset BaseAddress + elementSize * [(row# * elementsPerRow) + column#] Example: Suppose Matrix is at address 20A0h Example: Suppose Matrix is at address 20A0h The address of Matrix[3][1] is The address of Matrix[3][1] is 20A0h + 4 * [(3 * 3) + 1] = 20C8h Size of DWORD Row index Elements per row Column index Base address 4*[(3*3)+1] = 4*[9+1] = 4 * Ah = 28h
Matrix: element addresses (hexadecimal) Matrix A020A420A8 120AC20B020B4 220B820BC20C0 320C420C820CC 420D020D420D8
Local Directive A local variable is created, used, and destroyed within a single procedure A local variable is created, used, and destroyed within a single procedure The LOCAL directive declares a list of local variables The LOCAL directive declares a list of local variables immediately follows the PROC directive immediately follows the PROC directive each variable is assigned a type each variable is assigned a type Syntax: Syntax: LOCAL varlist Example: MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD
Local variables MASM keeps local variables on the system stack MASM keeps local variables on the system stack Generates replacement code for the LOCAL directive Generates replacement code for the LOCAL directive
Sort PROC LOCAL temp:DWORD, SwapFlag:BYTE ; procedure code ret Sort ENDP Sort PROC push ebp mov ebp,esp sub esp,08h ;subtract 8 from ESP ; to create space for local variables ; procedure code pop ebp ret Sort ENDP MASM generates the following code:
LEA Instruction LEA means Load Effective Address LEA means Load Effective Address Returns offsets of both direct and indirect operands. Returns offsets of both direct and indirect operands. LEA is required when obtaining the offset of a local variable or stack parameter. LEA is required when obtaining the offset of a local variable or stack parameter. Example: Example: CopyString PROC LOCAL temp[20]:BYTE, count:DWORD mov edi,OFFSET count; invalid operand mov esi,OFFSET temp; invalid operand lea edi,count; ok lea esi,temp; ok
String primitives A string is an array of BYTE In most cases, an extra byte is needed for the zero-byte terminator MASM has some “string primitives” for manipulating strings byte-by-byte Most important are: lodsb; load string byte stosb; store string byte cld; clear direction flag std; set direction flag There are many others Explore on your own
lodsb and stosb lodsb Moves byte at [esi] into the AL register Increments esi if direction flag is 0 Decrements esi if direction flag is 1 stosb Moves byte in the AL register to memory at [edi] Increments edi if direction flag is 0 Decrements edi if direction flag is 1
cld and std cld Sets direction flag to 0 Causes esi and edi to be incremented by lodsb and stosb Used for moving “forward” through an array std Sets direction flag to 1 Causes esi and edi to be decremented by lodsb and stosb Used for moving “backward” through an array
Demo Program Linked to course website “Resources” page Linked to course website “Resources” page demo6.asm: Shows capitalizing and reversing a string demo6.asm: Shows capitalizing and reversing a string
Questions on … Arrays ? Parameter passing ? System stack ? Stack frame ? Local variables? Strings?
Procedure (summary) Separate, named section of code. May have parameters Calling mechanism Return mechanism During assembly, procedure code is translated once. During execution, control is transferred to the procedure at each call (activation record, etc.). May be called many times. All labels, etc. are local to the activation record.
Macro Separate, named section of code May have parameters Once defined, it can be invoked (called) one or more times. Use name only (don’t use CALL) During assembly, entire macro code is substituted for each call (expansion) Similar to a constant Invisible to the programmer
Defining Macros A macro must be defined before it can be used. Parameters are optional. Each parameter follows the rules for identifiers. Syntax: macroname MACRO [parameter-1, parameter-2,...] statement-list ENDM
Invoking Macros To invoke a macro, just give the name and the arguments (if any). Each argument matches a declared parameter. Each parameter is replaced by its corresponding argument when the macro is expanded. When a macro expands, it generates assembly language source code.
Example macro definition and call mWriteStr MACRO buffer push edx mov edx,OFFSET buffer call WriteString pop edx ENDM.data str1 BYTE "Welcome!",10,13,0 str2 BYTE "Please tell me your name ",0.code... mWriteStr str1 mWriteStr str2... Sets up registers and uses Irvine's library WriteString
Example macro expansion 1push edx 1mov edx,OFFSET str1 1call WriteString 1pop edx The expanded code shows how the str1 argument replaced the parameter named buffer: mWriteStr MACRO buffer push edx mov edx,OFFSET buffer call WriteString pop edx ENDM
Example macro definition and call mReadStr MACRO varName push ecx push edx mov edx,OFFSET varName mov ecx,(SIZEOF varName) – 1; Why? call ReadString pop edx pop ecx ENDM.data firstName BYTE 30 DUP(?).code... mReadStr firstName... The mReadStr macro provides a convenient wrapper around ReadString procedure calls.
A more complex macro seqmacroa, b; Print a sequence moveax,a; from a to b movebx,b test: cmpeax,ebx; if a <= b jgquit; print a and repeat callWriteDec ; otherwise quit inceax jmptest quit: endm
What's the problem? Code is expanded for each call If the macro is called more than once... Duplicate labels Register conflicts
Duplicate labels You can specify that a label is LOCAL MASM handles the problem by appending a unique number to the label Seqmacroa, b LOCALtest ; Print a sequence moveax,a; from a to b movebx,b test: cmpeax,ebx; if a <= b jgquit...
Local variables in macros You can specify that a variable is LOCAL seq macroa, b; Print a sequence LOCALtest ; from a to b LOCALsum.data;; data segment sum DWORD?;; define local var.code;; code segment moveax,a movebx,b test: cmpeax,ebx; if a <= b jgquit...
Parameters Arguments are substituted exactly as entered, so any valid argument can be used. Example calls to seq : seqx,y;memory seqecx,edx;registers seq1,20;literals
Macro vs. Procedure Macros are very convenient, easy to understand Macros actually execute faster than procedures No return address, stack manipulation, etc. Macros are invoked by name Parameters are “in-line” Macro does not have a ret statement (Why?) Why would you ever use a procedure instead of a macro? If the macro is called many times, the assembler produces “ fat code ” Invisible to the programmer Each macro call expands the program code by the length of the macro code
Macro vs. Procedure Use a macro for short code that is called “a few” times. Use a procedure for more complex tasks or code that is called “many” times The terms “few” and “many” are relative to the size of the whole program Is it OK to invoke a macro inside of a loop that executes 1000 times ? Is it OK to invoke a procedure inside of a loop that executes 1000 times ?
Demo Program Linked to course website “Resources” page Linked to course website “Resources” page demo7.asm: shows macros, macro calls, and macro parameters demo7.asm: shows macros, macro calls, and macro parameters
Questions? If learning assembly language does nothing else for you, it makes you appreciate high-level languages.