PDA

View Full Version : Local variable with asm



arthurprs
14-09-2008, 05:31 PM
i am having some fun with asm here

in witch ways i can store local variables? and the faster one?

ps: esp is the global stack address right?
ps: ebx and ebp ?

JSoftware
14-09-2008, 06:48 PM
Here's an example


push ebp //Push the base pointer
mov ebp, esp //Set the base pointer to the current stack pointer
add esp, -4 //Subtract 4 from the stack. Equivalent of PUSH DWORD 0. This will hold the local variable. [EBP-4] and [ESP] now points to the local variable
lea ecx, [eax*4+1024] //ecx := eax*4+1024
mov [ebp-4], ecx //store ecx in the local variable
mov eax, [ebp-4] //store the local variable in result
mov esp, ebp //restore the old stack pointer
pop ebp //pop the old base pointer
ret


This is ofcourse a pretty naive and unoptimized code sample, but it goes to show how to write assembler
The equivalent pascal code:


function GetIndex(i: integer): integer;
var x: integer;
begin
x := i*4+1024;
result := x;
end;

arthurprs
14-09-2008, 07:45 PM
weird :shock:

ebp and esp need to be restored on the function end?

what about ebx?

JSoftware
14-09-2008, 08:44 PM
ebx is a general purpose register. It's not different from eax, ecx, edx, esi or edi
'
You would probably have to read up on the calling convention you use. This is most likely fastcall, which is the standard in delphi and freepascal.

This states that the parameters gets passed left to right like this:
eax,edx,ecx,ebp+4,ebp+8,ebp+12,ebp+16, and so on

You are free to do whatever with ebx in the function, but if you modify any of the others and they are not used to pass parameters in, then you must restore them to the value they were before you altered them

This you must do, to any register, except for eax, which is the result register

arthurprs
14-09-2008, 11:47 PM
interesting :}, thanks

Setharian
15-09-2008, 09:03 AM
You are free to do whatever with ebx in the function, but if you modify any of the others and they are not used to pass parameters in, then you must restore them to the value they were before you altered themActually EBX, ESP and EBP values must be always preserved. Also you're free to change and not restore contents of EAX, EDX and ECX even if they were not used to pass parameters into the function. That's the case with all normal calling conventions (fastcall, stdcall, cdecl) as far as I know. Or maybe I do not understand your post correctly.

Setharian
15-09-2008, 09:03 AM
You are free to do whatever with ebx in the function, but if you modify any of the others and they are not used to pass parameters in, then you must restore them to the value they were before you altered themActually EBX, ESP and EBP values must be always preserved. Also you're free to change and not restore contents of EAX, EDX and ECX even if they were not used to pass parameters into the function. That's the case with all normal calling conventions (fastcall, stdcall, cdecl) as far as I know. Or maybe I do not understand your post correctly.

EDIT: How to delete my own double-post? I can't seem to find a buttom for that.

Memphis
23-09-2008, 05:12 PM
hi arthur,



push ebp
mov ebp, esp
add esp, FFFFFFFCh
leave
ret


note:


add esp, FFFFFFFCh

this is basically esp := esp -4


FFFFFFFCh = -4


reason for being -4 is because a cardinal is 4 bytes.

also the leave is basically to restore the stack for the procedure exit.

ret is to return to the line that called the procedure

this is equive something along the lines of.



procedure Blah;
var
xxx: Cardinal;
begin
//do nothing.
end;


also a quick note, passing an argument is different to storing a local variable.

this whole proc would take 8 bytes, it is the smallest and quickest way todo it.

hope this helps.

-MM