home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / os / msdos / programm / 9154 < prev    next >
Encoding:
Text File  |  1992-09-08  |  3.8 KB  |  112 lines

  1. Newsgroups: comp.os.msdos.programmer
  2. Path: sparky!uunet!uunet.ca!geac!zooid!ross
  3. From: Ross Ridge <ross@zooid.guild.org>
  4. Subject: Re: djgpp 2.2.2 Q's: mouse/svga/assembler/bios
  5. Organization: ZOOiD BBS
  6. Date: Tue, 8 Sep 1992 09:01:32 GMT
  7. Message-ID: <1992Sep8.090132.6246@zooid.guild.org>
  8. References: <25586@castle.ed.ac.uk> <18f73jINN2gr@agate.berkeley.edu>
  9. Lines: 101
  10.  
  11. benrg@ocf.berkeley.edu (Ben Rudiak-Gould) writes:
  12. >o  Register names like %bl and %cx are not used; instead, the word size
  13. >   is indicated by a letter (`b', `w', or `l') appended to the instruction
  14. >   mnemonic.  (This is not done for operations like shrd, where there is
  15. >   no possibility of confusion.)
  16.  
  17. This isn't true, registers names like %bl and %cx are used.  The letter
  18. suffixes are used instead of the BYTE PTR, WORD PTR, etc... constructs
  19. of MASM.  Suffixes are always required, just not when there is an ambiguity.
  20.  
  21. >For example, the following function will multiply two fixed-point
  22. >integers (each with 16 bits of integer and 16 bits of fraction), and
  23. >return their product as a third:
  24. >
  25. >int fixed_mul(int a, int b)
  26. >{
  27. >    asm("movl 8(%ebp),%eax");    /* get operands from stack into %eax */
  28. >    asm("movl 12(%ebp),%edx");    /* and %edx (%ebp is set up for us) */
  29. >    asm("mull %edx");        /* do the multiplication */
  30. >    asm("shrd $16,%edx,%eax");    /* shift off lower 16 bits from */
  31. >                    /* 64-bit result */
  32. >
  33. >}        /* result is in %eax, which is where djgpp wants it */
  34. >
  35. >Note that I deduced the assembly notation from looking at examples, and
  36. >the inline notation by trial and error.  If anybody knows of any official
  37. >documentation for this (in the full gcc package?) let me know.
  38.  
  39. The many uses of the "asm" keyword are all described in the in the
  40. GCC documentation.  You'll also need the to look at the machine
  41. description files for your CPU because it's very machine dependent.
  42.  
  43. I only have GCC 1.37.1 to work with, so things might be different
  44. with GCC 2.2.2, but the way you should define the fixed_mul function
  45. is like this:
  46.  
  47. int 
  48. fixed_mul(int a, int b) {
  49.     int ret;
  50.  
  51.     asm("mull %2;shrd $16,%%edx,%0"
  52. /* %0 is replaced with the first operand, %2 is replaced with
  53.    the third operand.  A semicolon (;) seperated assembly
  54.    statments */
  55.         : "=a" (ret)
  56. /* the constraints on the first operand, an output operand.  The equals
  57.    sign (=) means that this operand is written to, the letter 'a' means that
  58.    this operand must be the EAX register.  In brackets is an lvalue that
  59.    will be loaded with result */
  60.         : "0" (a),
  61. /* the constraints on the second operand, an input operand.  The digit
  62.    '0' means that this operand must be the same the first operand.
  63.    In backets is the value of this operand. */
  64.           "rm" (b)
  65. /* the constraints on the third operand, an input operand.  The letter
  66.    'r' means that it can be a register, the letter 'm' means that it
  67.    can also be a memory reference. */
  68.         : "dx");
  69. /* this means that the EDX register is clobberd by this statement */
  70.  
  71.     return ret;
  72. }
  73.  
  74. This generates the following code, one instruction shorter with my
  75. version of GCC:
  76.  
  77.     pushl %ebp
  78.     movl %esp,%ebp
  79.     movl 8(%ebp),%eax
  80.     mull 12(%ebp)
  81.     shrd $16,%edx,%eax
  82.     leave
  83.     ret
  84.  
  85. or in Intel syntax:
  86.  
  87.     push    ebp
  88.     mov    ebp,esp
  89.     mov    eax,[ebp+0x8]
  90.     mul    [ebp+0xc]
  91.     shrd    eax,edx,0x10
  92.     leave
  93.     ret
  94.  
  95. By using operands and constraints we're able to tell GCC about
  96. all the side effects of the asm statement, and have it load everything
  97. so we don't have to make any assumption on calling conventions.
  98. We can easily put it into a macro so it can be used inline:
  99.  
  100. #define fixed_mul(a, b) ({ int __result;            \
  101.     __asm__("mull %2;shrd $16,%%edx,%0":            \
  102.     "=a" (_t): "0" ((int)(a)), "rm" ((int)(b)): "dx");     \
  103.     __result })
  104.  
  105.                             Ross Ridge
  106.  
  107. -- 
  108. Ross Ridge - The Great HTMU                         l/     //
  109.                                     [OO][oo]
  110. ross@zooid.guild.org                            /()\/()/
  111. uunet.ca!zooid!ross                             db     //
  112.