1 / 47

Irvine chapter 10

Irvine chapter 10. Structures and macros. A simple point struct used in next program. COORD STRUCT X WORD ? Y WORD ? COORD ENDS;; struct requires end-struct. 3 points initialized to (1,1), (2,2), (3,3). TITLE Loop Through Array (AllPoints.asm)

tambre
Download Presentation

Irvine chapter 10

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Irvine chapter 10 Structures and macros

  2. A simple point struct used in next program COORD STRUCT X WORD ? Y WORD ? COORD ENDS;; struct requires end-struct

  3. 3 points initialized to (1,1), (2,2), (3,3) TITLE Loop Through Array (AllPoints.asm) ; Loop through the array of points and set their ; X and Y values. ; Last update: 11/26/01 INCLUDE Irvine32.inc ;coor is already defined in smallwin referenced by irvine32.inc .data;;;I added a message up here ; Create instances of the COORD structure, ; assigning values to both X and Y: point1 COORD <5,10> point2 COORD <10,20> NumPoints = 3 AllPoints COORD NumPoints DUP(<0,0>);;3 sets of int points .code main PROC mov edi,0 ; array index mov ecx,NumPoints ; loop counter mov ax,1 ; starting X, Y values L1: mov (COORD PTR AllPoints[edi]).X,ax mov (COORD PTR AllPoints[edi]).Y,ax add edi,TYPE COORD inc ax Loop L1 exit main ENDP END main • C:\Masm615>allpoints • just made point #1just made point #2just made point #3

  4. An “employee” typEmployee STRUCT Idnum BYTE 9 DUP(0) Lastname BYTE 30 DUP(0) Years WORD 0 SalaryHistory DWORD 10 DUP(0) typEmployee ENDS

  5. Employee slide 1 TITLE Intro to STRUCT (Struct1.asm) INCLUDE Irvine32.inc typEmployee STRUCT Idnum BYTE 9 DUP(0) Lastname BYTE 30 DUP(0) Years WORD 0 SalaryHistory DWORD 10 DUP(0) typEmployee ENDS .data worker typEmployee <> ; override all fields. Either angle brackets ; or curly braces can be used: person1 typEmployee {"555223333"} person2 typEmployee <"555223333"> ; override only the second field: person3 typEmployee <,"Jones"> ; skip the first three fields, and ; use DUP to initialize the last field: person4 typEmployee <,,,3 DUP(20000)>

  6. Employee slide 2 .code main PROC ; Get the offset of a field within a structure: mov edx,OFFSET typEmployee.SalaryHistory ; The following generates an "undefined identifier" error: ;mov edx,OFFSET Salary ; The TYPE, LENGTH, and SIZE operators can be applied ; to the structure and its fields: mov eax,TYPE typEmployee ; 82 mov eax,SIZE typEmployee mov eax,SIZE worker mov eax,SIZEOF worker mov eax,TYPE typEmployee.SalaryHistory ; 4 mov eax,LENGTH typEmployee.SalaryHistory ; 10 mov eax,SIZE typEmployee.SalaryHistory ; 40 ; The TYPE, LENGTH and SIZE operators can be applied ; to instances of the structure: mov eax,TYPE worker ; 82 mov eax,TYPE worker.Years ; 2 ; Indirect operands require the PTR operator: mov esi,offset worker mov ax,(typEmployee PTR [esi]).Years exit main ENDP END main There is no output from the program but it is a model for building say an array of employees.

  7. Structs can be nested…a rectangle consists of upper left/lower right coords TITLE Nested Structures (Struct2.asm) ; This program shows how to declare nested ; structures, and how to access the members. ; Last update: 8/14/01. INCLUDE Irvine32.inc Rectangle STRUCT UpperLeft COORD <> LowerRight COORD <> Rectangle ENDS .data rect1 Rectangle <> rect2 Rectangle { } rect3 Rectangle { {10,20}, {5,15} } rect4 Rectangle < <10,20>, <5,15> > .code main PROC ; Direct reference to a nested member. mov rect1.UpperLeft.X,30 ; Using an indirect operand, access a ; nested member. mov esi,OFFSET rect1 mov (Rectangle PTR [esi]).UpperLeft.Y, 40 ; Get the offsets of individual members. mov edi,OFFSET rect2.LowerRight mov edi,OFFSET rect2.LowerRight.X exit main ENDP END main

  8. Showtime system time struct & output (I added clrscr) SYSTEMTIME STRUCT wYear WORD ? wMonth WORD ? wDayOfWeek WORD ? wDay WORD ? wHour WORD ? wMinute WORD ? wSecond WORD ? wMilliseconds WORD ? SYSTEMTIME ENDS • I added a bunch of output to the original

  9. The rest of showtime .data sysTime SYSTEMTIME <> XYPos COORD <10,5> consoleHandle DWORD ? colonStr BYTE ":",0 TheTimeIs BYTE "The time is ",0 .code main PROC call clrscr ; Get the standard output handle for the Win32 Console. INVOKE GetStdHandle, STD_OUTPUT_HANDLE mov consoleHandle,eax ; Set the cursor position and get the local time zone. INVOKE SetConsoleCursorPosition, consoleHandle, XYPos INVOKE GetLocalTime,ADDR sysTime mov edx,offset year call writestring movzx eax,sysTime.wYear ; year call WriteDec call crlf mov edx,offset month ; call WriteString movzx eax,sysTime.wMonth ; month call crlf call WriteDec mov edx,offset day ; ":" call WriteString movzx eax,sysTime.wdayofweek ; day call WriteDec call Crlf call Crlf mov edx,OFFSET TheTimeIs ; "The time is " call WriteString movzx eax,sysTime.wHour ; hours call WriteDec mov edx,offset colonStr ; ":" call WriteString movzx eax,sysTime.wMinute ; minutes call WriteDec mov edx,offset colonStr ; ":" call WriteString movzx eax,sysTime.wSecond ; seconds call WriteDec exit main ENDP

  10. A drunkard’s walk C:\Masm615>walk 25,25 24,25 23,25 24,25 24,24 25,24 25,25 24,25 24,26 24,25 23,25 23,26 23,25 23,26 23,27 23,26 23,25 23,24 22,24 21,24 22,24 23,24 23,23 22,23 22,24 21,24 21,25 21,24 20,24 19,24

  11. Main proc for drunkard’s walk INCLUDE Irvine32.inc WalkMax = 30 StartX = 25 StartY = 25 DrunkardWalk STRUCT path COORD WalkMax DUP(<0,0>) pathsUsed WORD 0 DrunkardWalk ENDS DisplayPosition PROTO currX:WORD, currY:WORD .data aWalk DrunkardWalk <> .code main PROC mov esi,offset aWalk call TakeDrunkenWalk exit main ENDP

  12. The take-a-walk proc TakeDrunkenWalk PROC LOCAL currX:WORD, currY:WORD ; ; Take a walk in random directions (north, south, east, ; west). ; Receives: ESI points to a DrunkardWalk structure ; Returns: the structure is initialized with random values ;------------------------------------------------------- pushad ; Point EDI to the array of COORD objects. mov edi,esi add edi,OFFSET DrunkardWalk.path mov ecx,WalkMax ; loop counter mov currX,StartX ; current X-location mov currY,StartY ; current Y-location Again: ; Insert current location in array. mov ax,currX mov (COORD PTR [edi]).X,ax mov ax,currY mov (COORD PTR [edi]).Y,ax INVOKE DisplayPosition, currX, currY;;;this generates output….not shown mov eax,4 ; choose a direction (0-3) call RandomRange .IF eax == 0 ; North inc currY .ELSEIF eax == 1 ; South dec currY .ELSEIF eax == 2 ; West dec currX .ELSE ; East (EAX = 3) inc currX .ENDIF next: add edi,TYPE COORD ; point to next COORD loop Again finish: mov ax,WalkMax ; count the steps taken sub ax,cx mov (DrunkardWalk PTR [esi]).pathsUsed, ax popad ret TakeDrunkenWalk ENDP

  13. A bunch of useful macros • TITLE Useful Macros (Macro2.ASM) • ; This program demonstrates several useful macros: • ; mGotoxy, mWrite, mWriteLn, mWriteStr, mReadStr, • ; and mDumpMem. • ; Last update: 8/17/01. • INCLUDE Irvine32.inc • ;----------------------------------------------------- • mWriteStr MACRO buffer • ; • ; Improved version of mWriteStr that checks for • ; a blank argument. • ;----------------------------------------------------- • IFB <buffer> • ECHO ----------------------------------------- • ECHO * Error: parameter missing in mWriteStr • ECHO * (no code generated) • ECHO ----------------------------------------- • EXITM • ENDIF • push edx • mov edx,OFFSET buffer • call WriteString • pop edx • ENDM

  14. useful macros continued • ;----------------------------------------------------- • mWrite MACRO text • ; • ; No changes to this macro. • ;----------------------------------------------------- • LOCAL string • .data ;; local data • string BYTE text,0 ;; define the string • .code • push edx • mov edx,OFFSET string • call Writestring • pop edx • ENDM • ;----------------------------------------------------- • ; This version supplies a default argument. • mWriteLn MACRO text := < " " > • ;----------------------------------------------------- • mWrite text • call Crlf • ENDM

  15. useful macros continued • ;----------------------------------------------------- • mGotoxyConst MACRO X:REQ, Y:REQ • ; • ; Set the cursor position • ; This version checks the ranges of X and Y. • ; are not used. • ;------------------------------------------------------ • LOCAL ERRS ;; local constant • ERRS = 0 • IF (X LT 0) OR (X GT 79) • ECHO Warning: First argument to mGotoxy (X) is out of range. • ECHO ******************************************************** • ERRS = 1 • ENDIF • IF (Y LT 0) OR (Y GT 24) • ECHO Warning: Second argument to mGotoxy (Y) is out of range. • ECHO ******************************************************** • ERRS = ERRS + 1 • ENDIF • IF ERRS GT 0 ;; if errors found, • EXITM ;; exit the macro • ENDIF • push edx • mov dh,Y • mov dl,X • call Gotoxy • pop edx • ENDM

  16. useful macros continued • ;------------------------------------------------------ • mReadStr MACRO bufferPtr, maxChars • ; • ; Read from standard input into a buffer. • ; EDX cannot be the second argument. • ;------------------------------------------------------ • IFIDNI <maxChars> , <EDX> • ECHO Warning: EDX cannot be second argument to mReadStr. • ECHO *************************************************** • EXITM • ENDIF • push ecx • push edx • mov edx,bufferPtr • mov ecx,maxChars • call ReadString • pop edx • pop ecx • ENDM

  17. useful macros continued • ;--------------------------------------------------- • ShowRegister MACRO regName • LOCAL tempStr • ; • ; Display a register's name and contents. • ;--------------------------------------------------- • .data • tempStr BYTE " &regName=",0 • .code • push eax • ; Display the register name • push edx • mov edx,offset tempStr • call WriteString • pop edx • ; Display the register contents • mov eax,regName • call WriteHex • pop eax • ENDM • .data • message BYTE "Hello there",0 • buffer BYTE 50 DUP(?) • BadYValue TEXTEQU <Warning: Y-coordinate is !> 24> • ShowWarning MACRO message • mWrite "&message" • ENDM

  18. useful macros …a main driver count = 4 sumVal TEXTEQU %5 + count ; sumVal = 9 .code main PROC mGotoxyConst %5 * 10, %3 + 4 ;ShowWarning %BadYValue call Crlf call Crlf ShowRegister ECX mReadStr OFFSET buffer,50 ; ok mov edx,50 ;mReadStr buffer,edx ; generates warning mGotoxyConst 10,20 mWrite "Line one" mWriteLn ; missing argument mWriteLn "Line two" mWrite <"Line three",0dh,0ah> mWriteStr ; missing argument exit main ENDP END main

  19. Run of macro2 (I added clrscr) • ECX=0012FFB0 • Line one • Line two • Line three • C:\Masm615>

  20. Macro redefinition • Macros can be redefined. For example, if you define a macro using • Somemac macro • --- • Endm • All invocations to the macro use the current definition. But if, later, you use the same name again to (re)define the macro, the macro has been redefined and all subsequent invocations will use the new definition.

  21. Another redefinition example INCLUDE Irvine16.inc .code cls macro local skip jmp short skip cls_sub proc near pusha xor cx,cx mov dh,24 mov dl,79 mov bh, 7 xor al,al mov ah,6 int 10h popa ret cls_sub endp cls macro call cls_sub endm skip: cls endm main PROC mov ax,@data mov ds,ax cls exit main ENDP END main

  22. 16 bit exit to DOS macro Exittodos MACRO mov ax,4C00h int 21h ENDM

  23. Toupper macro to_upper MACRO ch LOCAL done cmpch,'a’ jb done cmpch,'z' ;;2 semicolons suppresses this comment in expansion ja done ;but this comment would be displayed sub ch,32 done: ENDM

  24. Generic operation macro doanything MACRO op_code, dest,src op_code dest,src ENDM

  25. SWAP word macro SWAP MACRO operand1, operand2 xchg AX,operand1 xchg AX,operand2 xchg AX,operand1 ENDM

  26. 16 bit GOTOXY Macro GOTOXY MACRO Row, ColumnPUSH AXPUSH BXPUSH DXMOV AH, 02H;;rom bios codeMOV DH, RowMOV DL, ColumnMOV BH, 0;;video pageINT 10H ;;bios intPOP DXPOP BXPOP AXENDM

  27. Recursive macro pushall MACRO reg1, reg2, reg3, reg4, reg5, reg6 IFNB <reg1> ;; If parameter not blank push reg1 ;; push one register and ;; repeat pushall reg2, reg3, reg4, reg5, reg6 ENDIF ENDM ;;example call pushall ax, bx, si, ds pushallcs, es

  28. Substitute operator (&) Substitutes a parameter with the actual argument sort2 MACRO cond, num1, num2 LOCAL done push AX mov AX,num1 cmp AX,num2 j&cond done xchg AX,num2 mov num1,AX done: pop AX ENDM

  29. Literal-text string operator (< >) * Treats the enclosed text as a single string literal rather than separate arguments * Syntax: <text> range_error1 MACRO number,variable,range err_msg&number DB '&variable: out of range',0 range_msg&number DB 'Correct range is &range',0 ENDM • Invoking with range_error1 1,<Assignment mark>,<0 to 25> produces err_msg1 DB 'Assignment mark: out of range',0 range_msg1 DB 'Correct range is 0 to 25',0

  30. Literal-character operator (!) * Treats the character literally without its default meaning * Syntax: !character range_error2 MACRO number,variable,range err_msg&number DB '&variable: out of range - &range',0 ENDM • Invoking with range_error2 3,mark,<can!'!'t be !> 100> produces err_msg3 DB 'mark: out of range - can''t be > 100',0 * Without the ! operator, two single quotes will produce a single quote in the output

  31. Expression Evaluate operator (%) * Expression is evaluated and its value is used to replace the expression itself * Syntax: %expression init_arry MACRO element_size,name,size,init_value name &element_size size DUP (init_value) ENDM • Assuming NUM_STUDENTS EQU 47 NUM_TESTS EQU 7 Invoking with init_arrayWord,marks,%NUM_STUDENTS*NUM_TESTS,-1 produces marks Word 329 DUP (-1)

  32. Literal-character operator (!) * Treats the character literally without its default meaning * Syntax: !character range_error2 MACRO number,variable,range err_msg&number DB '&variable: out of range - &range',0 ENDM • Invoking with range_error2 3,mark,<can!'!'t be !> 100> produces err_msg3 DB 'mark: out of range - can''t be > 100',0 * Without the ! operator, two single quotes will produce a single quote in the output

  33. Generating data for dictionary program using repeat macro, & and % ;will generate data like: ;wd0 byte 20 dup(0) ;wd1 byte 20 dup(0) ;wd2 byte 20 dup(0) include irvine32.inc gen macro val wd&val byte 20 dup(0) endm .data value=0 wct=20 repeat wct gen %value value=value+1 endm .code start proc exit start endp end start

  34. Similar but using for include irvine16.inc .data wordval label dword for ctr,<0,1,2,3,4,5,6,7,8,9> wordval&ctrdwordctr endm ;;generates ;;wordval0 dword 0 ;;etc .code main proc movax,@data movds,ax movecx, 9 mov di,0 up: moveax,wordval[di] call writeint add di,4 call crlf loop up exit main endp end main

  35. And using this with % to add numbers up include irvine16.inc ;;32 bit ok too .data wordval label dword for ctr,<0,1,2,3,4,5,6,7,8,9> wordval&ctr dword ctr endm sum macro c add eax,wordval&c endm addup macro count=0 while count LT 10 sum %count count=count+1 endm endm

  36. continued .code main proc movax,@data movds,ax xoreax,eax addup call writedec exit main endp end main

  37. A program with I/0 similar to wordsort: include irvine16.inc  .data words label byte for ctr,<0,1,2,3,4,5,6,7,8,9> words&ctr byte 10 dup(0) endm prompt byte 0ah,0dh,"enter",0ah,0dh,'$'

  38. getstart & fill macros getstart macro x,c movx,offsetwords&c endm  fill macro count=0 while count LT 5 print prompt getstartedx,%count call readstring count=count+1 endm endm

  39. print print macro x pusha mov ah,9;;DOS print…requires ‘$’ terminator movdx,offset x int 21h popa endm

  40. Show macro show macro count=0 while count LT 5 getstartedx,%count call writestring call crlf count=count+1 endm endm

  41. driver .code main proc movax,@data; or could be 32 bit movds,ax fill show exit main endp end main

  42. Linklist output • C:\Masm615>list • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15

  43. Linked list part1 TITLE Creating a Linked List (List.asm) ; This program shows how the STRUC directive ; and the REPT directive can be combined to ; create a linked list at assembly time. ; Last update: 11/8/02 INCLUDE Irvine32.inc ListNode STRUCT NodeData DWORD ? NextPtr DWORD ? ListNode ENDS TotalNodeCount = 15 NULL = 0 Counter = 0 .data LinkedList LABEL PTR ListNode REPT TotalNodeCount Counter = Counter + 1 ListNode <Counter, ($ + Counter * SIZEOF ListNode)> ENDM ListNode <0,0> ; tail node

  44. Linked list part2 .code main PROC mov esi,OFFSET LinkedList ; Display the integers in the NodeData members. NextNode: ; Check for the tail node. mov eax,(ListNode PTR [esi]).NextPtr cmp eax,NULL je quit ; Display the node data. mov eax,(ListNode PTR [esi]).NodeData call WriteDec call Crlf ; Get pointer to next node. mov esi,(ListNode PTR [esi]).NextPtr jmp NextNode quit: exit main ENDP END main

  45. Linklist2 a linklist on the stack C:\Masm615>linklist2 enter numbers... 999 to quit 34 enter numbers... 999 to quit 56 enter numbers... 999 to quit 333 enter numbers... 999 to quit 12 enter numbers... 999 to quit 90 enter numbers... 999 to quit 609 enter numbers... 999 to quit 45 enter numbers... 999 to quit 32 enter numbers... 999 to quit 665 enter numbers... 999 to quit 435 enter numbers... 999 to quit 354 enter numbers... 999 to quit 09 enter numbers... 999 to quit 54 enter numbers... 999 to quit 999 54 9 354 435 665 32 45 609 90 12 333 56 34 C:\Masm615>

  46. Linklist2…build arbitrary size list (up to stack allocation) ListNode STRUCT NodeData DWORD ? NextPtr DWORD ? ListNode ENDS TotalNodeCount = 15;;;not used NULL = 0 Counter = 0 .data nullval dword 0 prompt byte "enter numbers... 999 to quit",0 ;;;;LinkedList LABEL PTR ListNode ListNode <0,0> ; tail node…not used .code

  47. Linklist2 main main PROC push nullval push nullval;;;this is the tail ptr mov esi,esp;;;current node address more: mov edx,offset prompt call writestring call crlf call readint;;;;;;here is where we get data cmp eax,999 je doneInput mov ebp,esi push ebp ;;;this is the next node ptr push eax;;;this is the data mov esi,esp;;;now this is the address of current node jmp more doneInput: NextNode: ; Check for the tail node. mov eax,(ListNode PTR [esi]).NextPtr cmp eax,NULL je quit ; Display the node data. mov eax,(ListNode PTR [esi]).NodeData call WriteDec call Crlf ; Get pointer to next node. mov esi,(ListNode PTR [esi]).NextPtr jmp NextNode quit: exit main ENDP END main

More Related