Transfer and stack correction of parameters in assembly

Source: Internet
Author: User
Tags win32

In the Win32 assembly, we often have to deal with the API, but also will often use their own API-like with the parameters of the subroutine, this article is about the subroutine call in the process of the concept and analysis of parameter transfer. Generally in a program, the passing of parameters is carried out through the stack, that is, the caller presses the parameters to be passed to the subroutine (or the callee), and the subroutine takes the corresponding value out of the stack and uses it, for example, if you want to call Subrouting (VAR1,VAR2,VAR3), The compiled final code may be

Push VAR3
Push VAR2
Push VAR1
Call subrouting
Add esp,12

That is, the caller first presses the parameter onto the stack and then invokes the subroutine, and after completion, the caller or callee must have one side of the stack pointer fixed to the state before the call, since the number previously pressed in the stack is no longer useful. Whether the argument is the rightmost first stack or the leftmost first stack, and whether the caller or callee can fix the stack must have a convention. Otherwise it would produce incorrect results, which is why I used the word "possible" in the preceding words: The conventions for calling subroutines in various languages are different, and their differences are shown in the following table:

C SysCall stdcall Basic Fortran Pascal
Parameters from left to right yes Yes Yes
Parameter from right to left is yes Yes
The caller cleanup stack is
Allow to use: VARARG Yes Yes Yes

VARARG represents the number of parameters can be indeterminate, there is an example of the printf statement in C, in the table above, the definition of stdcall has to be explained that if stdcall use: VARARG, the caller clears the stack, and in the absence of: Vararg is cleared by the caller.
In the Win32 assembly, the Convention uses the StdCall method, so we need to use the. Model StdCall statement at the beginning of the program. That is, in an API or subroutine, the rightmost argument is first put into the stack, and then the subroutine is responsible for correcting the stack when it returns, for example, if we are going to call MessageBox this API because it is defined as MessageBox (Hwnd,lptext, Lpcaption,utype) So in the program to use this:

Push MB_OK
Push offset Szcaption
Push offset Sztext
Push HWnd
Call MessageBox
...

We don't have to add an add sp,4*4 to the API to fix the stack, because this is already done by the MessageBox subroutine. In the Windows API, the only special API is wsprintf, the API is C, and it's defined as wsprintf (lpout,lpformat,var1,var2 ...), so when you use it, you need to:

Push 1111
Push 2222
Push 3333
Push offset Szformat
Push offset Szout
Call wsprintf
Add Esp,4*5

Here's how the subroutine accesses the parameters, because the default registers for stack operations have ESP and EBP, and ESP is a stack pointer that cannot be used temporarily, it is generally used EBP to access the stack, assuming that there are two parameters in one call, and that the stack pointer ESP is X before the first argument is pushed, The ESP after pressing two parameters is X-8, the program begins to execute the call instruction, and the calls command puts the return address on the stack, when ESP is X-C, and it is already in the subroutine, and we can start using EBP to access the parameters, but in order to restore the EBP value on return, we need another sentence Push EBP to first save the value of EBP, then ESP for X-10, and then execute a MOV ebp,esp, according to the right figure can be seen, in fact at this time [Ebp + 8] is the parameter 1,[EBP + c] is the parameter 2. In addition, local variables are also defined on the stack, their positions are generally placed after the EBP values saved by the push EBP, and local variables 1, 2 correspond to [ebp-4], [ebp-8], and the following is a typical subroutine that completes the first argument minus the second argument. It is defined as:

MyProc proto Var1,var2; two parameters
Local lvar1,lvar2; two locals

Note that the two local variables here are not actually used, but for demonstration purposes, the actual code is:

MYPROC proc

Push EBP
MOV Ebp,esp

Sub esp,8

mov Eax,dword ptr [ebp + 8]
Sub Eax,dword ptr [Ebp + c]

Add esp,8

Pop EBP
RET 8

MyProc ENDP

Now to analyze this subroutine, push Ebp/mov Ebp,esp is a routine save and set EBP code, sub esp,8 left two local variables in the stack space, Mov/add statement completed Add, add esp,8 fixed two local variables used by the stack, ret 8 Fix the stack used by two parameters, which is equivalent to the effect of Ret/add esp,8 two-sentence code. As you can see, this is a standard stdcall convention subroutine, when the last parameter is used to the stack, and when it is returned, the child program makes a stack correction. Of course, this subroutine in order to demonstrate the implementation process, using the manual save Ebp and set the local variable method, in fact, 386 processors have two dedicated instructions to complete this function, that is the function of the Enter and Leave,enter statement is push Ebp/mov EBP, Esp/sub esp,xxx, this xxx is Enter, Leave completes the Add Esp,xxx/pop ebp function, so the above program can be changed to:

MYPORC proc
Enter 8,0

mov Eax,dword ptr [ebp + 8]
Sub Eax,dword ptr [Ebp + c]

Leave
RET 8
MyProc ENDP


Okay, in this regard, the principle of parameter transfer should also be clear, but also to conclude that, in the use of Masm32 Win32 assembler, we do not need to remember [Ebp + XX], such as the trouble of the address, or calculate the local variables need to reserve the stack space, and in the RET When calculating the value to be added, MASM32 's macro instructions have done this, as in Masm32, the above program as long as the written:

MYPROC proc Var1,var2
Local LVAR1,LVAR2

MOV eax,var1
Sub Eax,var2
Ret

MyProc ENDP

The compiler automatically inserts a Enter statement in front of the Mov eax,var1, and its parameters are automatically specified according to the local variables defined locally, before the RET will automatically add a Leave, the same, the compiler will be based on the number of parameters of the RET to replace the RET xxx, the mov eax,var1 change mov eax,dword ptr [EBP + 8] and so on.

Finally, using the MASM32 invoke macro directive, as you can see earlier, when you invoke a subroutine with a parameter, we need to push the parameter onto the stack, and if we accidentally mistake the number of arguments, we make the stack unbalanced, causing the program to take out the wrong return address from the stack and cause unpredictable consequences, So it is necessary to have a statement to complete the task of automatic inspection, invoke is such a statement, in fact, it is automatically push all parameters, detect the number of parameters, type is correct, and use call to invoke a macro instruction, for the above Push/push/call MyProc Instructions, you can do it with a single instruction:

Invoke MYPROC,VAR1,VAR2

Of course, when you look at the machine code when the program is compiled, you will find that it is correctly replaced with the same push/push/call instruction. However, before using invoke, in order for it to perform the correct parameter test, you need to declare the function, as in C, the declared statement is:

MyProc Proto:dword,:dword

In the statement, the proto is a keyword, which indicates that the type of the parameter is a double word type, and several of the arguments are of a double word in Win32, and that the statement is to be written before invoke, so we generally include it in the Include file, well, to put it together, using a subroutine or Api with parameters in Masm32, we just use:

...
MyProc Proto:d word,:d Word
...
. Data
x DD?
Y dd?
Dwresult DD?
...
MOV x,1
MOV y,2
Invoke MyProc X,y
MOV dwresult,eax
...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.