; Listing6-2.asm ; ; A program that demonstrates protocols in MASM. option casemap:none .nolist include aoaTypes.inc include aoaMacros.inc include aoaClasses.inc include aoalib.inc includelib aoalib.lib .list .const ; Program title: align word ttlStr byte "Listing 6-2", 0 protocol pro1 virtual p1A virtual p2A endpr pro1 protocol pro2, inherits( pro1 ) virtual p3A virtual p4A endpr pro2 ; A sample class that uses a protocol. ; It adds one additional function that ; is not part of the protocol. class protoClass b byte ? a byte 64 dup (?) c byte ? d dword ? virtual pcFunc endc protoClass ; A second class that uses the proto123 protocol. protocol pro1a, inherits( pro1 ) override p1A, protoClass2$p1A override p2A, protoClass2$p2A endpr pro1a class protoClass2, inherits(protoClass) e real4 ? supports pro1a virtual pcFunc2 override pcFunc, protoClass2$pcFunc1 endc protoClass2 ; Emit the VMTs for these classes. .const emitVMT protoClass emitVMT protoClass2 emitVMT pro1a .data pc protoClass {} pc2 protoClass2 {} .code ;--------------------------------------------------- ; ; Procedures for the protoClass class: protoClass$create proc push rcx push rdx mov ecx, sizeof protoClass xor edx, edx lea rdi, vmtAdrs(protoClass) call generic$Class$Constructor pop rdx pop rcx ret protoClass$create endp protoClass$pcFunc proc call print byte "Inside protoClass$pcFunc" byte nl, 0 ret protoClass$pcFunc endp ;--------------------------------------------------- ; ; Procedures for the protoClass2 class: protoClass2$create proc push rcx push rdx mov ecx, sizeof protoClass2 xor edx, edx lea rdi, vmtAdrs(protoClass2) call generic$Class$Constructor ; Must initialize the VMT pointer for the ; pro1 protocol: lea rdx, vmtAdrs(pro1a) mov protoClass2@.vmtPtr(pro1a), rdx pop rdx pop rcx ret protoClass2$create endp protoClass2$pcFunc1 proc call print byte "Inside protoClass2$pcFunc1" byte nl, 0 ret protoClass2$pcFunc1 endp protoClass2$pcFunc2 proc call print byte "Inside protoClass2$pcFunc2" byte nl, 0 ret protoClass2$pcFunc2 endp protoClass2$p1A proc call print byte "Inside protoClass2$p1a" byte nl, 0 ret protoClass2$p1A endp protoClass2$p2A proc call print byte "Inside protoClass2$p2a" byte nl, 0 ret protoClass2$p2A endp ;-------------------------------------------------- ; ; Here is the main assembly language function. public asmMain asmMain proc saveRBX textequ <[rbp-8]> saveRSI textequ <[rbp-16]> saveRDI textequ <[rbp-24]> push rbp mov rbp, rsp sub rsp, 128 and rsp, -16 mov saveRBX, rbx mov saveRSI, rsi mov saveRDI, rdi ; Initialize the pc/pc2 class objects: lea rsi, pc call protoClass$create lea rsi, pc2 call protoClass2$create ; Directly call the methods in pc, just to demonstrate ; that they work: call print byte "Calling protoClass.pcFunc", nl, 0 inv protoClass, pcFunc call print byte "Calling protoClass2.pcFunc", nl, 0 inv protoClass2, pcFunc call print byte "Calling protoClass2.pcFunc2", nl, 0 inv protoClass2, pcFunc2 call print byte nl byte "Calling protoClass.p1A/P2A" byte "functions", nl, 0 inv pro1, p1A, rsi, protoClass2@.vmtPtr(pro1a) inv pro1, p2A, rsi, protoClass2@.vmtPtr(pro1a) mov rbx, saveRBX mov rsi, saveRSI mov rdi, saveRDI leave ret ;Returns to caller asmMain endp end