2015-11-02 42 views
2

我试图在Visual Studio中的内联汇编程序中创建一个Base64Encode。Base64汇编程序填充数组错误“操作数大小不同”Visual Studio

我得到这个FUNC

char* Base64Encode(char* data, int len) 
{ 
// Tabelle mit den Zeichen für die Codierung 
const char* encodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 
// 
char* result; 


if (len > 0)   // sonst gibt es nichts zu tun ... 
{ 
    int encodedLength = ((len + 2)/3) * 4;  // effektiv die Ganzzahlfassung von ceil(length/3)*4 
    result = new char[encodedLength+1];    // +1 wg. Null-Terminierung 
    _asm 
    {   
     mov esi,data 
     mov edi,encodeTable 

     xor eax, eax 
     // get 3 bytes 
     mov ah, byte ptr[esi] 
     mov al, byte ptr[esi+1] 
     shl eax,16 
     mov ah, byte ptr[esi+2] 

     // 
     mov edx,eax 
     shl eax,6 

     shr edx, 26 
     mov bl, byte ptr[edi + edx]  
     mov [result],bl 

     // 
     mov edx, eax 
     shl eax, 6          

     shr edx, 26 
     mov bl, byte ptr[edi + edx]    
     mov[result+1], bl 

     //manipulate in edx bitset3 
     mov edx, eax 
     shl eax, 6 

     shr edx, 26 
     mov bl, byte ptr[edi + edx] 
     mov[result+2], bl 

     //manipulate in edx bitset4 
     mov edx, eax 
     shl eax, 6 

     shr edx, 26 
     mov bl, byte ptr[edi + edx] 
     mov[result+3], bl 


    } 
} 
else 
{ 
    result = ""; 
} 
return result; 
} 

的编码工作正确的,我在BL总是正确的字母,但输出不工作(结果数组不以字母填写,即时得到的错误,操作数具有不同的大小,我只允许在__asm函数中进行更改)。

有人能帮助我如何填写结果数组与我在BL中获得的字母?如果我注释掉所有结果行,调试总是会向我显示bl中的正确字母。

编辑: enter image description here

我得到什么结果数组时,我使用字节的PTR。

任何想法?

EDIT2:

enter image description here

enter image description here

+0

是什么,通过汇编代码步进建议? http://stackoverflow.com/questions/14905769/step-through-an-assembly-language-program-one-statement-at-a-time –

+0

不知道这是你的意思,在编辑2你看到有一个在BL中,在下一步它应该在结果数组中,但结果数组只是0'/ 0' – Alexxxx

+0

不能这么难做一个base64编码在那__asm :( – Alexxxx

回答

0

也许是足够写byte ptr

mov bl, byte ptr[edi + edx]  
mov byte ptr[result], bl 

而且你实际上并没有空终止。 (+1 wg。Null-Terminierung)

mov byte ptr[result+4], 0 
+0

我用过那个,然后我什么都没有(编辑我的线程)任何想法? – Alexxxx

1

代码中的问题是一个间接问题。定义和在C++代码初始化变量result这样的:

char* result; 
result = new char[encodedLength+1]; 

result是保持一个指针,指向由new返回的字符阵列的存储器位置。 result不是存储数据的内存位置,但包含指向该数据区域的指针。那么你访问它在ASM块这样的:

mov [result],bl 

编译器/汇编(MASM)警告说,有一个操作数不匹配时,它说操作数大小不同。它知道result是32位指针的位置(不是单个字符)。由于result是包含指针的地址,因此上面的代码已将bl的内容移至内存位置result。这具有改变指针(由new返回)而不是result指向的效果。

你需要在这里处理间接。您想要获取存储在result中的地址,并将其作为基地址用于存储器寻址。你可以选择一个可用的寄存器,如ECXMOVresult的内容。你可以做的是像这样的东西在你ASM块的顶部:

mov ecx, dword ptr [result] 

这需要在内存位置result 32位(DWORD)值,并存储在ECX。现在我们具有存储位置到字符缓冲区的开始位置,现在我们可以修改ASM块中result的所有引用,并将其更改为ECX。实例:

mov [result],bl 

将成为:

mov byte ptr [ecx],bl 

mov[result+1], bl 

将成为:

mov byte ptr [ecx+1], bl 

第二个例子被称为base plus displacement (or offset) addressing。该链接还描述了x86上的所有寻址模式。如果您使用的是16位代码(您不知道),那么寄存器选择中会有一些额外的限制,可用于基址和索引。

除了user3144770还指出,你没有空终止您的字符串(只分配给它的空间),所以在你ASM块的底部,你应该就可能使用类似:

mov byte ptr[ecx+4], 0 

与您的代码上面的改变可能看起来像:

char* Base64Encode(char* data, int len) 
{ 
    // Tabelle mit den Zeichen für die Codierung 
    const char* encodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 
    // 
    char* result; 

    if (len > 0)   // sonst gibt es nichts zu tun ... 
    { 
     int encodedLength = ((len + 2)/3) * 4;  // effektiv die Ganzzahlfassung von ceil(length/3)*4 
     result = new char[encodedLength + 1];   // +1 wg. Null-Terminierung 
     _asm 
     { 
      mov esi, data 
      mov edi, encodeTable 

       mov ecx, dword ptr [result] 
       xor eax, eax 
       // get 3 bytes 
       mov ah, byte ptr[esi] 
       mov al, byte ptr[esi + 1] 
       shl eax, 16 
       mov ah, byte ptr[esi + 2] 

       // 
       mov edx, eax 
       shl eax, 6 

       shr edx, 26 
       mov bl, byte ptr[edi + edx] 
       mov byte ptr [ecx], bl 

       // 
       mov edx, eax 
       shl eax, 6 

       shr edx, 26 
       mov bl, byte ptr[edi + edx] 
       mov byte ptr [ecx + edx + 1], bl 

       //manipulate in edx bitset3 
       mov edx, eax 
       shl eax, 6 

       shr edx, 26 
       mov bl, byte ptr[edi + edx] 
       mov byte ptr [ecx + 2], bl 

       //manipulate in edx bitset4 
       mov edx, eax 
       shl eax, 6 

       shr edx, 26 
       mov bl, byte ptr[edi + edx] 
       mov byte ptr [ecx + 3], bl 

       mov byte ptr[ecx + 4], 0 
     } 
    } 
    else 
    { 
     result = ""; 
    } 
    return result; 
}