Base64汇编程序填充数组错误"操作数不同的大小"视觉工作室

时间:2015-11-02 22:02:49

标签: visual-studio assembly base64

我试图在Visual Studio中的内联汇编程序中创建一个Base64Encode。

我得到了这个功能

char* Base64Encode(char* data, int len)
{
// Tabelle mit den Zeichen für die Codierung
const char* encodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//
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

2 个答案:

答案 0 :(得分: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中的地址,并将其用作 base 进行内存寻址。您可以选择一个可用的寄存器,如 ECX MOV ,其中包含result的内容。你可以在 ASM 块的顶部用这样的东西做到这一点:

mov ecx, dword ptr [result]

这将在内存位置result获取32位(双字)值,并将其存储在 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 也指出你没有null终止你的字符串(你只为它分配空间),所以在 ASM 块的底部你本应该使用类似的东西:

mov byte ptr[ecx+4], 0

通过上面的更改,您的代码可能类似于:

char* Base64Encode(char* data, int len)
{
    // Tabelle mit den Zeichen für die Codierung
    const char* encodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    //
    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;
}

答案 1 :(得分:0)

也许写mov bl, byte ptr[edi + edx] mov byte ptr[result], bl

就足够了
mov byte ptr[result+4], 0

另外,您实际上并没有进行空终止。 (+1 wg.Null-Terminierung)

from collections import Counter
wordlist = open('so.py', 'r').read().split()
c = Counter(wordlist)
print c

outfile = open('output.txt', 'w')
for word, count in c.items():
    outline = word + ',' + str(count) + '\n'
    outfile.write(outline)