C汇编程序代码的实现

时间:2010-08-30 12:40:33

标签: c assembly

我正在尝试在C中重写这个asm代码,但我的asm知识非常糟糕。  


struct
{
 union
 {
  struct{
  WORD  ShiftZ0;
  WORD  ShiftZ1;
  WORD  ShiftZ2;
  WORD  ShiftZ3; };
  struct{
  DWORD ShiftZ01;
  DWORD ShiftZ23; };
 };
  short ShiftZ0Align;
  short ShiftZ1Align;
  short ShiftZ2Align;
  short ShiftZ3Align;
  int   deltaZ0ToNextLine;
  int   deltaZ1ToNextLine;
  void *Palette;
} AsmDrawData;

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void video,int no_dot) { __asm { cmp no_dot,0 je end mov esi,zdata mov edi,video mov ebx,zbuffer mov ecx,AsmDrawData.Palette lp: mov eax,AsmDrawData.ShiftZ01 add ax,[esi] cmp ax,[ebx] jle end_out_byte mov [ebx],ax mov edx,data movzx edx,byte ptr [edx] mov DX_REG,[ecx+edx(COLOR_DEPTH/8)] mov [edi],DX_REG end_out_byte: add edi,(COLOR_DEPTH/8) add ebx,2 add esi,2 inc data dec no_dot jg lp end: } }

这是我写的,但错了:

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot)     {
  for( int i = 0; i < no_dot; i++ ) { 
   if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )
    {
        ((WORD*)zbuffer)[i] = ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0;
        ((WORD*)video)[i]   = ((WORD*)AsmDrawData.Palette)[((BYTE*)data)[i]];
    }
  }
}

我哪里错了? (对不起我非常糟糕的英语)

1 个答案:

答案 0 :(得分:2)

这不是一个真正的答案。这只是一些想法和对函数的重写,因为我理解它有希望更清晰的形式。

我非常怀疑你的问题在于:

 if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )

在此代码中,您将zdata指针从字节转换为指针。这对我来说似乎很奇怪。不过,这个装配似乎做了同样的事情。由于您可能更了解 zdata 字段的填充方式,因此您可以更好地确定它。

这个zbuffer算法似乎是相当标准的,所以即使不试图对这个程序集进行反向工程,你也应该可以很容易地在C中重新实现它。

我重写了这个,。我喜欢保持这种本地化,所以我只是在顶部声明具有正确类型的本地指针(并且还使用C99 stdint名称,因为它们比WORD更便携)。

#include <stdint.h>

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot) {
  uint8_t * zd = zdata;  // Should this be 8 or 16 bit
  uint8_t * dat = data;
  uint16_t * zb = zbuffer;
  uint16_t shz = AsmDrawData.ShiftZ0;
  uint16_t * vid = (uint16_t *)video;

  for( int i = 0; i < no_dot; i++ ) {
    uint16_t X = shz + zd[i];
    if( X >= zb[i] )  // Is this the correct direction of the compare
     {
        zb[i] = zdata[i] + X;  // update the depth
        vid[i] = AsmDrawData.Palette[ dat[i] ]; // update the color
     }
  }
}