Передача параметра через стек в процедуру в MASM

Я пытаюсь передать 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

person user190494    schedule 03.05.2016    source источник


Ответы (3)


Что я делаю не так?

Вы не комментировали свой код и не использовали отладчик.

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
person Jester    schedule 03.05.2016
comment
Спасибо за ваш ответ. Когда я вызываю вызов PutDDec, результат не является дополнением. Вы знаете причину этого? Спасибо - person user190494; 04.05.2016
comment
Мы не знаем, как PutDDec ожидает аргумент, возможно, он тоже хочет его в стеке. Стоит попробовать добавить mov [esp], eax перед call PutDDec. - person Jester; 04.05.2016
comment
PutDDec выводит десятичную версию регистра EAX - person user190494; 04.05.2016
comment
Ну а что напечатать? - person Jester; 04.05.2016
comment
781106505 Я выполняю mov eax, [esp+4] add eax, [esp+8] add eax, [esp+12] ret свою функцию - person user190494; 04.05.2016

В вашем теле подпрограммы сумма трех параметров может быть выполнена следующим образом:

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].

Кроме того, как отметил Шут в своем более подробном ответе, вам действительно не нужна локальная переменная для вычисления суммы.

person JosEduSol    schedule 03.05.2016

Мне удалось заставить программу работать, используя топорную часть базового указателя, поскольку я нажимал 2 БД, а не 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
person user190494    schedule 04.05.2016
comment
Мне кажется, вы неуместно ответили. Это относится к вашему другому/более позднему вопросу: MASM: как передать значение по ссылке. Также не очень приятно принимать свой собственный ответ, когда в то же время @Jester выручил вас! - person Sep Roland; 08.05.2016