Меня попросили изменить некоторый код __asm, чтобы он реализовал соглашение о вызовах C ++.Я пытался использовать cdecl, но получаю эту ошибку
Ошибка проверки времени выполнения # 0: значение ESP не было должным образом сохранено при вызове функции.Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах, с указателем функции, объявленным с другим соглашением о вызовах.
Код используется для шифрования строки по одному символу за раз, используя дляпетля.Функция encrypt_1
кодирует символ, проходящий через цикл for в то время.
Я попытался использовать cdecl, присвоив разные значения базовому указателю (ebp
) и указателю стека (esp
) как для цикла for, так и для функции, но я постоянно получаю ошибку проверки времени выполнения # 0, и каждая попытка ее настройки приводит к сбою программы.Я несколько дней думал об этом, может кто-нибудь подсказать мне, где я могу ошибаться?
Тело:
void encrypt_chars (int length, char EKey)
{
char temp_char; // Character temporary store
for (int i = 0; i < length; i++) // Encrypt characters one at a time
{
temp_char = OChars[i]; // Get the next char from Original Chars array
// Each character in the string will be encrypted individually
__asm
{ //
push eax // Stores a backup of the location of eax to be used later
push ecx // Stores a backup of the charcter to be encrypted in the stack for later use
push edx // Stores a backup of the location for the encrypted character in the stack for later use
//
movzx ecx, temp_char // Places the character (8 bits) to be encrypted in the ecx register (32 bits) and replaces any extraneous bits with 0 as they are not being used.
lea eax, EKey // places the Ekey in the eax register for later use. Registers are fast than calling variables?
push ebp
mov ebp, esp
// sub esp, 4
push ecx // Parameter for encrypt1. - Temporary Character
push eax // Parameter for encrypt1. - Address for the key.
call encrypt_1 // Begins the Encryption Function
mov temp_char, dl // Stores the encrypted character in the temp_char variable to be reconstruced later
add esp, 8
pop eax // Restoring eax to previous location before parameter call
pop ecx // Restores Temporary Character location before parameter call
pop edx // Restores the edx register to its original value, ready for the next character
pop ecx // Restores the ecx register to its original value, ready for the next character
pop eax // Restores the eax register to its original value, ready for the next character
mov esp, ebp
pop ebp
// ret
}
EChars[i] = temp_char; // Store encrypted char in the Encrypted Chars array
}
return;
Функция:
__asm
{
encrypt_1:
push ebp //Saves the present value of ebp on the stack for later use
mov ebp, esp //Places the stack pointer where the base pointer is so variables can be stored
mov ecx, [ebp +08h]
mov edx, [ebp +0Ch]
push ecx // Stores the original character on the top of the stack
movzx ecx, byte ptr[eax] // Moves the Ekey (8-bit) into the ecx register (32-bit), changing all extraneous bits to 0 so it can be rotated
add cl, 0x01 // Adds 1 to Ekey
rol cl, 1 // Rotates the binary value of Ekey to the left 6 times for further security
rol cl, 1 // Could have just used "rol cl, 6"
rol cl, 1
rol cl, 1
rol cl, 1
rol cl, 1
mov edx, ecx // Move the encrypted Ekey to edx, freeing the ecx register for the original character to be used later.
mov byte ptr[eax], dl // Move byte pointer to the left side of eax
pop ecx // Retrieves the original character to be encrypted
x1 : rol cl, 1 // Rotate the original character one place to the left , encrypting it
dec edx // Decrease the rotated Ekey by one, acting as a counter to continue decrypting the original character
jnz x1 // Jump back to x1 unless the Ekey = 0, which dictates that the encryption is complete
add ecx, 0x20 // Add 32 bits to the encrypted character, filling the register
mov edx, ecx // Place the encrypted character in the edx register, ready to be returned
mov esp, ebp
pop ebp
//add esp, 8
ret // Return the encrypted character
}
//--- End of Assembly code
}
PS.Извините за некоторые грязные закомментированные строки, я пробовал разные вещи, пытаясь заставить его работать.