Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 如何在x86程序集中按值传递结构_Winapi_Assembly_Struct_X86_Masm - Fatal编程技术网

Winapi 如何在x86程序集中按值传递结构

Winapi 如何在x86程序集中按值传递结构,winapi,assembly,struct,x86,masm,Winapi,Assembly,Struct,X86,Masm,我正在尝试从masm中的windows api调用函数 这是签名: BOOL WINAPI SetConsoleScreenBufferSize( _In_ HANDLE hConsoleOutput, _In_ COORD dwSize ); COORD结构dwSize是按值传递的,但当我尝试调用它时,函数失败 看起来像这样: .DATA dwSize COORD <20, 20> .

我正在尝试从masm中的windows api调用函数

这是签名:

BOOL WINAPI SetConsoleScreenBufferSize(
  _In_ HANDLE hConsoleOutput,
  _In_ COORD  dwSize
);
COORD结构dwSize是按值传递的,但当我尝试调用它时,函数失败

看起来像这样:

                .DATA
dwSize          COORD   <20, 20>
                .CODE
                INVOKE  SetConsoleScreenBufferSize,
                        hConsoleOutput,
                        dwSize
.DATA
dwSize坐标
密码
调用SetConsoleScreenBufferSize,
hConsoleOutput,
dwSize

这会导致类型错误,程序无法汇编。如果我传递对结构的引用,程序将进行汇编,但函数不起作用。我尝试过使用其他函数,这些函数通过值接受结构,但没有成功。

COORD只是两个16位数字组合在一起,并作为正常的32位数字传递

MSVC(x86)匝数

进入

推送
”之后,但在
调用
之前,堆栈以以下内容开始:

00000000 00420666 ...


对寄存器进行异或置零,然后按下该寄存器,这是一个遗漏的优化,而不是立即置零的
push 0
。首先存储到堆栈也是因为源代码是在禁用优化的情况下编译的。

COORD只是两个16位数字打包在一起,并作为正常的32位数字传递

MSVC(x86)匝数

进入

推送
”之后,但在
调用
之前,堆栈以以下内容开始:

00000000 00420666 ...


对寄存器进行异或置零,然后按下该寄存器,这是一个遗漏的优化,而不是立即置零的
push 0
。首先存储到堆栈也是因为源代码是在禁用优化的情况下编译的。

Hans是正确的
Invoke
不知道如何按值传递结构
COORD
是2个16位的值,正好是一个DWORD的大小。在
COORD
的情况下,您可以将其转换为DWORD作为
调用的参数。这应该起作用:

                .DATA
dwSize          COORD   <20, 20>
                .CODE
                INVOKE  SetConsoleScreenBufferSize,
                        hConsoleOutput,
                        DWORD PTR [dwSize]
.DATA
dwSize坐标
密码
调用SetConsoleScreenBufferSize,
hConsoleOutput,
DWORD PTR[dwSize]

注意:重要的是要了解,因为
COORD
恰好是一个DWORD的大小,所以我们可以不受影响。对于没有可以直接推送到堆栈上的大小的结构,您必须在堆栈上构建结构,并使用
CALL
指令,而不是
Invoke

Hans是正确的
Invoke
不理解如何通过值传递结构
COORD
是2个16位的值,正好是一个DWORD的大小。在
COORD
的情况下,您可以将其转换为DWORD作为
调用的参数。这应该起作用:

                .DATA
dwSize          COORD   <20, 20>
                .CODE
                INVOKE  SetConsoleScreenBufferSize,
                        hConsoleOutput,
                        DWORD PTR [dwSize]
.DATA
dwSize坐标
密码
调用SetConsoleScreenBufferSize,
hConsoleOutput,
DWORD PTR[dwSize]

注意:重要的是要了解,因为
COORD
恰好是一个DWORD的大小,所以我们可以不受影响。对于没有可以直接推送到堆栈上的大小的结构,您必须在堆栈上构建结构,并使用
CALL
指令,而不是
Invoke

Invoke宏不知道如何按值传递结构,这是一种C语言约定。如何正确地执行此操作,最好通过查看C编译器生成的反汇编来完成。应该生成类似于MOV eax、dword ptr[dwSize]的内容,现在可以使用eax作为第三个INVOKE参数。INVOKE宏不知道如何按值传递结构,这是一种C语言约定。如何正确地执行此操作,最好通过查看C编译器生成的反汇编来完成。应该产生类似于MOV-eax、dword-ptr[dwSize]的东西,现在您可以使用第三个调用参数eax。这是禁用优化的情况。启用优化会导致编译器将单个32位值(
00420666H
)加载到堆栈内存中。@IInspectable它可能取决于编译时是否知道该值以及调用后对COORD结构所做的操作。它不取决于编译时是否知道该值。重要的是结构布局,这在编译时是已知的。这是禁用优化的情况。启用优化会导致编译器将单个32位值(
00420666H
)加载到堆栈内存中。@IInspectable它可能取决于编译时是否知道该值以及调用后对COORD结构所做的操作。它不取决于编译时是否知道该值。重要的是结构布局,这在编译时是已知的。