flat assembler
Message board for the users of flat assembler.
Index
> Windows > Correct Procedures? |
Author |
|
Everhest 03 Aug 2008, 09:33
Zero wrote: But why is it that after the old EBP is pushed, then ESP is pushed? I'm confused as to why that is happening. No. Stack as straightedge with crawler , if ebp is pushed then on copied in [esp-4]. Zero wrote:
??? easier will so Code:
stdcall a2int, buffer Since time shall else render my aid. _________________ Forgive for my bad english, I from russia... |
|||
03 Aug 2008, 09:33 |
|
Zero 03 Aug 2008, 20:02
Quote: No. Stack as straightedge with crawler Smile, if ebp is pushed then on copied in [esp-4]. Right, I understand this, and maybe i'm wrong, but when I look at the values on the stack....after EBP I see ESP. So for my procedure, there are a total of 6 values that are pushed on the stack, but in my head i'm only expecting 5 (esi,ebx,ebp,ret, and buffer). Also, if anyone notices any other mistakes i've made, or maybe has suggestions on how to optimize or improve the procedure, i'd appreciate the help. I'm really new to all of this and i'm trying my best to learn. |
|||
03 Aug 2008, 20:02 |
|
asmcoder 03 Aug 2008, 20:28
[content deleted]
Last edited by asmcoder on 14 Aug 2009, 14:56; edited 1 time in total |
|||
03 Aug 2008, 20:28 |
|
Madis731 03 Aug 2008, 22:58
Zero wrote: So for my procedure, there are a total of 6 values that are pushed on the stack, but in my head i'm only expecting 5 (esi,ebx,ebp,ret, and buffer). Good to hear that you've learned a lot in these few days. Now I tried to answer really simply what is happening. These 6 are as follows: 1) buffer - this one you're pushing manually 2) return address - the stdcall remembers it for you now it gets tricky because its hidden for the user convenience 3) ebp is pushed because proc wants to use it mov ebp,esp <= this is where its overwritten 4) sub esp,4 - this is a kind of push that only preserves space i.e. nothing is stored there...yet 5) esi - it is pushed because you told it to: a2int uses esi 6) ebx - the same... Look at #4 - the space is preserved for sign db 0, in OllyDbg you can also see that there's an instruction MOV BYTE[EBP-4],0. This instruction writes 0 to that 'sign'-variable. Tomorrow I will teach you how to make it work (you have at least one bug) and help you optimize for readability, size and speed |
|||
03 Aug 2008, 22:58 |
|
Zero 04 Aug 2008, 20:28
Madis731 wrote:
Awesome. I'm looking forward to reading what you'll have to say. I've become addicted to assembly |
|||
04 Aug 2008, 20:28 |
|
Madis731 05 Aug 2008, 06:41
Try understanding this and if you have questions, just ask. Here are a few starters for you. I'm in a good mood today
1) See how I got rid of most of the jumps and labels. Jumps are usually bad, because CPU might not predict them and have slow performance. Not that it matters in a piece of code like this, but for general knowledge, this habit should be maintained 2) You don't actually need all those "a dd 4" etc. because they seem to be constants. In the future, if you are going to ask user for these values, then the data should look like "a dd ?" and moved to the end. That's what I did with sresult, its space is only reserved, not initialized. 3) int2a is a new routine I added. Because of its behaviour I needed to shift the digits to their correct place, that is why there's movsb used. 4) The last line of ReadConsole is there to make an artificial pause. Enter, for example, exits the program. Code: format PE Console include 'win32a.inc' entry start section '.code' code readable writeable start: ;ax^2 + bx + c invoke GetStdHandle, STD_INPUT_HANDLE mov [stdin],eax invoke GetStdHandle, STD_OUTPUT_HANDLE mov [stdout],eax invoke WriteConsoleA,[stdout],prompt,16,count,0 invoke ReadConsoleA,[stdin],buffer,512,count,0 ;calculate x^2 stdcall a2int,buffer mov [x],eax ;Here you have the input in eax ;We should multiply it with itself mul eax ; eax=x² mul [a] ; eax=a*x² mov ebx,eax ; ebx=a*x² mov eax,[b] mul [x] ; eax=b*x add eax,ebx ; eax=ax²+bx add eax,[c] ; eax=ax²+bx+c stdcall int2a,buffer,lenres ;eax=>buffer, len=>lenres invoke WriteConsoleA,[stdout],answer,27,count,0 invoke WriteConsoleA,[stdout],buffer,[lenres],count,0 invoke ReadConsoleA,[stdin],buffer,1,count,0 invoke ExitProcess,0 proc a2int uses esi ebx,lpbuffer:DWORD locals sign db 0 endl mov esi,[lpbuffer] ;[ebp+8] FASM calculates this! xor eax,eax movzx ebx,byte[esi] ;fetch a digit cmp ebx,"-" ;is the first char '-' jne not_negative ;Jump over sign manipulation ;if not negative inc esi mov [sign],1 not_negative: @@: movzx ebx,byte[esi] ;form the number lea eax,[eax*5] lea eax,[eax*2+ebx-"0"] add esi,1 cmp byte[esi]," " ;ANY non-printable char jnc @b ;signals the end of number cmp [sign],1 ;if flag is set, number is jne pos ;negative so subtract from 0 neg eax pos: ret endp proc int2a uses esi ebx,lpbuffer:DWORD,length:DWORD mov esi,[lpbuffer] cmp eax,7FFFFFFFh jc positive neg eax mov byte[esi],'-' add esi,1 positive: mov edi,10 ;divide by edi=10 mov ecx,10 ;maximum ecx=10 digits @@: test eax,eax jz .exit ;exit if zero xor edx,edx ;clear edx every time! div edi add edx,"0" ;change one digit to ascii mov [esi+ecx],dl sub ecx,1 jnz @b ;run until ecx=0 .exit: mov edi,esi lea esi,[esi+ecx+1] sub ecx,10 neg ecx rep movsb sub edi,[lpbuffer] ;how long is the string mov eax,[length] mov [eax],edi ret endp section '.data' data import readable writeable library kernel32,'KERNEL32.DLL' include 'api\kernel32.inc' buffer: times 512 db 0 prompt db 'Enter a number',13,10 answer db 'The answer (ax^2+bx+c) is: ' ; num dw 0 a dd 4 b dd 3 c dd 5 x dd ? ; result dd 0 ;Only uninitialized data from hereon ;dd ? or db ? or rw 123 etc. stdin dd ? stdout dd ? count dd ? lenres dd ? sresult rb 100 |
|||
05 Aug 2008, 06:41 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.