我试图在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中的正确字母。如果我注释掉所有的结果行。
当我使用字节ptr时,我在结果数组中什么都没有。
有什么想法吗?
EDIT2:
答案 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)