【问题标题】:Passing a parameter via stack to procedure in MASM通过堆栈将参数传递给 MASM 中的过程
【发布时间】:2016-05-03 20:14:15
【问题描述】:

我正在尝试将 3 个参数传递给一个过程,添加它们,然后将它们返回到 MASM 的税务登记册中。但是,结果是随机的巨大数字。我正在尝试使用 C 风格的调用约定,我将 3 个变量传递给一个函数。我究竟做错了什么?这是我的代码:

INCLUDE PCMAC.INC


.MODEL SMALL
.586
.STACK 100h
.DATA

.CODE
        EXTRN  GetDec :NEAR, PutDDec : NEAR, PutHex : NEAR
Main PROC
        _Begin
        push 10
        push 20
        push 30

        call Test1


        call PutDDec
        add esp, 12

        _Exit
Main ENDP
Test1 PROC
    ; *** Standard subroutine prologue ***
    push ebp
    mov ebp, esp
    sub esp, 4
    push edi
    push esi

    ; *** Subroutine Body ***

    mov eax, [ebp+8] ; parameter 1 / character
    mov esi, [ebp+12] ; parameter 2 / width
    mov edi, [ebp+16] ; parameter 3 / height

    mov [ebp-4], edi
    add [ebp-4], esi
    add eax, [ebp-8]
    add eax, [ebp-4]

    ; *** Standard subroutine epilogue ***
    pop esi ; Recover register values
    pop edi
    mov esp, ebp ; Deallocate local variables
    pop ebp ; Restore the caller’s base pointer value

    ret
Test1 ENDP
End Main

【问题讨论】:

    标签: assembly masm masm32


    【解决方案1】:

    我做错了什么?

    您没有评论您的代码,也没有使用调试器。

    mov [ebp-4], edi
    add [ebp-4], esi
    add eax, [ebp-8] ; <---- what is this ebp-8 here?
    add eax, [ebp-4]
    

    要加 3 个数字,你只需要 2 个加法,为什么你有 3 个? 你甚至不需要使用局部变量,你可以这样做:

    push ebp
    mov ebp, esp
    
    mov eax, [ebp+8] ; parameter 1 / character
    add eax, [ebp+12] ; parameter 2 / width
    add eax, [ebp+16] ; parameter 3 / height
    
    mov esp, ebp ; Deallocate local variables
    pop ebp ; Restore the caller’s base pointer value
    
    ret
    

    或者,如果您不需要堆栈帧,那么只需:

    mov eax, [esp+4]
    add eax, [esp+8]
    add eax, [esp+12]
    ret
    

    【讨论】:

    • 感谢您的回答。当我调用“调用 PutDDec”时,结果不是加法。你知道这其中的原因吗?谢谢
    • 我们不知道PutDDec 对参数的期望,也许它也希望在堆栈上。在call PutDDec 之前添加mov [esp], eax 可能值得一试。
    • PutDDec 打印出 EAX 寄存器的十进制版本
    • 嗯,打印什么?
    • 781106505 我正在关注mov eax, [esp+4] add eax, [esp+8] add eax, [esp+12] ret 作为我的功能
    【解决方案2】:

    在你的子程序体中,三个参数的总和可以这样完成:

    mov [ebp-4], edi   ;Move EDI into your local var
    add [ebp-4], esi   ;Add ESI into your local var
    add eax, [ebp-4]   ;Finally, add the contents of your local var into EAX
                       ;(note that EAX contains first param) 
    

    你的错误在于[ebp-8]

    正如 Jester 在他更彻底的回答中指出的那样,您实际上并不需要一个本地 var 来进行求和。

    【讨论】:

      【解决方案3】:

      我能够通过使用基指针的 ax 部分来让程序运行,因为我推送的是 2 DB,而不是 DW:

      INCLUDE PCMAC.INC
      
      
      .MODEL SMALL
      .586
      .STACK 100h
      .DATA
      sum DWORD ?
      
      .CODE
              EXTRN  GetDec :NEAR, PutDec : NEAR, PutHex : NEAR
      Main PROC
              _Begin
              push 10
              push 20
      
              call Test12
              ;and eax, 0ffffh
      
              call PutDec
      
              _Exit
      Main ENDP
      Test12 PROC
          push bp
          mov bp, sp
      
          mov ax, [bp+6] ;
          add ax, [bp+4] ;
      
          pop bp
          ret 4
      Test12 ENDP
      End Main
      

      【讨论】:

      • 我似乎放错了答案。它属于您的另一个/以后的问题:“MASM:如何通过引用传递值”。同时接受你自己的答案也不是很好,同时@Jester 帮助了你!
      猜你喜欢
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 2017-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多