How to implement look up table in assembly?

Hi all,

I have a lookup table:

Table:
[-inf,0.3]  -->  100.0
[0.3,0.4]  -->  200.0
[0.4,0.5]  -->  300.0
[0.5,0.6]  -->  400.0
[0.6,+inf] -->  500.0


i.e,
FuncLookUp(-1.0 ) returns 100.0
FuncLookUp(0.35 ) returns 200.0
FuncLookUp(0.51 ) returns 400.0
FuncLookUp(11.0 ) returns 500.0 , etc

in C code, it would look like:

static float table[]={
100.0f, 200.0f, 300.0f, 400.0f, 500.0f
};

static float minValue=0.3;
static float step=0.1;
static float maxValue=0.6;
static float maxRange=maxValue-minValue;
static int tableSize=5;

inline FuncLookUp(float x){

x-=minValue;
if (x<0) return table[0];
if (x>maxRange) return table[tableSize-1];

int idx= fastRound(x/maxRange*tableSize);
return table[idx];
}


How can I write FuncLookUp in assembly?
thank you!


hengck23Asked:
Who is Participating?
 
BeyondWuConnect With a Mentor Commented:
Hi hengck23,
It seems that you are coding for some image processing procedures...
If so, I think you may need to convert float to int, because use int may be more faster than float...
So your C code snippet seems can be modified like this:

static float table[]={
100.0f, 200.0f, 300.0f, 400.0f, 500.0f
};

static int ratio=100;                  // if you want to support 3 point precision, something like 0.602, you should change ratio=1000 or more.
static int minValue=0.3*ratio;
static int step=0.1*ratio;
static int maxValue=0.6*ratio;
static int maxRange=maxValue-minValue;
static int tableSize=5;
int nx = 0;
int idx = 0;

inline float FuncLookUp(float x)
{
      nx = x*ratio;            // convert float to int first
      nx-=minValue;
      if (nx<0) return table[0];
      if (nx>maxRange) return table[tableSize-1];

      idx = nx/step;            //remainder in EDX.
      idx += nx%step ? 1 : 0;

      return table[idx];
}

And then the asm code could be like this, I only tested it in my VC++ IDE, haven't tested into a pure asm environment, but I think it should can work properly.
__declspec(naked) inline float FuncLookUp(float x)
{
      _asm
      {
                  push        ebp
                  mov         ebp,esp
            
                  fild        dword ptr [ratio]
                  fmul        dword ptr [x]
                  call        _ftol
                  sub         eax,dword ptr [minValue]
                  
                  cmp         eax,0
                  jge         smallthan0
                  
                  fld         dword ptr [table]
                  jmp         finish
                  
_ftol:
                   push        ebp
                   mov         ebp,esp
                   add         esp,-12
                   wait
                   fnstcw      word ptr [ebp-2]
                   wait
                   mov         ax,word ptr [ebp-2]
                   or          ah,0Ch
                   mov         word ptr [ebp-4],ax
                   fldcw       word ptr [ebp-4]
                   fistp       qword ptr [ebp-0Ch]
                   fldcw       word ptr [ebp-2]
                   mov         eax,dword ptr [ebp-0Ch]
                   mov         edx,dword ptr [ebp-8]
                   leave
                   ret


smallthan0:
                  cmp         eax,dword ptr [maxRange]
                  jle         largethanmax
                  
                  mov         edx,dword ptr [tableSize]
                  dec                  edx
                  fld         dword ptr [edx*4+table]
            
                  jmp         finish
                  
largethanmax:
                  cdq
                  idiv        dword ptr [step]
                  cmp                  edx, 0
                  jz                  noremainder
                  inc                  eax
noremainder:

                  fld         dword ptr [eax*4+table]
                  
finish:
                  mov         esp,ebp
                  pop         ebp
                  ret
      }
}

call it like this:
main()
{
                float f = FuncLookUp(0.31);
      f = FuncLookUp(0.29);
      f = FuncLookUp(-0.30);
      f = FuncLookUp(0.30);
      f = FuncLookUp(0.50);
      f = FuncLookUp(0.52);
      f = FuncLookUp(0.60);
      f = FuncLookUp(0.62);
      f = FuncLookUp(0.603);
}

Good Luck
0
 
RHenningsgardCommented:
Just out of curiosity, what's it for?
0
 
RHenningsgardCommented:
One great tip, and always an intstructive starting point for the beginning assembly-language writer, is to compile the code in C or Pascal, then debug it in assembly to see what a compiler did with it.  That gets you over lots of little stumbling blocks like how to address the variables and so on.

The main thing with which you'll have to contend, if you are unfamiliar with assembly, is the way the floating-point numbers are represented in binary.  That is a lesson in itself (or actually several lessons, as there are several common, distinctly different floating point representations in common use).

Rob---
0
All Courses

From novice to tech pro — start learning today.