2010-08-30 54 views
1

我想在C中重写这个asm代码,但是我的asm知识非常糟糕。 汇编代码的C实现


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]]; 
    } 
    } 
} 

在哪里我可能是错的? (对不起,我的英语很不好)

+0

如果您还需要粘贴一些示例数据来查看它的错误,它将帮助我们帮助您。 asm代码在循环内有一个'if',它不会出现在你的代码中。 – Dummy00001 2010-08-30 12:45:54

+0

嗯。很奇怪,IF语句不存在于我的问题中 - 在我的问题的代码中。我添加IF,现在有我所有的功能。 – XRazont 2010-08-30 12:58:25

+0

我很抱歉,但我无法显示一些示例数据 - 此代码用于软件渲染。在屏幕上看到一些错误是很容易的,但确切的是 - 很难。我认为Z比较有问题,但我不明白究竟是什么。 – XRazont 2010-08-30 13:02:48

回答

2

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

我强烈怀疑你的问题是与线:

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

在这段代码中,你从字节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 
    } 
    } 
} 
+0

这似乎是正确的。我将zd类型更改为uint16_t(因为zdata实际上是16位Z缓冲区)并且几乎呈现良好。还有一个错误,但我认为我可以修复它。但也许我不能:) – XRazont 2010-08-31 06:30:05

+0

我明白什么是错的。有一些操作出现签名/未签名的混淆。这是正确的: – XRazont 2010-08-31 07:36:20

+0

int16_t * zd =(int16_t *)zdata; uint8_t * dat = data; int16_t * zb =(int16_t *)zbuffer; uint16_t shz = AsmDrawData.ShiftZ0; uint16_t * vid =(uint16_t *)video; [...] int16_t X = shz + zd [i]; [...] zb [i] = X; //更新深度 – XRazont 2010-08-31 07:36:45