X86 assembly procedure prologue help.

In summary, the code saves the base pointer to the stack, assigns the new stack pointer, and sets the CPU flags.
  • #1
perplexabot
Gold Member
329
5
Hey all, I was doing a bit of reading and ran into the following code (this is a function prologue for a main function, if you need more code or the actual C code let me know):

push ebp
mov ebp, esp
sub esp, 0x18
and esp, 0xblackf0
mov eax, 0x0
sub esp, eax

So I understand the first three lines. first save the base pointer to the stack, second assign the base pointer and lastly set the new stack pointer with enough space for the local variables.

What I don't understand are the last three lines. I know what the and, mov and sub opcodes do but I can't get the general picture. Also what exactly is eax used for? Is it a gpr? Those last three lines don't appear in regular functions, so I am guessing it has something to do with the main function.

Any help will be much appreciated, thank you.
 
Technology news on Phys.org
  • #2
"and esp, 0xblackf0" - truncates esp to a 16 byte boundary

"mov eax, 0x0" "sub esp, eax" - accomplishes nothing.
 
  • Like
Likes 1 person
  • #3
rcgldr said:
"and esp, 0xblackf0" - truncates esp to a 16 byte boundary

"mov eax, 0x0" "sub esp, eax" - accomplishes nothing.

Hmmm thank you. If you don't mind me asking though, why truncate it and why have the second to last line if it does nothing (I can see that it does nothing)?

Thanks.
 
  • #4
One possibility is that some type of structure that is some multiple of 16 bytes long could be allocated on the stack. For example, the "mov eax, 0x0", could instead be "mov eax, 0x40", to allocate 64 bytes from the stack on a 16 byte boundary. I haven't seen this done with any of the microsoft compilers I use. Perhaps the space is allocated for some type of optional debug mode.
 
Last edited:
  • Like
Likes 1 person
  • #5
rcgldr said:
One possibility is that some type of structure that is some multiple of 16 bytes long could be allocated on the stack. For example, the "mov eax, 0x0", could instead be "mov eax, 0x40", to allocate 64 bytes from the stack on a 16 byte boundary. I haven't seen this done with any of the microsoft compilers I use. Perhaps the space is allocated for some type of optional debug mode.

Thank you.
 
  • #6
rcgldr said:
"and esp, 0xblackf0" - truncates esp to a 16 byte boundary

That may be to optimize the access speed to physical memory, and/or the CPU chip's memory cache(s).

"mov eax, 0x0" "sub esp, eax" - accomplishes nothing.

I'm not sure, but could that reset some of the CPU flags to a known state? (this sort of trick can be quicker than setting the flags directly).

It certainly sets eax to a known state, so it does accomplish "something".
 
  • Like
Likes 1 person
  • #7
"mov eax, 0x0" "sub esp, eax" - accomplishes nothing.

AlephZero said:
I'm not sure, but could that reset some of the CPU flags to a known state? (this sort of trick can be quicker than setting the flags directly).
The flags are just set to indicate the unsigned result is greater than zero (esp - 0). I doubt it's used, as the cpu flags will get set again on any math like instruction that occurs later.

"mov eax, 0x0"

AlephZero said:
It certainly sets eax to a known state, so it does accomplish "something".
But it's likely that eax is going to get changed during the function. eax is the return values so a return(0) will translate into "mov eax,0", or more likely "xor eax,eax", but at the end of the function, just before "ret". As mentioned before, I haven't seen those last 3 lines of function header code with microsoft compilers.
 
  • #8
Interesting, I didn't know that eax was for the return values. Good info. Thanks.
I also was wondering if those last three lines were compiler optimizations.
 
  • #9
perplexabot said:
I also was wondering if those last three lines were compiler optimizations.
Just the opposite, optimization would not add lines of code that accomplish nothing. What compiler generated that code?
 
  • #10
rcgldr said:
Just the opposite, optimization would not add lines of code that accomplish nothing. What compiler generated that code?

Hmmm, that makes sense, thank you for correcting my logic. This was disassembled using gdb.
 
  • #11
perplexabot said:
Hmmm, that makes sense, thank you for correcting my logic. This was disassembled using gdb.
I was wondering what compiler created that code, not how you disassembled it.
 
  • #12
Oops, sorry, was compiled using gcc.
 
  • #13
perplexabot said:
Oops, sorry, was compiled using gcc.
See what the various options are for gcc, perhaps ones that disable any debug stuff and increase optimization to see if you get the same function entry code.
 

What is the purpose of the prologue in an X86 assembly procedure?

The prologue is the first part of an assembly procedure and its purpose is to set up the stack frame for the procedure. This includes allocating space for local variables, saving the previous frame pointer, and setting the current frame pointer.

What is the role of the frame pointer in the prologue?

The frame pointer is used to access parameters and local variables within the procedure. In the prologue, the frame pointer is set to the current stack pointer before any local variables are allocated. This allows the procedure to access these variables at a fixed offset from the frame pointer throughout the execution.

Why is it important to save the previous frame pointer in the prologue?

Saving the previous frame pointer is important because it allows for nested procedure calls. If the previous frame pointer is not saved, it will be overwritten by the current frame pointer, making it impossible to access local variables in the outer procedure. Saving the previous frame pointer ensures that the stack can be properly unwound when the procedure returns.

What are the common instructions used in the prologue of an X86 assembly procedure?

The common instructions used in the prologue include push, mov, sub, and lea. Push is used to save registers and parameters onto the stack. Mov is used to save the previous frame pointer and set the current frame pointer. Sub is used to allocate space for local variables on the stack. Lea is used to calculate the address of the current frame pointer.

How does the prologue differ in 32-bit and 64-bit X86 assembly?

The prologue in 32-bit X86 assembly is simpler compared to 64-bit assembly. This is because 64-bit assembly has more registers available, which means that fewer variables need to be saved on the stack. Additionally, the 64-bit prologue uses the rbp register as the frame pointer instead of ebp in 32-bit assembly.

Similar threads

  • Programming and Computer Science
Replies
19
Views
2K
  • Programming and Computer Science
Replies
4
Views
8K
  • Programming and Computer Science
Replies
5
Views
3K
  • Computing and Technology
Replies
11
Views
2K
  • Programming and Computer Science
Replies
3
Views
2K
  • Programming and Computer Science
Replies
11
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
6
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Programming and Computer Science
Replies
32
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
Back
Top