Can FPU registers be pushed/popped on/from the stack?

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
Hello,

I know that the data registers of the FPU are themselves logically organized as a stack of sorts.

But, I want to know if the registers can be sent to/taken from the stack.

Something like: pop st(0) or push st(2) where st(0) represents the top of the FPU data register stack and st(i) is i registers above st(0).

What do you guys think?
 
Last edited:

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,666
4,606
75
I think several things.

First, I'm not sure if there's a single instruction to do this. But you can store a float at the stack pointer and increment or decrement the stack pointer - I'm not sure which - by the size of a float. So there's some way to do it.

Second, you shouldn't use the old fp stack unless you have a desperate need for 80-bit floats. Use SSE instructions instead.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
First, I'm not sure if there's a single instruction to do this. But you can store a float at the stack pointer and increment or decrement the stack pointer - I'm not sure which - by the size of a float.

I read about this very thing in the Intel "bible".

There is no opcode to do it.

You have to do it by hand.

Incidentally, you would decrement the stack pointer; after all, the stack grows down.

Second, you shouldn't use the old fp stack unless you have a desperate need for 80-bit floats. Use SSE instructions instead.

Really? Just abandon the whole FP unit altogether?
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
The x87 instructions are pretty much defunct now because of the SSE/AVX instructions (especially since now 128 bit floats are supported. So there really is little reason).

The FP unit is shared among the instructions (x87 and SSE), so there isn't really a loss of hardware performance. The only thing you sort of lose out on is the extra registers of the FP stack, but that really isn't much of a loss. Stack based programming in assembly is somewhat weird when everything else is register manipulation.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
Stack based programming in assembly is somewhat weird when everything else is register manipulation.

I think that the stack has been pretty muck abandoned in 64-bit programming.

After all, you have such an abundance of CPU registers that everything can be done there.

Also, in 64-bit 4 out of the 6 segment registers are disabled. (permanently set to 0)

One of the disabled segment registers is the SS register which is supposed to hold the base address of the stack segment.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,666
4,606
75
I think that the stack has been pretty muck abandoned in 64-bit programming.
Not even close! For instance, every local variable you create in C has to be either in a register or on the stack. But arrays can't be stored in registers. So every local array you create in C is stored on the stack.

The stack is also the only place call pushes the instruction pointer, and the only place ret retrieves it from.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
Not even close! For instance, every local variable you create in C has to be either in a register or on the stack. But arrays can't be stored in registers. So every local array you create in C is stored on the stack.

The stack is also the only place call pushes the instruction pointer, and the only place ret retrieves it from.

I had't considered that.

But, how is it implemented in 64-bit?

Like the OCD madman that I am, I'm reading every page of the Intel "bible". (I'm on page 331. Only 4287 to go!)

It was mentioned rather early, in chapter 6 I believe, that the SS register, along with three others, is zeroed out in 64-bit mode (the standard mode for modern systems).

I somehow interpreted that to mean, incorrectly apparently, that the stack wasn't used any longer.

I see now that just because the SS register doesn't point to a "special value" doesn't mean that the stack is no longer utilized.

I supposed then that the stack memory is "flat".

That is, the RSP register points to the actual address of the stack pointer, not just an offset from some base value.

But, what about the C convention for 64-bit systems?

Is it still to push parameters on the stack before making the procedure call?
 

Schmide

Diamond Member
Mar 7, 2002
5,739
1,028
126
There may be a bit of confusion over the use of the word stack. The FPU stack is not a true stack in the sense of a memory stack. It is more of an operand stack. The best way of thinking of it is a post-fix (reverse polish notation) calculator with a few cheats. You basically push operands on the stack then the stack is operated upon. The operators are not pushed on the stack and there is the fxchg command that allows for movement of operands within the stack.

In terms of memory addressing. The stack pointers and segment registers are only related by the memory model used with them. The non segment registers have the same function regardless of memory model, whereas the segment registers facilitate the memory model for which they operate in.

You could easily create a stack using 2 regular registers. However its function would take multiple operators to provide its function. A push would be a move then increment. A pop would be a move then decrement. A enter and leave would be similar but using add and subtract respectively. Call and ret save or return instruction pointer.
 
Last edited:

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
There may be a bit of confusion over the use of the word stack. The FPU stack is not a true stack in the sense of a memory stack. It is more of an operand stack. The best way of thinking of it is a post-fix (reverse polish notation) calculator with a few cheats. You basically push operands on the stack then the stack is operated upon. The operators are not pushed on the stack and there is the fxchg command that allows for movement of operands within the stack.

Yes, I am aware of how the FPU stack works.

Though, why was the FPU unit built that way?

Why wasn't the FPU unit just made of "regular" registers like RAX, REX, etc.?
 

Schmide

Diamond Member
Mar 7, 2002
5,739
1,028
126
Prob because it was built on a coprocessor and thus commands had to go over a bus to get there. That and in general post-fix was the more common encoding for FP back in the day.
 
Last edited: