home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / OTHERUTI / TCPP30-3.ZIP / DOC.ZIP / BASM.DOC < prev    next >
Text File  |  1992-02-18  |  32KB  |  927 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. CONTENTS
  7. ___________________________________________________________________________
  8.  
  9.  
  10.  
  11.  
  12.  
  13. Chapter 1  BASM.DOC                1         Inline assembly and register
  14.   Inline assembly language . . . . 1         variables . . . . . . . . .  7
  15.     BASM . . . . . . . . . . . . . 1         Inline assembly, offsets, and
  16.     Inline syntax  . . . . . . . . 2         size overrides  . . . . . .  7
  17.     Opcodes  . . . . . . . . . . . 3       Using C structure members . .  7
  18.       String instructions  . . . . 5       Using jump instructions and
  19.       Prefixes . . . . . . . . . . 5       labels  . . . . . . . . . . .  8
  20.       Jump instructions  . . . . . 5     Interrupt functions . . . . . .  9
  21.       Assembly directives  . . . . 6     Using low-level practices . . . 10
  22.     Inline assembly references to
  23.     data and functions . . . . . . 6   Index                             13
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.                                      i
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. TABLES
  65. ___________________________________________________________________________
  66.  
  67.  
  68.  
  69.  
  70.  
  71. 1.1: Opcode mnemonics  . . . . . . 4   1.3: Jump instructions  . . . . . .6
  72. 1.2: String instructions . . . . . 5
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.                                     ii
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128. Online document
  129. ___________________________________________________________________________
  130.  
  131.  
  132.  
  133.                                                                    BASM.DOC
  134.  
  135.  
  136.                     This online file tells you how to use the Turbo C++
  137.                     built-in inline assembler (BASM) to include assembly
  138.                     language routines in your C and C++ programs without
  139.                     any need for a separate assembler. Such assembly
  140.                     language routines are called inline assembly, because
  141.                     they are compiled right along with your C routines,
  142.                     rather than being assembled separately, then linked
  143.                     together with modules produced by the C compiler.
  144.  
  145.                     Of course, Turbo C++ also supports traditional mixed-
  146.                     language programming in which your C program calls
  147.                     assembly language routines (or vice-versa) that are
  148.                     separately assembled by TASM (Turbo Assembler), sold
  149.                     separately. In order to interface C and assembly
  150.                     language, you must know how to write 80x86 assembly
  151.                     language routines and how to define segments, data
  152.                     constants, and so on. You also need to be familiar with
  153.                     calling conventions (parameter passing sequences) in C
  154.                     and assembly language, including the pascal parameter
  155.                     passing sequence in C.
  156.  
  157.    Inline assembly  =======================================================
  158.           language
  159.                     Turbo C++ lets you write assembly language code right
  160.                     inside your C and C++ programs. This is known as inline
  161.                     assembly.
  162.  
  163. ------------------  If you don't invoke TASM, Turbo C++ can assemble your
  164.               BASM  inline assembly instructions using the built-in
  165. ------------------  assembler (BASM). This assembler can do everything TASM
  166.                     can do with the following restrictions:
  167.  
  168.                     o It cannot use assembler macros
  169.  
  170.  
  171.  
  172.  
  173.                                    - 1 -
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.                     o It cannot handle 80386 or 80486 instructions
  181.  
  182.                     o It does not permit Ideal mode syntax
  183.  
  184.                     o It allows only a limited set of assembler directives
  185.                       (see page 6)
  186.  
  187.  
  188. ------------------  Of course, you also need to be familiar with the 80x86
  189.      Inline syntax  instruction set and architecture. Even though you're
  190. ------------------  not writing complete assembly language routines, you
  191.                     still need to know how the instructions you're using
  192.                     work, how to use them, and how not to use them.
  193.  
  194.                     Having done all that, you need only use the keyword asm
  195.                     to introduce an inline assembly language instruction.
  196.                     The format is
  197.  
  198.                        asm  opcode  operands ; or newline
  199.  
  200.                     where
  201.  
  202.                     o opcode is a valid 80x86 instruction (Table 1.0 lists
  203.                       all allowable opcodes).
  204.  
  205.                     o operands contains the operand(s) acceptable to the
  206.                       opcode, and can reference C constants, variables, and
  207.                       labels.
  208.  
  209.                     o ; or newline is a semicolon or a new line, either of
  210.                       which signals the end of the asm statement.
  211.  
  212.                     A new asm statement can be placed on the same line,
  213.                     following a semicolon, but no asm statement can
  214.                     continue to the next line.
  215.  
  216.                     To include a number of asm statements, surround them
  217.                     with braces:
  218.  
  219.  The initial brace   asm {
  220. must appear on the      pop ax; pop ds
  221.   same line as the      iret
  222.       asm keyword.   }
  223.  
  224.                     Semicolons are not used to start comments (as they are
  225.                     in TASM). When commenting asm statements, use C-style
  226.                     comments, like this:
  227.  
  228.  
  229.  
  230.  
  231.                                    - 2 -
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.                      asm mov ax,ds;               /* This comment is OK */
  239.                      asm {pop ax; pop ds; iret;}  /* This is legal too */
  240.                      asm push ds                  ;THIS COMMENT IS
  241.                      INVALID!!
  242.  
  243.                     The assembly language portion of the statement is
  244.                     copied straight to the output, embedded in the assembly
  245.                     language that Turbo C++ is generating from your C or
  246.                     C++ instructions. Any C symbols are replaced with ap-
  247.                     propriate assembly language equivalents.
  248.  
  249.                     Because the inline assembly facility is not a complete
  250.                     assembler, it may not accept some assembly language
  251.                     constructs. If this happens, Turbo C++ will issue an
  252.                     error message. You then have two choices. You can
  253.                     simplify your inline assembly language code so that the
  254.                     assembler will accept it, or you can use an external
  255.                     assembler such as TASM. However, TASM might not identi-
  256.                     fy the location of errors, since the original C source
  257.                     line number is lost.
  258.  
  259.                     Each asm statement counts as a C statement. For
  260.                     example,
  261.  
  262.                      myfunc()
  263.                      {
  264.                         int  i;
  265.                         int x;
  266.  
  267.                         if  (i > 0)
  268.                            asm  mov  x,4
  269.                         else
  270.                            i = 7;
  271.                      }
  272.  
  273.                     This construct is a valid C if statement. Note that no
  274.                     semicolon was needed after the mov x,4 instruction. asm
  275.                     statements are the only statements in C that depend on
  276.                     the occurrence of a new line. This is not in keeping
  277.                     with the rest of the C language, but this is the
  278.                     convention adopted by several UNIX-based compilers.
  279.  
  280.                     An assembly statement can be used as an executable
  281.                     statement inside a function, or as an external
  282.                     declaration outside of a function. Assembly statements
  283.                     located outside any function are placed in the data
  284.                     segment, and assembly statements located inside func-
  285.                     tions are placed in the code segment.
  286.  
  287.  
  288.  
  289.                                    - 3 -
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296. ------------------  You can include any of the 80x86 instruction opcodes as
  297.            Opcodes  inline assembly statements. There are four classes of
  298. ------------------  instructions allowed by the Turbo C++ compiler:
  299.  
  300.                     o normal instructions--the regular 80x86 opcode set
  301.  
  302.                     o string instructions--special string-handling codes
  303.  
  304.                     o jump instructions--various jump opcodes
  305.  
  306.                     o assembly directives--data allocation and definition
  307.  
  308.                     Note that all operands are allowed by the compiler,
  309.                     even if they are erroneous or disallowed by the
  310.                     assembler. The exact format of the operands is not
  311.                     enforced by the compiler.
  312.  
  313.  
  314.                     -------------------------------------------------------
  315.  
  316. Opcode mnemonics    aaa            fclex          fldenv         fstenv
  317.                     aad            fcom           fldl2e         fstp
  318.                     aam            fcomp          fldl2t         fstsw
  319.                     aas            fcompp         fldlg2         fsub
  320.                     adc            fdecstp**      fldln2         fsubp
  321.   This table lists  add            fdisi          fldpi          fsubr
  322.         the opcode  and            fdiv           fldz           fsubrp
  323. mnemonics that can  bound          fdivp          fmul           ftst
  324.  be used in inline  call           fdivr          fmulp          fwait
  325.         assembler.  cbw            fdivrp         fnclex         fxam
  326.                     clc            feni           fndisi         fxch
  327.                     cld            ffree**        fneni          fxtract
  328. Inline assembly in  cli            fiadd          fninit         fyl2x
  329.  routines that use  cmc            ficom          fnop           fyl2xp1
  330.     floating-point  cmp            ficomp         fnsave         hlt
  331.  emulation doesn't  cwd            fidiv          fnstcw         idiv
  332.        support the  daa            fidivr         fnstenv        imul
  333.     opcodes marked  das            fild           fnstsw         in
  334.           with **.  dec            fimul          fpatan         inc
  335.                     div            fincstp**      fprem          int
  336.                     enter          finit          fptan          into
  337.                     f2xm1          fist           frndint        iret
  338.                     fabs           fistp          frstor         lahf
  339.                     fadd           fisub          fsave          lds
  340.                     faddp          fisubr         fscale         lea
  341.                     fbld           fld            fsqrt          leave
  342.                     fbstp          fld1           fst            les
  343.                     fchs           fldcw          fstcw          lsl
  344.  
  345.  
  346.  
  347.                                    - 4 -
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.                     mul            or             ret            stc
  355.                     neg            out            rol            std
  356.                     nop            pop            ror            sti
  357.                     not            popa           sahf           sub
  358.                                    popf           sal            test
  359.                                    push           sar            verr
  360.                                    pusha          sbb            verw
  361.                                    pushf          shl            wait
  362.                                    rcl            shr            xchg
  363.                                    rcr            smsw           xlat
  364.                                                                  xor
  365.                     -------------------------------------------------------
  366.  
  367.  
  368.                     String instructions
  369.                     =======================================================
  370.  
  371.                     In addition to the listed opcodes, the string
  372.                     instructions given in the following table can be used
  373.                     alone or with repeat prefixes.
  374.           String
  375.     instructions    -------------------------------------------------------
  376.                        cmps          insw           movsb          outsw          stos
  377.                        cmpsb         lods           movsw          scas           stosb
  378.                        cmpsw         lodsb          outs           scasb          stosw
  379.                        ins           lodsw          outsb          scasw
  380.                        insb          movs
  381.  
  382.                     -------------------------------------------------------
  383.  
  384.  
  385.                     Prefixes
  386.                     =======================================================
  387.  
  388.                     The following prefixes can be used:
  389.  
  390.                      lock   rep   repe   repne   repnz   repz
  391.  
  392.  
  393.                     Jump instructions
  394.                     =======================================================
  395.  
  396.                     Jump instructions are treated specially. Since a label
  397.                     cannot be included on the instruction itself, jumps
  398.                     must go to C labels (discussed in "Using jump
  399.                     instructions and labels" on page 8). The allowed jump
  400.                     instructions are given in the next table.
  401.  
  402.  
  403.  
  404.                                    - 5 -
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.                     Table 1.3: Jump instructions (continued)_______________
  412.  
  413.             Jump    -------------------------------------------------------
  414.     instructions      ja      jge     jnc      jns     loop
  415.                       jae     jl      jne      jnz     loope
  416.                       jb      jle     jng      jo      loopne
  417.                       jbe     jmp     jnge     jp      loopnz
  418.                       jc      jna     jnl      jpe     loopz
  419.                       jcxz    jnae    jnle     jpo
  420.                       je      jnb     jno      js
  421.                       jg      jnbe    jnp      jz
  422.  
  423.                     -----------------------------------------
  424.  
  425.  
  426.                     Assembly directives
  427.                     =======================================================
  428.  
  429.                     The following assembly directives are allowed in Turbo
  430.                     C++ inline assembly statements:
  431.  
  432.                       db      dd      dw       extrn
  433.  
  434.  
  435. ------------------  You can use C symbols in your asm statements; Turbo C++
  436.    Inline assembly  automatically converts them to appropriate assembly
  437. references to data  language operands and appends underscores onto
  438.      and functions  identifier names. You can use any symbol, including
  439. ------------------  automatic (local) variables, register variables, and
  440.                     function parameters.
  441.  
  442.                     In general, you can use a C symbol in any position
  443.                     where an address operand would be legal. Of course, you
  444.                     can use a register variable wherever a register would
  445.                     be a legal operand.
  446.  
  447.                     If the assembler encounters an identifier while parsing
  448.                     the operands of an inline assembly instruction, it
  449.                     searches for the identifier in the C symbol table. The
  450.                     names of the 80x86 registers are excluded from this
  451.                     search. Either uppercase or lowercase forms of the
  452.                     register names can be used.
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.                                    - 6 -
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.                     Inline assembly and register variables
  470.                     =======================================================
  471.  
  472.                     Inline assembly code can freely use SI or DI as scratch
  473.                     registers. If you use SI or DI in inline assembly code,
  474.                     the compiler won't use these registers for register
  475.                     variables.
  476.  
  477.  
  478.                     Inline assembly, offsets, and size overrides
  479.                     =======================================================
  480.  
  481.                     When programming, you don't need to be concerned with
  482.                     the exact offsets of local variables. Simply using the
  483.                     name will include the correct offsets.
  484.  
  485.                     However, it may be necessary to include appropriate
  486.                     WORD PTR, BYTE PTR, or other size overrides on assembly
  487.                     instruction. A DWORD PTR override is needed on LES or
  488.                     indirect far call instructions.
  489.  
  490.  
  491. ------------------  You can reference structure members in an inline
  492.  Using C structure  assembly statement in the usual fashion (that is,
  493.            members  variable.member). In such a case, you are dealing with
  494. ------------------  a variable, and you can store or retrieve values.
  495.                     However, you can also directly reference the member
  496.                     name (without the variable name) as a form of numeric
  497.                     constant. In this situation, the constant equals the
  498.                     offset (in bytes) from the start of the structure
  499.                     containing that member. Consider the following program
  500.                     fragment:
  501.  
  502.                      struct myStruct {
  503.                         int a_a;
  504.                         int a_b;
  505.                         int a_c;
  506.                      } myA ;
  507.  
  508.                      myfunc()
  509.                      {
  510.                         ...
  511.                         asm  {mov  ax, myA.a_b
  512.                               mov  bx, [di].a_c
  513.                              }
  514.                         ...
  515.                      }
  516.  
  517.  
  518.  
  519.  
  520.                                    - 7 -
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.                     We've declared a structure type named myStruct with
  528.                     three members, a_a, a_b, and a_c; we've also declared a
  529.                     variable myA of type myStruct. The first inline
  530.                     assembly statement moves the value contained in myA.a_b
  531.                     into the register AX. The second moves the value at the
  532.                     address [di] + offset(a_c) into the register BX (it
  533.                     takes the address stored in DI and adds to it the
  534.                     offset of a_c from the start of myStruct). In this
  535.                     sequence, these assembler statements produce the
  536.                     following code:
  537.  
  538.                      mov  ax, DGROUP : myA+2
  539.                      mov  bx, [di+4]
  540.  
  541.                     Why would you even want to do this? If you load a
  542.                     register (such as DI) with the address of a structure
  543.                     of type myStruct, you can use the member names to
  544.                     directly reference the members. The member name
  545.                     actually can be used in any position where a numeric
  546.                     constant is allowed in an assembly statement operand.
  547.  
  548.                     The structure member must be preceded by a dot (.) to
  549.                     signal that a member name, rather than a normal C
  550.                     symbol, is being used. Member names are replaced in the
  551.                     assembly output by the numeric offset of the structure
  552.                     member (the numeric offset of a_c is 4), but no type
  553.                     information is retained. Thus members can be used as
  554.                     compile-time constants in assembly statements.
  555.  
  556.                     However, there is one restriction. If two structures
  557.                     that you are using in inline assembly have the same
  558.                     member name, you must distinguish between them. Insert
  559.                     the structure type (in parentheses) between the dot and
  560.                     the member name, as if it were a cast. For example,
  561.  
  562.                        asm   mov    bx,[di].(struct tm)tm_hour
  563.  
  564.  
  565. ------------------  You can use any of the conditional and unconditional
  566.         Using jump  jump instructions, plus the loop instructions, in
  567.   instructions and  inline assembly. They are only valid inside a function.
  568.             labels  Since no labels can be defined in the asm statements,
  569. ------------------  jump instructions must use C goto labels as the object
  570.                     of the jump. If the label is too far away, the jump
  571.                     will be automatically converted to a long-distance
  572.                     jump. Direct far jumps cannot be generated.
  573.  
  574.  
  575.  
  576.  
  577.  
  578.                                    - 8 -
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.                     In the following code, the jump goes to the C goto
  586.                     label a.
  587.  
  588.                      int     x()
  589.                      {
  590.                      a:                /* This is the goto label "a" */
  591.                         ...
  592.                         asm  jmp  a    /* Goes to label "a" */
  593.                         ...
  594.                      }
  595.  
  596.                     Indirect jumps are also allowed. To use an indirect
  597.                     jump, you can use a register name as the operand of the
  598.                     jump instruction.
  599.  
  600.  
  601.    Interrupt func-  =======================================================
  602.              tions
  603.                     The 80x86 reserves the first 1024 bytes of memory for a
  604.                     set of 256 far pointers--known as interrupt vectors--to
  605.                     special system routines known as interrupt handlers.
  606.                     These routines are called by executing the 80x86
  607.                     instruction
  608.  
  609.                       int  int#
  610.  
  611.                     where int# goes from 0h to FFh. When this happens, the
  612.                     computer saves the code segment (CS), instruction
  613.                     pointer (IP), and status flags, disables the
  614.                     interrupts, then does a far jump to the location
  615.                     pointed to by the corresponding interrupt vector. For
  616.                     example, one interrupt call you're likely to see is
  617.  
  618.                       int  21h
  619.  
  620.                     which calls most DOS routines. But many of the
  621.                     interrupt vectors are unused, which means, of course,
  622.                     that you can write your own interrupt handler and put a
  623.                     far pointer to it into one of the unused interrupt
  624.                     vectors.
  625.  
  626.                     To write an interrupt handler in Turbo C++, you must
  627.                     define the function to be of type interrupt; more
  628.                     specifically, it should look like this:
  629.  
  630.                      void  interrupt myhandler(bp, di, si, ds, es, dx,
  631.  
  632.  
  633.  
  634.  
  635.                                    - 9 -
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.                                                cx, bx, ax, ip, cs, flags,
  643.                      ... );
  644.  
  645.                     As you can see, all the registers are passed as
  646.                     parameters, so you can use and modify them in your code
  647.                     without using the pseudovariables discussed earlier in
  648.                     this online file. You can also pass additional
  649.                     parameters (flags, ...) to the handler; those should be
  650.                     defined appropriately.
  651.  
  652.                     A function of type interrupt will automatically save
  653.                     (in addition to SI, DI, and BP) the registers AX
  654.                     through DX, ES, and DS. These same registers are
  655.                     restored on exit from the interrupt handler.
  656.  
  657.                     Interrupt handlers may use floating-point arithmetic in
  658.                     all memory models. Any interrupt handler code that uses
  659.                     an 80x87 must save the state of the chip on entry and
  660.                     restore it on exit from the handler.
  661.  
  662.                     An interrupt function can modify its parameters.
  663.                     Changing the declared parameters will modify the
  664.                     corresponding register when the interrupt handler
  665.                     returns. This may be useful when you are using an
  666.                     interrupt handler to act as a user service, much like
  667.                     the DOS INT 21 services. Also, note that an interrupt
  668.                     function exits with an IRET (return from interrupt)
  669.                     instruction.
  670.  
  671.                     So, why would you want to write your own interrupt
  672.                     handler? For one thing, that's how most memory-resident
  673.                     routines work. They install themselves as interrupt
  674.                     handlers. That way, whenever some special or periodic
  675.                     action takes place (clock tick, keyboard press, and so
  676.                     on), these routines can intercept the call to the
  677.                     routine handling the interrupt and see what action
  678.                     needs to take place. Having done that, they can then
  679.                     pass control on to the routine that was there.
  680.  
  681.  
  682.    Using low-level  =======================================================
  683.          practices
  684.                     You've already seen a few examples of how to use these
  685.                     different low-level practices in your code; now it's
  686.                     time to look at a few more. Let's start with an
  687.                     interrupt handler that does something harmless but
  688.                     tangible (or, in this case, audible): It beeps whenever
  689.                     it's called.
  690.  
  691.  
  692.  
  693.                                   - 10 -
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.                     First, write the function itself. Here's what it might
  701.                     look like:
  702.  
  703.                      #include        <dos.h>
  704.  
  705.                      void  interrupt  mybeep(unsigned bp, unsigned di,
  706.                      unsigned si,
  707.                                              unsigned ds, unsigned es,
  708.                      unsigned dx,
  709.                                              unsigned cx, unsigned bx,
  710.                      unsigned ax)
  711.                      {
  712.                         int     i, j;
  713.                         char    originalbits, bits;
  714.                         unsigned char   bcount = ax >> 8;
  715.  
  716.                         /* Get the current control port setting */
  717.                         bits = originalbits = inportb(0x61);
  718.  
  719.                         for (i = 0; i <= bcount; i++){
  720.  
  721.                            /* Turn off the speaker for awhile */
  722.                            outportb(0x61, bits & 0xfc);
  723.                            for (j = 0; j <= 100; j++)
  724.                               ;   /* empty statement */
  725.  
  726.                            /* Now turn it on for some more time */
  727.                            outportb(0x61, bits | 2);
  728.                            for (j = 0; j <= 100; j++)
  729.                               ;   /* another empty statement */
  730.                            }
  731.  
  732.                         /* Restore the control port setting */
  733.                         outportb(0x61, originalbits);
  734.                      }
  735.  
  736.                     Next, write a function to install your interrupt
  737.                     handler. Pass it the address of the function and its
  738.                     interrupt number (0 to 255 or 0x00 to 0xFF).
  739.  
  740.                      void  install(void interrupt (*faddr)(), int inum)
  741.                      {
  742.                         setvect(inum, faddr);
  743.                      }
  744.  
  745.                     Finally, call your beep routine to test it out. Here's
  746.                     a function to do just that:
  747.  
  748.  
  749.  
  750.  
  751.                                   - 11 -
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.                      void  testbeep(unsigned char bcount, int inum)
  759.                      {
  760.                         _AH = bcount;
  761.                         geninterrupt(inum);
  762.                      }
  763.  
  764.                     Your main function might look like this:
  765.  
  766.                      main()
  767.                      {
  768.                         char  ch;
  769.  
  770.                         install(mybeep,10);
  771.                         testbeep(3,10);
  772.                         ch = getch();
  773.                      }
  774.  
  775.                     You might also want to preserve the original interrupt
  776.                     vector and restore it when your main program is
  777.                     finished. Use the getvect and setvect functions to do
  778.                     this.
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.                                   - 12 -
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816. INDEX
  817. ___________________________________________________________________________
  818.  
  819.  
  820.  
  821.  
  822.  
  823. A                                       F
  824. asm (keyword) 2                         floating point
  825.   braces and 2                            arithmetic
  826. assembler                                   interrupt functions and 10
  827.   built in 1                            functions
  828. assembly language                         calling
  829.   inline 1                                  in inline assembly code 6
  830.     braces and 2
  831.     C structure members and 7
  832.       restrictions 8                    G
  833.     calling functions 6                 goto statements
  834.     commenting 2                          assembly language and 8
  835.     directives 6
  836.     goto in 8
  837.     jump instructions 5, 8              I
  838.     option (*B) 1                       INT instruction 9
  839.     referencing data in 6               interrupt (keyword) 9
  840.     register variables in 7             interrupts
  841.     semicolons and 3                      beep
  842.     size overrides in 7                     example 11
  843.     syntax 2                              functions
  844.     variable offsets in 7                   example of 10
  845.                                             floating-point arithmetic in 10
  846.                                           handlers
  847. B                                           calling 11
  848. braces                                      installing 11
  849.   asm keyword and 2                         programming 9
  850. built-in assembler 1
  851.  
  852.                                         J
  853. C                                       jump instructions, inline assembly language
  854. command-line compiler                     table 5
  855.   options                                 using 8
  856.     assembly language and 1
  857.     -B (inline assembler code) 1
  858.     inline assembler code  1            L
  859. comments                                labels
  860.   inline assembly language code 2         in inline assembly code 8
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867. Index                                                                    13
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874. M                                       repeat prefix opcodes 5
  875. memory-resident routines 10
  876.  
  877.                                         S
  878. O                                       size overrides in inline assembly
  879. opcodes 3                                 code 7
  880.   defined 2                             software interrupt instruction 9
  881.   mnemonics                             sounds
  882.     table 4                               beep 11
  883.   repeat prefixes 5                     structures
  884. operands (assembly language) 2            members
  885.                                             in inline assembly code 7
  886.                                               restrictions 8
  887. P                                       syntax
  888. prefix opcodes, repeat 5                  inline assembly language 2
  889. programs
  890.   terminate and stay resident
  891.     interrupt handlers and 10           T
  892.                                         terminate and stay resident
  893.                                           programs
  894. R                                         interrupt handlers and 10
  895. referencing data in inline assembly     Turbo Assembler 1
  896.   code 6
  897. registers
  898.   DI                                    V
  899.     assembly language and 7             variables
  900.   SI                                      offsets in inline assembly code 7
  901.     assembly language and 7
  902.   variables
  903.     in inline assembly code 7
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.                                   - 14 -
  926.  
  927.