函数的参数没有正确传递MASM

时间:2017-07-05 15:18:17

标签: assembly x86 masm masm32

我正在学习MASM,但我无法使用这个简单的代码。我没有得到我调用的值,我不知道发生了什么。我试过推2,推2,叫pow。结果相同。 EAX和EDX看起来像垃圾或内存地址。

线程0x1544已退出,代码为-1073741510(0xc000013a)。 线程0xd8已退出,代码为-1073741510(0xc000013a)。 线程0x898已退出,代码为-1073741510(0xc000013a)。 线程0x21c4已退出,代码为-1073741510(0xc000013a)。 程序'[2296] AssemblyTutorial.exe'已退出,代码为-1073741510(0xc000013a)。

这只是意味着我关闭了控制台窗口,但为什么有4个线程?

res

2 个答案:

答案 0 :(得分:2)

是的,cdecl和stdcall之间的区别在于前者是调用者干净的而后者是被调用者干净的。 (另见Raymond Chen's series on calling conventions in Windows

问题是,你的pow程序是而不是遵循stdcall约定,因为它清理堆栈。您需要指定要作为ret指令的一部分弹出的字节数。在这种情况下,那将是ret 8

或者,您可以创建函数cdecl,在这种情况下调用者负责清理堆栈,MASM可以自动生成此代码作为INVOKE指令的一部分。

  

为什么有4个帖子?

Windows出于各种原因启动后台线程。这些都不用担心。如果你进一步研究它们,你可能会发现它们是由线程池工作线程(ntdll.dll中的TppWorkerThread)启动的。

对于它的价值,pow函数可以更有效地编写为:

pow PROC x:DWORD, power:DWORD
    ; Load parameters into registers
    mov  eax, x
    mov  edx, power
    mov  ecx, eax

    ; Decrement 'power' by 1 and bail out if we're done.
    dec  edx
    jz   Finished

    ; The main loop.
CalculatePow:
    imul eax, ecx
    dec  edx
    jnz  CalculatePow

Finished:
    ret  8        ; assuming this function is STDCALL
pow ENDP

答案 1 :(得分:0)

将调用约定更改为c并且它可以正常工作,但我不知道为什么。如果有人能解释那会很棒。

使用stdcall调用约定,被调用者清理堆栈......这就是我所知道的。必须有更多。堆栈指针可以在从pow函数返回后的任何位置继续进行,并且事情应该正常工作吗?