简体   繁体   中英

How to pass MASM array to c++ function

I have to pass an array from an assembly program to a C++ function. I FINALLY figured out how to get the two files talking, now I can't figure out how I am supposed to pass the address of the MASM array to my C++ function. I tried invoking the recursive DFS with both a ptr and addr in masm. Not sure what I'm doing wrong as I've only been programming in assembly and c++ for just over 2 months. The printSomething function called does display so I know the two programs are communicating, however, I get a deque iterator not dereferenceable when the DFS is invoked, so I'm not sure what is going on, but it's related to the DFS using my stack "path" in the DFS algorithm. I tried using int *hex_array[] as an argument in the DFS function but it didn't like that. The DFS searches the array for values of 1 (red search), adding 3 to each visited red hex. If no path is found, it resets the "visited" hexes by subtracting 3 from each "visited hex and returns a -1. It returns a 1 if a valid path is found. The DFS works when the entire program is in C++ so it isn't the function itself or an issue with the stack. Though when I stepped through with my debugger in VS2012 I notice it appears to fail each time the stack = 1 and I set the array_index to the path top, pop the stack and call DFS with array_index. At that point, the stack is empty. But what I don't understand why it is failing here when it worked perfectly when the entire program was in the C++ file. I am guessing it has something to do with the MASM array not getting accessed by the C++ function the way it should???

Part of my assembly code:

INCLUDE Irvine32.inc

printSomething PROTO C ;displays "Goobers" 
DFS PROTO C, color:BYTE, bptr:PTR DWORD, arrayIndex:SDWORD

PDWORD TYPEDEF PTR DWORD

.data

ALIGN SDWORD

bptr PDWORD board
board SDWORD 121 DUP (0)        ;array to hold the hex board

.code

main PROC 

INVOKE printSomething   ;test to see if MASM talking to C++ program

Start:              
    CALL PlaceRed       ;prompt user to place a red stone
    CALL ShowBoard      ;redraw board to show update

    ;check if there is a valid path using C++ DFS 
    ;What needs to be saved...? not aX since DFS will return -1 (no path) or 1(path) in aX from C++ function
    PUSH EDX
    PUSH EBX
    PUSH ECX
    ;INVOKE DFS, 1, ADDR board, 0   ; color red, board pointer, arrayIndex 0
    INVOKE DFS, 1, bptr, 0      ; color red, board pointer, arrayIndex 0
    POP ECX
    POP EBX
    POP EDX
    CMP AX,1            ;if Ax == 1 winning path found
    JNE Continue            ;Ax != 1 no valid path...continue game
    MOV EDX, OFFSET redWins     ; move "Red wins..." to eDx and display
    CALL WriteString    
    JMP END_GAME        

Continue:
    CALL PlaceBlue      ;place a blue stone
    CALL ShowBoard      ;redraw the board

    ;check if there is a valid path using C++ DFS
    PUSH EDX
    PUSH EBX
    PUSH ECX
    ;INVOKE DFS, 2, ADDR board, 0; color blue (2), pointer, arrayIndex 0
    INVOKE DFS, 2, bptr, 0; color blue (2), pointer, arrayIndex 0
    POP ECX
    POP EBX
    POP EDX
    CMP AX,1                ;if Ax == 1 winning path found
    JNE Start               ;Ax != 1 no valid path...continue game
    MOV EDX, OFFSET blueWins ; move "Blue wins..." to eDx and display
    CALL WriteString

END_GAME:

Retn
main ENDP

END main

and part of my C++ code

#include "stdafx.h"
#include<iostream>
#include<stack>
#include "DFSAlgorithm.h"//include definition of class DFSAlgorithm
using namespace std;

//int *board[121];
int adjacency[6];
stack<int> path; //stack to hold the last hex visited

//test printsomething
extern "C" void printSomething(){
    cout<<"goobers";
}

//First call of DFS always starts with array_index ==  0
int DFS(int color, int hex_array[], int array_index){   

//DFS code here...blah blah...  
    }

My header file

//DFSAlgorithm.h 
//Definition of DFSAlgorithm class that does the DFS for the game of HEX
//Member functions are defined in DFSAlgorithm.ccp

#ifndef DFSAlgorithm_H
#define DFSAlgorithm_H
extern "C" void printSomething();
extern "C" int DFS(int color, int hex_array[], int array_index);

#endif

DFS code in it's entirety per Ferruccio request

#include "stdafx.h"
#include<iostream>
#include<stack>
#include "DFSAlgorithm.h"//include definition of class DFSAlgorithm
using namespace std;

int adjacency[6];
//int hex_array[];
//int array_index;
extern stack<int> path; //stack to hold the last hex visited

//test printsomething
extern "C" void printSomething(){
    cout<<"I'm not dead yet...";
}

