delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/12/23/16:39:58

From: GAMMELJL AT SLU DOT EDU
Date: Tue, 23 Dec 1997 15:38:09 -0600 (CST)
Subject: assembly language
To: djgpp AT delorie DOT com
Message-id: <01IRIOAUEKSYBL3ECY@SLU.EDU>
Organization: SAINT LOUIS UNIVERSITY St. Louis, MO
MIME-version: 1.0

#define mode4(arg1,arg2) \
__asm__ (                                                          \
   "movl %2, %%eax; mull %3; movl %%edx, %0; movl %%eax, %1"       \
   : "=m" (xL), "=m" (xR)                                          \
   : "g" (i), "g" (j)                                              \
   : "eax", "ebx", "edx");

#define mode5(arg1,arg2) \
__asm__ ("movl %2, %%edx; movl %3, %%eax; divl %4;"                \
         "movl %%edx, %0; movl %%eax, %1"                         \
         : "=m" (remainder), "=m" (result)                         \
         : "rm" (xL), "rm" (xR), "rm" (i)                          \
         : "eax", "ebx", "edx");           

#include <iostream.h>

unsigned int i=0xffffffff,j=0xffffffff; //test is hex equivalent of
                                        //9x9=81, 99x99=9801
                                        //999x999=998001,etc;
                                        //that is FFFFFFFFxFFFFFFFF=
                                        //FFFFFFFE 00000001
                                        //followed by FFFFFFFE 00000006/
                                        //FFFFFFFF=FFFFFFFF remainder 5
unsigned int xL,xR;
unsigned int result,remainder;

int main()                                                         {
  mode4(0,0);
  cout<<hex<<xL<<" "<<xR<<" which should be fffffffe 00000001"<<'\n';
  xR=xR+5;            //added so that div will have non-zero remainder 5
  mode5(0,0);
  cout<<hex<<"result "<<result<<" "<<" remainder "<<remainder<<'\n';
  return 0;
                                                                   }

// A short explanation of the GCC inline assembly facilities used below:
//
// The inline assembly has the following format:
//
//	__asm__ (instructions : outputs : inputs : clobbered registers);
//
// `instructions' are the assembly code as a string, with the following
//		  special features:
//
//		  - multiple instructions are separated by `\n' or `;'
//		  - operands which are registers are written as %%eax
//		  - operands which are inputs or outputs are written
//		    as %n, where `n' is their ordinal number in the
//		    `outputs' and `inputs' section (see below), with
//		    outputs counted first, beginning from %0
//
// Note that the GNU assembler which comes with GCC has a syntax that's
// different from the so-called Intel asm syntax; in particular, the
// dest,src order is reversed, and each instruction has an operand size

// suffix: e.g., `movl' (`l' for `long') means the operands are DWORDs.
//
// `outputs'	  is a list of operands that are used as destinations
//		  where the results are stored; they must be lvalues
// `inputs'	  is a list of operands that are used as source values
//
// Each operand is described by an operand-constraint string followed by the
// C++ expression in parentheses.  The constraints specify to the compiler
// whether the expression comes from a register or memory (or both), what
// data type is the input, etc.  This allows you to give the compiler a lot
// of info about what your code does, so it generates correct and optimal
// code, although it doesn't understand and doesn't parse the assembly code
// itself.  For example, the "g" constraint means any memory, register or
// immediate integer operand, "rm" means register or memory integer operand,
// etc.
//
// Finally, the list of clobbered registers specifies which registered are
// used by the code and should therefore be reloaded.

// This is the original Watcom code:
//
// void mode4(void);
// #pragma aux mode4 = \
//                      "mov EAX,i",         \
//                      "mul j",             \
//                      "mov xL,EDX",        \
//                      "mov xR,EAX",        \
//                                           \
//                      modify [ EAX EBX EDX ];

// This is the original Watcom code:
//
// void mode5(void);
// #pragma aux mode5 = \
//                      "mov EDX,xL",           \
//                      "mov EAX,xR",           \
//                      "div i",                \
//                      "mov remainder,EDX",    \
//                      "mov result,EAX",       \
//                                              \
//                       modify [ EAX EBX EDX ];


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019