flat assembler
Message board for the users of flat assembler.
Index
> Windows > VisualC++ ASM output |
Author |
|
shaolin007 25 May 2005, 16:46
The 1st part
Code: 00401010 push ebp 00401011 mov ebp,esp [color=red] this is a stack frame setup[/red] 00401013 sub esp,44h [color=red]Allocate 68bytes for local variables[/red] 00401016 push ebx 00401017 push esi [color=red]saving state of these registers[/red] 00401018 push edi 00401019 lea edi,[ebp-44h] [color=red]getting address of ebp-44h for rep stos instruction 0040101C mov ecx,11h [color=red] This is the count for rep stos or write 68 bytes[/red] 00401021 mov eax,0CCCCCCCCh [color=red]??? I have no idea why this value is written to 68 bytes[/red] 00401026 rep stos dword ptr [edi][color=red]mov eax into contents of [edi] [/red] The second part is self explanatory. The 3rd part though... Code: [color=red] restore registers and destroy stack frame[/red] 0040104B pop edi 0040104C pop esi 0040104D pop ebx 0040104E add esp,44h [color=red]unallocate 68 bytes used[/red] 00401051 cmp ebp,esp 00401053 call __chkesp (00401130)[color=red] maybe double checking to see if stack is corrupted?[/red] 00401058 mov esp,ebp 0040105A pop ebp 0040105B ret [color=green] And here, something else: Why gets 100 asigned through hexadecimal value? Is it faster than decimal? [/green] Usually when you debug/disassemble its going to show in hex. |
|||
25 May 2005, 16:46 |
|
Nikolay Petrov 25 May 2005, 18:01
__chkesp is a runtime check function.
I don't remember, but I think that you will turn off it with #pragma runtime_checks ... or /RTC "cl" compiler option by the way bcc32 generate this: Code: _main proc near ?live1@0: ; ; main() ; push ebp mov ebp,esp push ebx ; ; { ; int x; ; x=100; ; @1: mov ebx,100 ; ; x=x+5; ; ?live1@32: ; EBX = x add ebx,5 ; ; x=x/3; ; mov eax,ebx mov ecx,3 cdq idiv ecx mov ebx,eax ; ; getch(); ; call _getch ; ; return x; ; mov eax,ebx ; ; } ; ?live1@96: ; @3: @2: pop ebx pop ebp ret _main endp Last edited by Nikolay Petrov on 25 May 2005, 18:17; edited 1 time in total |
|||
25 May 2005, 18:01 |
|
denial 25 May 2005, 18:06
Thank you for your answers.
So if I read it right, BCC compiler doesn't generate a place for local data at all, is that correct? So I may guess that BCC recognizes that there isnt much local data to declare, so EBX can be used to get faster results. Correct me if I am wrong. Anyway, I don't understand why VC++ allocated 68 bytes as I am just using one DWORD value. I heard that most compilers allocate more data while debug-mode for security. Maybe it is about that? |
|||
25 May 2005, 18:06 |
|
shaolin007 25 May 2005, 18:19
"by the way bcc32 generate this" Nickolay
"So if I read it right, BCC compiler doesn't generate a place for local data at all, is that correct?" denial Looks like Nickolay is using _fastcall calling convention where as the other uses _cedecl. |
|||
25 May 2005, 18:19 |
|
Nikolay Petrov 25 May 2005, 19:09
denial wrote: ... BCC compiler doesn't generate a place for local data at all, is that correct? denial wrote: So I may guess that BCC recognizes that there isnt much local data to declare, so EBX can be used to get faster results. Correct me if I am wrong. denial wrote: Anyway, I don't understand why VC++ allocated 68 bytes as I am just using one DWORD value. I heard that most compilers allocate more data while debug-mode for security. Maybe it is about that? |
|||
25 May 2005, 19:09 |
|
r22 25 May 2005, 19:52
When compiling with VC++ to check out it's ASM rolling make sure to compile the code in RELEASE mode this will get rid of all the debugging stuff like _chkesp and also try to optimize the code for speed.
RELEASE > Build | Configurations | select release instead of debug SPEED OPTIMIZED > Project | Settings | C/C++ tab | Optimizations (select Maximize Speed) Compilers do a decent job of optimizing code using only the most compatible opcodes, but because their goal is portability over power they ignore simple optimizations like using MMX to unroll a loop. Short paper I wrote: kryogeniks.com/projects/VCppVSASM.txt |
|||
25 May 2005, 19:52 |
|
denial 26 May 2005, 08:04
The paper you wrote is very interesting - thank you for that well done work. And thank you all for your answers. Anyway, I want to learn writing assembly without those macros.
|
|||
26 May 2005, 08:04 |
|
denial 26 May 2005, 09:16
I'm sorry for a double-post, but it is important.
Based on your paper, I tried to write an own local function, but I don't know if everything is right. It compiles and executes fine, but I learned that not all problems in assembly can be obvious So can someone check it for me? Would be nice Code: start: call _testlocal push 0 call [ExitProcess] _testlocal: .a equ ebp-4 ;save adress of local var ;for easy handling push ebp mov ebp,esp sub esp,4 ;allocate space for one dword mov dword [.a],000030h ;set dword to MB_EXCLAMATION push dword[.a] ;push in reverse order push _caption push _message push 0 call [MessageBox] ;call add esp,4 ;restore data mov esp,ebp pop ebp ret 0 |
|||
26 May 2005, 09:16 |
|
Torrey 26 May 2005, 09:35
The local function works perfectly, you could also get rid of few instructions.
Code: start: call _testlocal push 0 call [ExitProcess] _testlocal: .a equ ebp-4 ;save adress of local var ;for easy handling push ebp mov ebp,esp sub esp,4 ;allocate space for one dword mov dword [.a],000030h ;set dword to MB_EXCLAMATION push _caption push _message push 0 call [MessageBox] ;call mov esp,ebp pop ebp ret |
|||
26 May 2005, 09:35 |
|
denial 26 May 2005, 14:30
Thank you..... and if I want to create local arrays / strings with bigger size? Or structures? Lets say I want two dwords, and a string of the size 35... can I just adress them like this?
.a equ ebp-35 .b equ ebp-39 .c equ ebp-43 and allocate the needed space then? sub esp, 43? |
|||
26 May 2005, 14:30 |
|
r22 27 May 2005, 19:45
If the array is short than using then using the stack to reserve space for it locally is fine. There's good amount of space on the stack for doing local allocations. but if the arrays or strings are very large ( > ~1mb) you may just want to allocate 1 dword and use an API function like VirtualAlloc and then store the return value of the API in the local space you created.
For example... Code: Function: .array1 equ ebp-4 .array2 equ ebp-8 push ebp mov ebp,esp sub esp,8 push esi push edi push 4 ;readwrite push 1000h ;mem commit push 4000000 ;1million dwords array1[0-999,999] push 0 call [VirtualAlloc] mov [.array1],eax push 4 ;readwrite push 1000h ;mem commit push 4000000 ;1million dwords push 0 call [VirtualAlloc] mov [.array2],eax ; now that the large local arrays are allocated To modify values... mov esi, [.array1] mov edi, [.array2] mov ecx, 999999 xor eax,eax xor edx,edx dec edx ;fill array1 with 0's(eax) and array2 with -1's(edx) (unoptimized) .label1: mov [esi+ecx*4],eax mov [edi+ecx*4],edx dec ecx jns .label1 ;when ECX = -1 the loop is done ; now its the end of the function so you need to FREE alloc'd memory push 8000h ;mem release push 0 push dword[.array1] call [VirtualFree] push 8000h ;mem release push 0 push dword[.array2] call [VirtualFree] pop edi pop esi add esp,8 mov esp,ebp pop ebp ret 0 |
|||
27 May 2005, 19:45 |
|
denial 01 Jun 2005, 12:07
Thank you very much fir your help. The last snipped was pretty helpful.
|
|||
01 Jun 2005, 12:07 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.