//First call of DFS always starts with array_index ==  0
extern "C" int DFS(int color, int hex_array[], int array_index){    

    if (hex_array[array_index] == color){ //if hex has an appropriately colored stone

        hex_array[array_index] += 3;    //mark the hex as visited

        path.push(array_index); //push the hex onto the path stack
    }
    if ((color == 1 && array_index % 11 == 10 && hex_array[array_index] == 4) || 
        (color == 2 && array_index / 11 == 10 && hex_array[array_index] == 5)){

    return 1; //winner base case==>reached the other side
    }

//If a visited/unvisited hex has a stone of correct color==> search the adjacent hexes
if ((color == 1 &&  hex_array[array_index] == 4)  || 
    (color == 2  &&  hex_array[array_index] == 5)){

    //get adjacencies
    if(array_index == 0){//top left 2 corner
        adjacency[ 0 ] = 1;
        adjacency[ 1 ] = 11;
        adjacency[ 2 ] = - 1;
        adjacency[ 3 ] = - 1;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
        }

    else if(array_index == 10){//top right three corner
        adjacency[ 0 ] = 9;
        adjacency[ 1 ] = 20;
        adjacency[ 2 ] = 21;
        adjacency[ 3 ] = - 1;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
    }

    else if(array_index == 110){//bottom left corner
        adjacency[ 0 ] = 99;
        adjacency[ 1 ] = 100;
        adjacency[ 2 ] = 111;
        adjacency[ 3 ] = - 1;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
    }
    else if(array_index==120){//bottom right corner
        adjacency[ 0 ] = 109;
        adjacency[ 1 ] = 119;
        adjacency[ 2 ] = -1;
        adjacency[ 3 ] = -1;
        adjacency[ 4 ] = -1;
        adjacency[ 5 ] = -1;
    }

    else if(array_index / 11 == 0){//top row minus corners
        adjacency[ 0 ] = array_index - 1;
        adjacency[ 1 ] = array_index + 1;
        adjacency[ 2 ] = array_index + 10;
        adjacency[ 3 ] = array_index + 11;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
    }

    else if(array_index % 11 == 0){//left column minus corners
        adjacency[ 0 ] = array_index - 11;
        adjacency[ 1 ] = array_index + 11;
        adjacency[ 2 ] = array_index - 10;
        adjacency[ 3 ] = array_index + 1;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
    }

    else if (array_index / 11 == 10){//row 10 minus corners
        adjacency[ 0 ]= array_index - 1;
        adjacency[ 1 ]= array_index + 1;
        adjacency[ 2 ]= array_index - 11;
        adjacency[ 3 ]= array_index - 10;
        adjacency[ 4 ]= - 1;
        adjacency[ 5 ]= - 1;
    }

    else if( array_index % 11 == 10){//right column minus corners
        adjacency[ 0 ] = array_index - 11;
        adjacency[ 1 ] = array_index + 11;
        adjacency[ 2 ] = array_index - 1;
        adjacency[ 3 ] = array_index + 10;
        adjacency[ 4 ] = - 1;
        adjacency[ 5 ] = - 1;
    }

    else{//all interior hexes
        adjacency[ 0 ] = array_index - 11;
        adjacency[ 1 ] = array_index + 11;
        adjacency[ 2 ] = array_index - 10;
        adjacency[ 3 ] = array_index + 10;
        adjacency[ 4 ] = array_index - 1;
        adjacency[ 5 ]= array_index + 1;
        }

    /*Initialize adjacentHexes count to zero: if == 0 after all 6 adjacencies are 
    checked it means it is a dead end as there are no unvisited adjacent hexes with 
    the correct color stone*/
    int adjacentHexes = 0;  
        for(int b = 0; b < 6; b++){//traverse adjacency array of the passed in index

            //if one of the adjacent hexes has a red/blue stone
            if((color == 1 && hex_array[adjacency[b]] == color) ||
                (color == 2 && hex_array[adjacency[b]] == color )){ 

                adjacentHexes++;            //increment the adjacentHexes count

                hex_array[adjacency[b]] += 3;   //mark the hex as visited

                path.push(adjacency[b]);        //push visited adjacent hex onto path 

                //recursively call DFS with that adjacent hex index
                return DFS(color, hex_array,adjacency[b]);  

                }
            }
            //If adjacentHexes == 0 ==> dead-end
                if(adjacentHexes == 0 && path.size() > 1){

                    path.pop();//pop the top hex from the stack if stack > 1

                    //recursive call of DFS with the new top red/blue hex
                    return DFS(color, hex_array,path.top());

                    }
                if(adjacentHexes == 0 && path.size() == 1){//back to Row 0/Column 0

                    //make the array_index = the top of the path stack      
                    array_index = path.top();//this is the line causing deque iterator not dereferenceable problems+++++++++++++++++++++++

                    //pop remaining element from the stack so path is now zero
                    path.pop();
                }

    }
        //if checking for a red path and path is empty
        if (color == 1 ){

            //search remaining column 0 hexes for unvisited red hexes 
            for(array_index ; array_index <= 99; ){ 

                //recursively call DFS with next Column 0 hex
                return DFS(color, hex_array, array_index + 11);
                }
        }

        //if checking for a blue path and path is empty
        if (color == 2){

        //search remaining row 0 hexes for unvisted blue hexes
            for(array_index ; array_index <= 9; ){

                //recursively call DFS with next Row 0 hex
                return DFS(color, hex_array, array_index + 1);
                }
            }
            //No path exists reset all visited hexes to unvisited
            for(int a = 0; a < 121; a++){
                if(hex_array[a] >= 4)//if hex has been visited
                    hex_array[a] -= 3;//remove visited designation  
            }

        return -1;//return false as no path exists
    }

It's probably a good idea if the parameter types match up. The first parameter to DFS ( color ) is declared as a BYTE in the MASM PROTO directive, but is an int in the C++ code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM