# Assembly, EBP, ESP, R8-R15 and addressing

This topic is 3937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Are there any usage restrictions on the EBP and ESP registers or can they be used exactly like the other registers? I kind of remember there being some restriction on them but haven't found anything. Same case with the x86-64 registers (R8-R15)? For addressing if it's possible to hard code a physical address would that be the best thing to do? For example..
MOV EAX, dword ptr[EBP + 10]
becomes...
MOV EAX, dword ptr[12345678]
Any benefit to keeping the address in the register? Readability isn't important as this will be compiled code and the physical addresses will be known at compile time. I also won't need to modify this address as the program runs. I'm guessing the second method will decode to a few less micro op's but performance difference should be negligible (potentially free register though). Thanks in advance

##### Share on other sites
It’s been a while since my last line of assembly but let me try to answer this.
I think you can use EBP like other registers, and potentially you could use it to store any value. As a kind of convention in languages like C/C++, EBP holds the stack base pointer which is used to
1. build the function calling / return mechanism
2. allocate variables on the stack.

ESP holds the stack current pointer so I would be careful not to mess with it.

So if you are not in 100% assembly program, like inside a C/C++ program, you should be very careful to save EBP’s value before messing with it, by pushing it on the stack and popping it later on.

##### Share on other sites
I found This useful when I was doing x64 assembly stuff.

##### Share on other sites
Quote:
 Original post by bulgurmayoESP holds the stack current pointer so I would be careful not to mess with it.

Quote:
 Original post by Evil SteveI found This useful when I was doing x64 assembly stuff.

##### Share on other sites
The 16-bit BP register used to have restrictions (and benefits) on it

In the 32bit era and beyond, EBP/RBP is no longer so asymetric because CS = DS = ES = SS .. the old segment preferences and restrictions of some instructions/registers are no longer meaningful.

btw, a decent compiler (or asm programmer) NEVER uses a stack frame.. ever.. if you cant figure out where things are relative to ESP/RSP then you are probably already dead in the water

##### Share on other sites
Quote:
 Original post by Rockoon1Tbtw, a decent compiler (or asm programmer) NEVER uses a stack frame.. ever.. if you cant figure out where things are relative to ESP/RSP then you are probably already dead in the water

That's not entirely true. It's not difficult to have a situation where the data pushed onto the stack is indeterminate, i.e. some data is only pushed is certain conditions are met.

The only real issue with using BP for memory access is the use of SS by default.

Skizz

##### Share on other sites
Quote:
 Original post by Rockoon1btw, a decent compiler (or asm programmer) NEVER uses a stack frame.. ever.. if you cant figure out where things are relative to ESP/RSP then you are probably already dead in the water

GCC does for x86 IIRC, even with -O#, because it allows some minimal debugging and tracing. You have to explicitly pass -fomit-frame-pointer if you don't want them.

As for the OP's question, having EBP free probably wont get you much anyway, internally the processor has many more unnamed registers and will use them to side step write-after-read stalls, so you might be better off setting stack frames and making debugging easier if that is a requirement.

Edit:

Forgot about your other question re: hard coding the address. Which one is better depends on the context. The version with the entire address hard coded in the instruction will obviously be longer, and will probably decode into more micro-ops that break the instruction into 2 (or more) steps, loading the address from just after opcode, then loading the value from that address.

Used sparingly you can make life easier on yourself by using the hard coded one, but inside a loop you would be better off loading the address once outside the loop and using the other one.

[Edited by - outRider on October 10, 2007 11:51:40 AM]

##### Share on other sites
Quote:
 Original post by SkizzThat's not entirely true.

its not?

Quote:
 Original post by SkizzIt's not difficult to have a situation where the data pushed onto the stack is indeterminate, i.e. some data is only pushed is certain conditions are met.

pushes? heh... a really good compiler wont be doing that either.. especially under win64 where the stack should always be aligned to 16 byte boundaries

Allocate enough local space, aligned to the requirements, for the worst case at the start of the procedure.

stop thinking like a black-box compiler :)

Quote:
 Original post by SkizzThe only real issue with using BP for memory access is the use of SS by default.

Thats not an issue. ss = ds under win32 and win64, and probably under linux as well.

##### Share on other sites
Quote:
 Original post by outRiderGCC does for x86 IIRC, even with -O#, because it allows some minimal debugging and tracing. You have to explicitly pass -fomit-frame-pointer if you don't want them.

gcc is not a good compiler.

it is great for what it is .. an open source cross-platform compiler .. but it is not intended to produce the tightest, fastest code on x86(-64) .. icc on the other hand only targets x86(-64) and a stack frame would be a rare exception even without optimizations ..

it is extra work that is not necessary, which also arbitrarily ties up a register .. doesnt that sum it up?

##### Share on other sites
Quote:
Original post by Rockoon1
Quote:
 Original post by SkizzThat's not entirely true.

its not?

Quote:
 Original post by SkizzIt's not difficult to have a situation where the data pushed onto the stack is indeterminate, i.e. some data is only pushed is certain conditions are met.

pushes? heh... a really good compiler wont be doing that either.. especially under win64 where the stack should always be aligned to 16 byte boundaries

Allocate enough local space, aligned to the requirements, for the worst case at the start of the procedure.

stop thinking like a black-box compiler :)

You think too much like a Windows programmer. There are millions of IA32 systems out there that don't run Windows or *nix (VxWorks for example). My comments were really targeted to assembly programming and not compilers (I should have made that clear). Optimising compilers almost certainly allocate stack space for the worst case scenario. But this is not always a good thing to do, assembly code on limited resource systems would need to keep memory use to a minimum - unused memory is wasted after all, and so memory is only reserved if it is actually going to be used. In this case, SP relative addressing is not really an option. I agree that this scenario is not very common, but it can happen. As for the pushes issue, how about an assembly routine calling a C library function that takes va_args?

Quote:

Quote:
 Original post by SkizzThe only real issue with using BP for memory access is the use of SS by default.

Thats not an issue. ss = ds under win32 and win64, and probably under linux as well.

As I said above, what about all the other systems you could be programming for? Making assumptions could lead to errors in the future when the assumptions are no longer valid. If you assume that [BP] == [DI] for BP == DI then you'll get a nasty surprise one day.

Skizz

1. 1
2. 2
3. 3
Rutin
19
4. 4
5. 5

• 10
• 14
• 30
• 13
• 11
• ### Forum Statistics

• Total Topics
631782
• Total Posts
3002332
×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!