assembly - 函数参数未正确传入 MASM

标签 assembly x86 masm masm32

我正在学习 MASM,但我无法让这个简单的代码工作。我没有得到传递给调用的值,我不知道发生了什么。我试过push 2,push 2,call pow。结果相同。 EAX 和 EDX 看起来像垃圾或者可能是内存地址。

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

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

.386
.model flat,stdcall
option casemap:none

include windows.inc

include masm32.inc
includelib masm32.lib

include kernel32.inc
includelib kernel32.lib

include user32.inc
includelib user32.lib


.code

;requires power > 0 for correct answers
pow proc x:DWORD, power:DWORD

    ;THESE TWO MOVES RIGHT HERE ARE NOT WORKING AS EXPECTED
    ;I PUSH 2 ONTO STACK BUT WHEN I LOOK AT REGISTER VALUES
    ;IN DEBUG THEY ARE INCORRECT/GARBAGE
    mov eax, x      ;eax has x
    mov edx, power  ;edx has power
    mov ecx, eax    ;ecx will be my constant base

start_power:
    cmp edx, 1      ;is power 1?
    je end_power    ;then jump to end
    imul eax, ecx   ;else mul result/x with x
    dec edx         ;power--
    jmp start_power ;jump back to beginning of loop

end_power:
    ret             ;return answer eax

pow endp


start:

invoke pow, 2, 2 ;eax should hold 4 after this
invoke ExitProcess, eax ;program should exit with code eax, ez way to print result

end start

最佳答案

是的,cdecl和stdcall的区别在于前者是caller-clean,后者是callee-clean。 (另请参阅Raymond Chen's series on calling conventions in Windows

问题是,您的 pow 过程没有遵循 stdcall 约定,因为它没有清理堆栈。您需要指定要弹出的字节数作为 ret 指令的一部分。在本例中,该值为 ret 8

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

why are there 4 threads?

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


就其值(value)而言,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

关于assembly - 函数参数未正确传入 MASM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44930178/

相关文章:

assembly - 在 MASM 中调用 c 的 print

assembly - 是否可以使用外部宏参数被内部宏使用?

c++ - 来自数组 0 初始化的奇怪程序集

c - 将变量移动到 cl 并使用内联汇编执行 shr

x86 - 英特尔处理器的 TLB ASID 标签中有多少位?以及如何处理 'ASID overflow' ?

c - 在c中访问进程独立寄存器的值

assembly - 使用Newton-Raphson方法在x87 FPU上建立多维数据集根

assembly - MIPS 中的操作系统如何访问外设?

c - 如何确定外围设备的端口号?

assembly - 创建一个 ASM 文件,该文件将返回位于 8 个连续寄存器中的字符