Search code examples
c++arraysassemblyswapmasm

I can't figure out how to print arrays and in turn, I can't figure out how to swap elements in an array


this is the c++ file:

#include <iostream>
using namespace std;

//This is the C prototype of the assembly function, it requires extern"C" to
//show the name is going to be decorated as _test and not the C++ way of
//doing things
extern"C"
{
    //char arrayReverse(char*, int);
    int numChars(char *, int);
    char swapChars(char *, int);
}

int main()
{
    const int SIZE = 7;
    char arr[SIZE] = { 'h', 'e', 'l', 'l', 'o', '1', '2' };

    int val1 = numChars(arr, SIZE);
    cout << "The number of elements is: " << val1 << endl;

    char val2 = swapChars(arr, SIZE);
    cout << "Swapped! " << endl;


    return 0;
}

and my swapChars() file:

    .686
    .model flat
    .code

    _swapChars PROC ; named _test because C automatically prepends an underscode, it is needed to interoperate
        push ebp
        mov ebp,esp ; stack pointer to ebp

        mov ebx,[ebp+8] ; address of first array element
        mov ecx,[ebp+12] ; number of elements in array
        mov ebp,0
        mov eax,0
        mov edx,ebx     ;move first to edx
        add edx, 7      ;last element in the array

    loopMe:
        cmp ebp, ecx        ;comparing iterator to total elements
        jge nextLoopMe
        mov eax, [ebx]      ;move 1st element into tmp eax
        mov ebx, [edx]      ;move last element into first
        mov edx, eax        ;move tmp into last
        push ebx            ;push first element onto stack
        add ebx, 1          ;first + 1
        sub edx, 1          ;last - 1
        add ebp, 1          ;increment
    jmp loopMe




        nextLoopMe:
            mov ebx,[ebp+8] ;find first element again  USING AS FFRAME POINTER AGAIN
            cmp ebx, ecx    ;comparing first element to number of elements
            je allDone

            pop ebx
            add ebx, 1
        jmp nextLoopMe

    allDone:    
        pop ebp
        ret
    _swapChars ENDP

    END 

This is supposed to take the value in arr[0] and swap that with arr[6], arr[1] with arr[5] etc. until the entire array is swapped and then display it. I don't know if any of the code I wrote does anything I want it to, but I'm looking for a way to see what is going on.

Is there a way I can make the asm code print something to the console while iterating through the loop?

Do brackets around the register ( [ebx] ) mean the value for the register?

When in loopMe:, the third line

mov eax, [ebx]

I get an exception "Exception thrown at 0x012125FC in assignment4.exe: 0xC0000005: Access violation reading location 0xCCCCCCCD."

Am I handling the swaps correctly?

Thanks for your time.


Solution

  • You do really need to learn to use the debugger to step thru this. That said, here are some problems I see.

    add edx,7
    

    will point edx past the end of your array. Just like arr[7] would in the C code. It should be add edx,6 to point edx to the last character.

    It's error prone to change ebp in your the middle of your proc and I think you have an error there. You change it's value, but then expect [ebp+8] to reference the same data later.

    You are not modifying the list correctly either. To move a char from one element to another you would do something like:

    mov al, [ebx]     ; copy byte from address ebx to register al
    mov [edx], al     ; copy byte in register al into address edx
    

    The eax register is 32-bits and will copy 4 bytes at a time, not 1.