如何将MASM数组传递给c++函数

How to pass MASM array to c++ function

本文关键字:c++ 函数 数组 MASM      更新时间:2023-10-16

我必须将一个数组从汇编程序传递给c++函数。我终于弄清楚了如何让这两个文件交谈,现在我不知道我应该如何将MASM数组的地址传递给我的c++函数。我尝试在masm中使用ptr和addr调用递归DFS。不知道我做错了什么,因为我只在汇编和c++编程刚刚超过2个月。调用的printSomething函数确实显示,所以我知道两个程序正在通信,然而,当调用DFS时,我得到一个不可解引用的deque迭代器,所以我不确定发生了什么,但它与DFS相关,使用DFS算法中的堆栈"路径"。我尝试使用int *hex_array[]作为DFS函数的参数,但它不喜欢那样。DFS在数组中搜索值1(红色搜索),对每个访问的红色十六进制加上3。如果没有找到路径,它通过从每个"访问过的"十六进制中减去3来重置"访问过的"十六进制,并返回-1。如果找到有效的路径,则返回1。当整个程序使用c++时,DFS可以工作,因此它不是函数本身或堆栈的问题。虽然当我在VS2012中使用调试器时,我注意到每次堆栈= 1时似乎都会失败,并且我将array_index设置为路径顶部,弹出堆栈并使用array_index调用DFS。此时,堆栈为空。但我不明白的是,当整个程序在c++文件中完美工作时,为什么它在这里失败了。我猜这与MASM数组没有被c++函数访问有关??

部分汇编代码:

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

和部分c++代码

#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...  
    }

我的头文件

//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

每个Ferruccio请求的完整DFS代码

#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
    }

如果参数类型匹配可能是个好主意。DFS (color)的第一个参数在MASM PROTO指令中声明为BYTE,但在c++代码中声明为int