C реализация кода на ассемблере - PullRequest
1 голос
/ 30 августа 2010

Я пытаюсь переписать этот asm-код на C, но мои знания 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;</p>

<p>inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void <em>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</em>(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 Ответ

2 голосов
/ 30 августа 2010

Это не настоящий ответ.Это всего лишь некоторые идеи и переписывание функции, как я понимаю, в более понятной форме.

Я очень подозреваю, что ваша проблема была в строке:

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

В этом кодеВы переводите указатель zdata из байта в указатель word .Это кажется странным для меня.Сборка, похоже, сделала то же самое.Поскольку вы, вероятно, знаете больше о том, как заполняется поле zdata , вы, вероятно, можете сделать более точное определение по этому поводу.

Этот алгоритм zbuffer представляется довольно стандартным, поэтому даже без попыток обратного инжинирингаВ этой сборке вы сможете довольно легко перестроить его на C.

Я переписал это,.Мне нравится сохранять это локализованным, поэтому я просто объявляю локальные указатели сверху, которые имеют правильные типы (и также использую имена stdint C99, потому что они более переносимы, чем 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
     }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...