A virtual device defines its services by using the BeginProc and EndProc macros and the Service or Async_Service options. The macros mark the start and end of the procedure code for the service. The options identify the procedure as a service. The following example shows the definition for the service VSAMPLED_Get_Version:
BeginProc VSAMPLED_Get_Version, Service
mov ax, 030Ah
clc
ret
EndProc VSAMPLED_Get_Version
The Async_Service option is for services that can be called asynchronously, that is, during processing of an interrupt. Asynchronous services must be re-entrant and must not call VMM or virtual device services that are not also asynchronous.
The VMM and standard virtual devices use two calling conventions for their services: register-based and 32-bit C-language based. These calling conventions specify the spelling for the service name, the method for passing parameters and returning values, and the registers to preserve.
For register-based services, the service name should not begin with an underscore (_). All the parameters are passed in registers, and results are returned in registers. Typically, the service preserves all registers it does not explicitly use to return values in.
For C-language-based services, the service name must begin with an underscore (_). All parameters are passed as 32-bit values on the stack. Results (if any) are returned in the EAX register (for 32-bit values), or the EAX and EDX registers (for 64-bit values). The service preserves the EBX, ES, FS, and GS registers as well as the ESI and EDI registers. Only the flags and the EAX, ECX, and EDX registers are modified.