flat assembler
Message board for the users of flat assembler.
Index
> High Level Languages > C++ and ASM routine. Goto page Previous 1, 2, 3, 4, 5 |
Author |
|
revolution 25 Oct 2010, 01:31
Actually because of the inlining the compiler generates exactly what is expected.
Code: push ecx ;this is not saving the value of ecx, but is allocating stack space. Could also be "sub esp,4", but this is an optimised version. mov [esp],4 ;our volatile variable MUST be saved to memory, we told it to do this by using volatile pop ecx ;this is merely to release our local stack storage, the ecx value is not a return value. Could also be "add esp,4", but this is an optimised version. retn 0x10 ;remove callers parameters from stack, stdcall |
|||
25 Oct 2010, 01:31 |
|
DarkAlchemist 25 Oct 2010, 02:53
That is surely not how any assembly language programmer would do the coding if they wrote the entire program in ASM. If they did then they would not use the stack, at least I would hope not, and just return eax, or w/e with the 4. Smaller and faster code than what MSVC is spitting out for sure.
|
|||
25 Oct 2010, 02:53 |
|
revolution 25 Oct 2010, 03:44
Well you forced it with the volatile keyword, the compiler HAD to do it because you said so. And the stack is the natural place to store local variables. In this instance, the compiler did it exactly as you asked for, and did it in the most efficient way possible.
And without the volatile keyword the compiler also did it exactly, and as efficiently as is possible, it made a simple 'retn 0x10'. |
|||
25 Oct 2010, 03:44 |
|
DarkAlchemist 25 Oct 2010, 04:12
I still do not call that efficient to store the 4 on the stack when I was asking for a return of 4. Storing it in EAX, for instance, and RETN 10 would have been better in an efficiency point of view.
As far as the simple retn 10 I do agree with you there. |
|||
25 Oct 2010, 04:12 |
|
revolution 25 Oct 2010, 04:24
Volatile forces the compiler to store the value in memory, that is the purpose of volatile. The compiler had no choice. There is little point in returning anything in EAX since the function has been inlined into your winmain. The value 4 is only used within winmain and never returned to the OS upon exit.
[edit] Volatile is meant for situations where the value must be passed to memory. These situations usually occur when the address is in some external chip (an IO chip) and we can't simply throw away the value or else the IO chip does not get the right commands and your driver fails to work. However you told the compiler that your local stack variable absolutely must be stored to memory, so it did it, just as you commanded. Last edited by revolution on 25 Oct 2010, 04:31; edited 1 time in total |
|||
25 Oct 2010, 04:24 |
|
Tyler 25 Oct 2010, 04:28
Why is it storing it in ecx? I thought stdcall uses eax.
|
|||
25 Oct 2010, 04:28 |
|
revolution 25 Oct 2010, 04:33
Tyler wrote: Why is it storing it in ecx? I thought stdcall uses eax. |
|||
25 Oct 2010, 04:33 |
|
revolution 25 Oct 2010, 04:39
Here is something you can try:
Code: #include <windows.h> int test() { return 4; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { volatile int a = test(); a = 1; a = 2; a = 3; a = 4; a = 5; return 6; } |
|||
25 Oct 2010, 04:39 |
|
DarkAlchemist 25 Oct 2010, 04:58
revolution wrote: Here is something you can try: Code: CPU Disasm Address Hex dump Command Comments 00401000 /$ 55 PUSH EBP ; test.00401000(guessed Arg1,Arg2,Arg3,Arg4) 00401001 |. 8BEC MOV EBP,ESP 00401003 |. 51 PUSH ECX 00401004 |. 6A 04 PUSH 4 00401006 |. 58 POP EAX 00401007 |. 8945 FC MOV DWORD PTR SS:[LOCAL.1],EAX 0040100A |. C745 FC 01000 MOV DWORD PTR SS:[LOCAL.1],1 00401011 |. C745 FC 02000 MOV DWORD PTR SS:[LOCAL.1],2 00401018 |. C745 FC 03000 MOV DWORD PTR SS:[LOCAL.1],3 0040101F |. 8945 FC MOV DWORD PTR SS:[LOCAL.1],EAX 00401022 |. 6A 06 PUSH 6 00401024 |. C745 FC 05000 MOV DWORD PTR SS:[LOCAL.1],5 0040102B |. 58 POP EAX 0040102C |. C9 LEAVE 0040102D \. C2 1000 RETN 10 |
|||
25 Oct 2010, 04:58 |
|
revolution 25 Oct 2010, 04:59
Looks good to me. Optimised for size also. And your return value (6) has been set.
|
|||
25 Oct 2010, 04:59 |
|
DarkAlchemist 25 Oct 2010, 05:46
revolution wrote: Looks good to me. Optimised for size also. And your return value (6) has been set. |
|||
25 Oct 2010, 05:46 |
|
baldr 25 Oct 2010, 06:00
DarkAlchemist wrote: I still do not call that efficient to store the 4 on the stack when I was asking for a return of 4. Storing it in EAX, for instance, and RETN 10 would have been better in an efficiency point of view. |
|||
25 Oct 2010, 06:00 |
|
revolution 25 Oct 2010, 07:01
DarkAlchemist wrote: Now, if you were to write that by hand, for an entirely ASM project, how would you have written it? |
|||
25 Oct 2010, 07:01 |
|
f0dder 25 Oct 2010, 07:56
Tyler wrote: Why is it storing it in ecx? I thought stdcall uses eax. _________________ - carpe noctem |
|||
25 Oct 2010, 07:56 |
|
DarkAlchemist 25 Oct 2010, 15:21
revolution wrote:
|
|||
25 Oct 2010, 15:21 |
|
DarkAlchemist 25 Oct 2010, 15:22
f0dder wrote:
Code: #include <windows.h> int test() { return 4; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { return test(); } Code: CPU Disasm Address Hex dump Command Comments 00401000 /$ 6A 04 PUSH 4 ; test.00401000(guessed Arg1,Arg2,Arg3,Arg4) 00401002 |. 58 POP EAX 00401003 \. C2 1000 RETN 10 |
|||
25 Oct 2010, 15:22 |
|
f0dder 25 Oct 2010, 15:37
Compiler: Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86 (VS2010)
Code snippet below is the entire contents of the file. Code: int main() { return 42; } Optimized for speed: cl /Ox /FAsc /Faret4.asm /c ret4.c wrote: PUBLIC _main Optimized for size: cl /O1 /FAsc /Faret4.asm /c ret4.c wrote: PUBLIC _main Points of interest: /Ox and /O1 are shorthands for other options. Speed optimization = 5 bytes, size optimization = 3 bytes. |
|||
25 Oct 2010, 15:37 |
|
DarkAlchemist 25 Oct 2010, 18:05
So, the sites that say to optimize for size normally produces faster code these days was full of bunk? Your examples says, at least in this instance, it was.
This has been a HUGE learning example for me because, as so many are, I only took what people said and not until I decided to launch back into ASM did I actually see the truth. In this day and age does anyone compile for size? |
|||
25 Oct 2010, 18:05 |
|
f0dder 25 Oct 2010, 19:36
DarkAlchemist wrote: So, the sites that say to optimize for size normally produces faster code these days was full of bunk? Your examples says, at least in this instance, it was. The majority of normal code isn't running speed critical inner loops, and a lot of time will be spent block-waiting on external resources. Outside of those tight inner loops, you're probably better off optimizing for size. It might result in slower code, but 1) it doesn't matter if your code takes 1ms or 2ms if the next action is waiting hundreds of ms for socket or file data. 2) reducing size means (slightly) smaller code. Might not matter much wrt. filesize or memory consumption, but it means less L1 cache consumption. |
|||
25 Oct 2010, 19:36 |
|
Goto page Previous 1, 2, 3, 4, 5 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.