flat assembler
Message board for the users of flat assembler.
Index
> Windows > Questions: parameter passing and return values |
Author |
|
cod3b453 27 May 2015, 20:24
Assuming the 32bit code is cdecl/stdcall with sizeof(void*)=sizeof(int)=4, the parameters will be on the stack at esp+4 and esp+8 (the return address is at esp) when entering the function. So with your push ebp these shift to esp+8/C like in your code. The return value, if a singular value, will be in eax, so:
Code: PerformAddition: push ebp ; Save ebp by pushing onto stack mov ebp,esp mov eax,dword [ebp+0x8] ; A is at ebp+8 add eax,dword [ebp+0xC] ; B is at ebp+C pop ebp ; Restore ebp by popping off of stack ret 8 It is possible to assemble using fastcall [or others] in both 32 and 64bit which use registers for the parameters but this usually depends on platform/compiler. The stack is still used to provide "shadow" space to save parameters the same as before but the function must save the register to this space by itself. In this case the stack is not needed at all but included example code you might see a debug build use: Code: PerformAddition: ; Equivalent code - note int is still 4 bytes but values occupy 8 bytes on the stack ; push rbp ; mov rbp,rsp ; mov dword [rbp+0x10],ecx ; mov dword [rbp+0x18],edx ; mov eax, dword [rbp+0x10] ; add eax,dword [rbp+0x10] lea eax,[ecx+edx] ; Only really need this line. A is in rcx, B is in rdx ; pop rbp ret ; Parameters on stack cleaned up by caller |
|||
27 May 2015, 20:24 |
|
yq8 28 May 2015, 00:12
So for x64 every offset is double the size of the x86 offset?
|
|||
28 May 2015, 00:12 |
|
El Tangas 28 May 2015, 10:04
yq8 wrote: So for x64 every offset is double the size of the x86 offset? Yes, 8 byte steps, and since there is always storage for at least 4 variables, the stack needs to be adjusted by (at least) 32 bytes on return. Problem is, I'm not sure who is supposed to do that, caller or callee. Code: ;callee cleans up ... ret 32 ;caller does nothing return_address: Code: ;calle just returns ... ret ;caller cleans up return_address: add rsp,32 So you will have to try and trace with a debugger, see if the code crashes, etc. But check this link: https://msdn.microsoft.com/en-us/library/ms235286.aspx |
|||
28 May 2015, 10:04 |
|
revolution 28 May 2015, 11:21
El Tangas wrote: ... and since there is always storage for at least 4 variables, the stack needs to be adjusted by (at least) 32 bytes on return. Problem is, I'm not sure who is supposed to do that, caller or callee. |
|||
28 May 2015, 11:21 |
|
AsmGuru62 28 May 2015, 15:48
If few API calls must be made - code to reserve/adjust can be done just once:
Code: sub rsp, 32 ; perform parameters passing for an API call #1 ; perform parameters passing for an API call #2 ; perform parameters passing for an API call #3 add rsp, 32 Of course, provided there are no branches in the calls. |
|||
28 May 2015, 15:48 |
|
cod3b453 28 May 2015, 16:51
yq8 wrote: So for x64 every offset is double the size of the x86 offset? - Passing parameters larger than 32bit on x86 would use more than 4 bytes e.g. f(int a, double b, int c) would use 4 bytes for a & c and 8 bytes for b - You can pass structures by value rather than by reference which means a parameter can be any size [a similar mechanism is used when returning structures] |
|||
28 May 2015, 16:51 |
|
eeikel 08 Apr 2016, 10:14
Assuming your using:
- eclipse cdt - Fasm - mingw with gcc on a windows machine In Fasm create an object file: Code: format MS64 COFF public show public PerformAddition hello db 'Hello World',0 show: mov rax, hello; ret PerformAddition: push r10 push r11 mov r10,rcx mov r11,rdx mov rax,qword r10 add rax,qword r11 pop r10 pop r11 ret save as samplecode in fasm open eclipse, create a new project TestASM locate the samplecode.OBJ file and copy it to your workspace->TestASM folder in eclipse: refresh project TestASM open: Project-> c/c++ build -> Settings in Tools Settings Tab -> MinGW C Linker -> Miscellaneous add samplecode.OBJ you can use search workspace to lactae the file. create an new c source file and name it: text.c add following code: Code: #include "stdlib.h" #include "stdio.h" #include "string.h" int Perform-addition(int a, int b); char * show(); int main(){ printf("-> %s \n",show()); printf("============================ \n"); int number = PerformAddition(3, 9); printf("3 + 9 = 12? %d",number); return 0; } result: Quote:
https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions The Microsoft x64 calling convention[11][12] is followed on Windows and pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8, R9 for the first four integer or pointer arguments (in that order), and XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional arguments are pushed onto the stack (right to left). Integer return values (similar to x86) are returned in RAX if 64 bits or less. Floating point return values are returned in XMM0. Parameters less than 64 bits long are not zero extended; the high bits are not zeroed.[/quote] |
|||
08 Apr 2016, 10:14 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.