Embedding assembly code into C/C++ programs with Watcom C/C++ Why the _asm keyword is not supported. Microsoft and Borland have an _asm keyword that is provided with their code, that allows in-line assembly code to coexist within a C or C++ program. Instead, Watcom uses a #pragma statement to declare a section of assembly code as an auxiliary function. The developer can specify parameters to be passed to this code, which registers they go into, and what registers will be modified. Watcom prefers to use this implementation, and does not support the _asm implementation, for the following reasons: 1. The _asm directive does not tell the code generator what registers have been modified. Therefore, the optimizer cannot exploit maximum speed advantages. Assembly code is usually written for speed-critical sections of a program, and having to save and restore all registers when calling the routine would add program overhead where it is least desirable. Microsoft and Borland turn off optimizations around assembly code, but Watcom finds out which registers are modified to take advantage of maximum optimization. 2. The pragma statement is much more flexible than the _asm statement. It allows you to tell the code generator which registers are modified by the assembly language. It also lets you define 'parameters' to your routine. For example, using a pragma, you could do something like the following: #pragma aux foo= "int 21" parm [ah] [ es bx ]; then foo( 1, &p ); will automatically put the parameters 1 into ah and &p into es:bx. You could also call "foo( 2, &q )" Using the _asm statement, you cannot create generalized inline assembly like this. The examples would have to be coded separately, as follows: ASM( mov ah,1 ) ASM( mov es,seg p ); ASM( mov bx,offset p ); ASM( int 21 ); This would only work if 'p' were a static/extern variable, not an auto. 3. #pragma's are quite easy to create. The following creates a DOS assembly function to set the screen to mode 4: void mode4( void ); #pragma aux mode4 = \ "mov AH,0", \ "mov AL,4", \ "int 10H" \ modify [ AH, AL ]; This function can be called by using "mode4();" anywhere in a program. 4. The code is kept more portable. All of the machine dependent code is kept in callable auxiliary functions, with an explicit interface. This makes the code very easy to port to other processors, which is especially important with the movement toward RISC-based PCs. 5. Pragmas should generally be needed only for specialty processor- specific functions, such as "lidt" or "out". In this case, it is easier to code the instruction once, and call it using a function. At this time, the #pragma auxiliary functions will only take 128 bytes of code at a time. For existing programs that use large amounts of assembly code, it is recommended that this code be put into a separate assembly language file, and be assembled as a function. The optimizer will then expand this code inline, and the developer should notice no difference in performance.