home *** CD-ROM | disk | FTP | other *** search
- ; I'll be using the extended registers, so ".386" is required here. I'm
- ; using simplified directives here. However, there is no reason why I
- ; can't declare my own segments. I will probably give a sample of that
- ; in a future upload or an appended version of this upload.
- .386
-
- ;-----I'll be accessing extended memory while in protected mode. In that
- ; mode, memory is like one of those long "flat" highways across the
- ; western U.S. deserts. The 32RTM shares the same data selector with
- ; SS, ES, and DS, so addressing variables and other items that require
- ; an offset are seamlessly integrated between modules. Using the "C"
- ; calling convention eliminates the need for the preceding underscores.
- .model flat, c
-
- ;-----The assembler structure which makes it easy to manipulate data between
- ; the C++ module and here
- mystruct struc
- ascii_char db 0
- unsigned_char db 0
- short dw 0
- unsigned_short dw 65535
- long dd 0
- unsigned_long dd 0
- string db 13, 10, "This is the string from the .asm routine", 0
- mystruct ends
-
- ;----- This will be the data segment. It is of course not segmented the
- ; same as in real mode, but is defined that way.
- .data
- str db 10, 13, "This is the value passed by way of the .asm's private stack: $"
- str2 db "This is the address of assembler stack: $"
-
- ;----- Define some default variables for my structure
- struct_1 mystruct <>
-
- ;----- Set up my inner stack. I've used the current location counter to
- ; obtain the address of the end of my stack.
-
- public end_stack
- inner_stack dd 200h dup (0)
- end_stack = $
-
- ;----- I'll save the values of esp, and ebp upon program entry. I'll also
- ; create space to hold the argument (pointer) passed by the C++ module.
- esp_save dd ?
- ebp_save dd ?
-
- struct_ptr dd ?
-
- ;----- Here is the declaration of the section where the code will begin.
- ; Variables can go here as well. Note, that even though it is
- ; certainly possible to (by using an alias descriptor), it's not
- ; really normal, nor keeping with tradition to write to the code
- ; area (modify variables) while operating in protected mode.
- .code
-
- ;----- Since this routine will be "called" from the C++ module, it must of
- ; course be made "public"
- public fill_struct
-
- ;----- all procedures in protected mode are of type "near". Something that
- ; i've noticed when compiling using Power Pack is that "near" actually
- ; has to be declared here. Whereas usually it will default to "near"
- ; here as long as "near" is declared at the end of the procedure.
- fill_struct proc near
-
- ;----- This is the argument that was passed to here from the C++ module
- ARG the_struct:dword
-
- ;----- I have the most success saving and repositioning reference to the
- ; stack using this method. I often prefer to define a separate stack
- ; within my assembler module. This lays the ground-work to do that.
- mov ebp_save, ebp
- mov esp_save, esp
-
- ;----- Since I'm not addressing variables passed on the C++ module's stack,
- ; this line isn't "really" necessary. The argument(s) was already
- ; addressed correctly by the "ARG" directive used above. I'll do this
- ; here, just because it's a good habit
- mov ebp, esp
-
- ;----- Reset stack pointer to point at my stack. Then check the integrity
- ; of the new stack by filling and then dumping it.
- lea edx, end_stack
- mov esp, edx
-
- mov cx, 01fch
- loop_check:
- push eax
- dec cx
- jnz loop_check
-
- mov cx, 01fch
- loop_check_2:
- pop eax
- dec cx
- jnz loop_check_2
-
-
- ;----- This will load the EBX register with the address of the structure
- ; within the C++ module. This also makes it quite convenient to access
- ; character sequences of structured type. I'll also save this argument
- ; just out of habit, so I don't have to worry about finding it on the
- ; stack if I need it later.
- mov ebx, [the_struct]
- mov [struct_ptr], ebx
-
- ;----- The following code will use the offset values from my assembler
- ; routine to load values into the structure within the C++ module.
- ; This is the actual loading of the structure within the C++ module.
- ; I can also, first fill my structure here, with the data I desire,
- ; and then send a copy of that data to the C++ module. I'll do that
- ; with the variable representing an unsigned character. I'll also
- ; use two of the default defined values from my (only) "defined"
- ; structured data of type "mystruct". The two members that are
- ; pre-defined, as "unsigned_short" and "string".
-
- mov [ebx].ascii_char, -'~'
-
- mov [struct_1.unsigned_char], 255
- mov cl, [struct_1.unsigned_char]
- mov [ebx].unsigned_char, cl
-
- mov [ebx].short, -32767
-
- mov cx, [struct_1.unsigned_short]
- mov [ebx].unsigned_short, cx
- mov [ebx].long, -2147483647
- mov [ebx].unsigned_long, 4294967295
-
- ;----- This is the code used to copy our string over to the allocated
- ; array within the C++ module. Note that I've terminated the array
- ; with 0, since I believe that to be what the C++ print function will
- ; look for as a terminator. Also note that although the value in CX
- ; can exceed the actual length of the string from this module, it
- ; -MUST NOT- exceed the size of the allocated array within the C++
- ; module. Also note that even though I'm only moving a byte at a
- ; time here, there is no reason, one cannot move 32 bits at a time.
-
- mov edx, offset struct_1.string
- mov cx, 54
- cld
- repeat:
-
- mov al, [edx]
- mov [ebx].string, al
- inc edx
- inc bx
- dec cx
- cmp cx, 0
- jne repeat
-
- ;----- Now we'll return the saved stack type registers.
- mov esp, esp_save
-
- mov ebp, ebp_save
-
- ret
- fill_struct endp
-
-
- ;----- I use this procedure to get and pass a pointer to my .asm module's
- ; internal stack (the one I created above). Now, all this internal
- ; stack stuff is kind of silly, in the simple way that it's used here.
- ; However, it can prove useful in expanded applications.
- public get_stack_pntr
-
- get_stack_pntr proc near
-
- lea eax, end_stack
-
- ret
- get_stack_pntr endp
-
-
-
- ;----- The following procedure retrieves, converts to ascii decimal, and
- ; outputs the value that was place on this module's internal stack
- ; by the C++ module.
- public print_stack_value
- print_stack_value proc near
-
- push ebp
- mov ebp, esp
- mov [esp_save], esp
-
- mov edx, offset str
- mov ah, 09h
- int 21h
-
- mov edx, offset end_stack - 4 ;backstep four, to point to end of my stack.
- mov esp, edx ;point SP to our stack
- pop edx ;pop from our stack
- add dl, 30h
- mov ah, 02h
- int 21h
- mov dl, 10
- int 21h
- mov dl, 13
- int 21h
-
- mov esp, [esp_save]
- pop ebp
-
- ret
- print_stack_value endp
-
-
-
- ;----- That's all there is to it. Pretty easy don't you think? I haven't
- ; been using the PowerPack's 32RTM all that long, so am not sure of all
- ; the things it's capable of. The "flat" memory addressing and the
- ; DOS string write herein seemed to work just fine. I did a lot of
- ; shuffling of pointers, and everything still came out pretty straight.
- ; Keep in mind, that most of this code has been put together rather
- ; "loosely", as it's meant only to be used as a springboard for those
- ; who might need a little something to get the creative juices flowing.
- ; Now.... let's give Borland a round of applause for their
- ; Power Pack product!
- end
-