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

时间:2019-06-07 16:22:11

标签: winapi assembly x86 masm

我正试图从Windows api中以masm调用函数。

这是签名:

BOOL WINAPI SetConsoleScreenBufferSize(
  _In_ HANDLE hConsoleOutput,
  _In_ COORD  dwSize
);

COORD结构dwSize按值传递,但是当我尝试调用它时,该函数失败。

看起来像这样:

                .DATA
dwSize          COORD   <20, 20>
                .CODE
                INVOKE  SetConsoleScreenBufferSize,
                        hConsoleOutput,
                        dwSize

这将导致类型错误,并且程序将无法汇编。如果我传递对该结构的引用,则程序将进行汇编,但该功能将无法正常工作。我尝试了其他按值接受结构的函数,但没有成功。

2 个答案:

答案 0 :(得分:3)

Hans是正确的Invoke不了解如何通过值传递结构。 COORD是2个16位值,恰好是DWORD的大小。对于COORD,可以将其强制转换为DWORD作为Invoke的参数。这应该起作用:

                .DATA
dwSize          COORD   <20, 20>
                .CODE
                INVOKE  SetConsoleScreenBufferSize,
                        hConsoleOutput,
                        DWORD PTR [dwSize]

注意:重要的是要理解,由于COORD恰好是DWORD的大小,因此我们可以避免这种情况。对于没有可直接推入堆栈的大小的结构,您必须在堆栈上构建结构,并使用CALL指令而不是Invoke

答案 1 :(得分:2)

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

MSVC(x86)转

const db = new Sequelize(`postgres://localhost:5432/${pkg.name}`, {
  logging: false
});

进入

COORD cord = { 0x666, 0x42 };
SetConsoleScreenBufferSize(0, cord);

33db xor ebx,ebx 66c745986606 mov word ptr [ebp-68h],666h ; store cord.x 66c7459a4200 mov word ptr [ebp-66h],42h ; store cord.y ff7598 push dword ptr [ebp-68h] ; push the whole struct 53 push ebx ; push 0 ff1540104000 call dword ptr [image00400000+0x1040 (00401040)] ; SetConsoleScreenBufferSize 之后但在push之前,堆栈开始于:

call

对寄存器进行异或归零,然后推入这是错过的优化,而不是00000000 00420666 ... 立即数为零。首先存储到堆栈也是因为源代码在禁用优化的情况下进行编译。