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 -