如何在 ASM 中创建循环?

How to create a loop in ASM?

我真的很难理解这个交给我的任务,我现在快疯了。

我得到了以下循环的示例:

#include <iostream>     // for cout
using namespace std;

//declare an array of 'marks'.
const int array_size = 5;

int marks [] = {45,56,99,19,21};

int main()
{int index, average, total;

    total = 0;
    for ( index = 0; index < array_size; index++)
    {
        total = total + marks [index];  
    }
    average = total/array_size;

    cout << "\nAverage value = " << average << "\n\n";
    return(0);
}

汇编:

#include <iostream>     // for cout
using namespace std;

const int array_size = 5;

int marks [] = {45,56,99,19,21};    //declare an array of 'marks'.

int main()
{int index, average, total;

    __asm {
        mov   total,0       ;total = 0;

; ************************** This part is the FOR loop *************************                        
        mov   index,0       ;for ( index = 0; index < array_size; index++)
        jmp   checkend
forloop1:   
        mov   eax,index     ;add 1 to index
        add   eax,1
        mov   index,eax

checkend:   
        cmp   index,5       ;check if 5 ('array_size') loops have been done
        jge   endfor1       ;jump if greater than or equal to (remember?)

        mov   ecx,index
        mov   edx,total     ; total =
        add   edx,[ecx*4+marks] ;      total + marks [index];
        mov   total,edx
        jmp   forloop1

; ******************************************************************************

endfor1:    
        mov   eax,total     ;average = total/array_size;
        cdq             ;convert EAX to quadword (uses EDX register)
        mov   ecx,5         ;get array_size as divisor
        idiv  ecx           ;divides EDX:EAX pair by ECX, EAX=answer
        mov   average,eax       ;save answer in variable 'average'
        }               //end of assembly section

        cout << "\nAverage value = " << average << "\n\n";
        return(0);
}

但是,我的问题是:我需要将以下循环转换为程序集,根据给出的示例,执行此操作的最佳方法是什么?我真的很难将 temp_char 变量分配给数组变量。

下面的循环是指 encrypt_chars 函数循环

#define MAXCHARS 6              
#define dollarchar '$'          // string terminator

char OChars[MAXCHARS],
EChars[MAXCHARS],
DChars[MAXCHARS] = "Soon!";    // Global Original, Encrypted, Decrypted character strings

//----------------------------- C++ Functions ----------------------------------------------------------

void get_char(char& a_character)
{
    cin >> a_character;
    while (((a_character < '0') | (a_character > 'z')) && (a_character != dollarchar))
    {
        cout << "Alphanumeric characters only, please try again > ";
        cin >> a_character;
    }
}
//-------------------------------------------------------------------------------------------------------------

void get_original_chars(int& length)
{
    char next_char;
    length = 0;
    get_char(next_char);

    while ((length < MAXCHARS) && (next_char != dollarchar))
    {
        OChars[length++] = next_char;
        get_char(next_char);
    }
}

void encrypt_chars(int length, char EKey)
{
    char temp_char;                         // char temporary store

    for (int i = 0; i < length; i++)        // encrypt characters one at a time
    {
        temp_char = OChars[i];              // temp_char now contains the address values of the individual character
        __asm
        {
                push    eax                 // Save values contained within register to stack
                push    ecx

                movzx   ecx, temp_char
                push    ecx                 // Push argument #2
                lea     eax, EKey
                push    eax                 // Push argument #1
                call    encrypt4
                add     esp, 8              // Clean parameters of stack
                mov     temp_char, al       // Move the temp character into a register    

                pop     ecx
                pop     eax
        }
        EChars[i] = temp_char;              // Store encrypted char in the encrypted chars array
    }
    return;

    // Inputs: register EAX = 32-bit address of Ekey,
    // ECX = the character to be encrypted (in the low 8-bit field, CL).
    // Output: register EAX = the encrypted value of the source character (in the low 8-bit field, AL).

    __asm
    {
    encrypt4:
            push    ebp                 // Set stack
            mov     ebp, esp            // Set up the base pointer

            mov     eax, [ebp + 8]      // Move value of parameter 1 into EAX
            mov     ecx, [ebp + 12]     // Move value of parameter 2 into ECX
            push    edi                 // Used for string and memory array copying
            push    ecx                 // Loop counter for pushing character onto stack

            not     byte ptr[eax]       // Negation
            add     byte ptr[eax], 0x04 // Adds hex 4 to EKey
            movzx   edi, byte ptr[eax]  // Moves value of EKey into EDI using zeroes
            pop     eax                 // Pop the character value from stack
            xor     eax, edi            // XOR character to give encrypted value of source
            pop     edi                 // Pop original address of EDI from the stack

            rol     al, 1               // Rotates the encrypted value of source by 1 bit (left)
            rol     al, 1               // Rotates the encrypted value of source by 1 bit (left) again
            add     al, 0x04            // Adds hex 4 to encrypted value of source

            mov     esp, ebp            // Deallocate values
            pop     ebp                 // Restore the base pointer
            ret
    }

    //--- End of Assembly code
}

int main(void)
{
    int  char_count;        // The number of actual characters entered (upto MAXCHARS limit).
    char EKey;                      // Encryption key.

    cout << "\nPlease enter your Encryption Key (EKey) letter: "; get_char(EKey);

    cout << "\nNow enter upto " << MAXCHARS << " alphanumeric characters:\n";
    get_original_chars(char_count);
    cout << "\n\nOriginal source string = " << OChars << "\tHex = ";
    for (int i = 0; i<char_count; i++) cout << hex << setw(2) << setfill('0') << ((int(OChars[i])) & 0xFF) << "  ";

    encrypt_chars(char_count, EKey);
    cout << "\n\nEncrypted string = " << EChars << "\tHex = ";
    for (int i = 0; i<char_count; i++) cout << ((int(EChars[i])) & 0xFF) << "  ";

    decrypt_chars(char_count, EKey);
    cout << "\n\nDecrypted string = " << DChars << "\tHex = ";
    for (int i = 0; i<char_count; i++) cout << ((int(DChars[i])) & 0xFF) << "  ";

    cout << "\n\nPress a key to end...";
    while (!_kbhit());                                     //hold the screen until a key is pressed
    return (0);   
}

为最佳解释(分步)答案/解决方案提供 cookie!!

编辑:从循环等生成的反汇编代码:

http://pastebin.com/u5MgJ2SW

notice line 32 where it says mov cl,byte ptr [eax+0CC0320h] Unless you can tell me how to convert that into 'normal asm code'

mov cl,byte ptr [eax+0CC0320h]eax此时包含i的值,0CC0320hOChars的地址,即它的开始。所以,"normal"汇编代码如下:

__asm {
    mov eax, i
    mov cl, byte ptr OChars[eax]
    mov temp_char, cl
}