2010-08-30 89 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