Confused by the assembly of the FLD m64fp instruction
I am so confused. I have a question about the FLD m64fp instruction, but I don't know where to start. Since this is homework, I am not specifically asking for an answer, but a method for solving the problem. Any suggestion or idea would be appreciated.
Eight consecutive bytes in memory contain hexadecimal values 01, 00, 00, 00, 00, 00, 00, 00. FLD m64fp command is executed. Its argument is the address of the first of these eight consecutive bytes. As a result of the FLD instruction, the value in ST (0) is now:
1) 2^(-1075) 2) 2^(-1074) 3) 2^(-1023) 4) 2^(-1022)
Also, if I have the following assembly code
│0x8048384 <main> lea 0x4(%esp),%ecx │
│0x8048388 <main+4> and $0xfffffff0,%esp │
│0x804838b <main+7> pushl -0x4(%ecx) │
│0x804838e <main+10> push %ebp │
│0x804838f <main+11> mov %esp,%ebp │
│0x8048391 <main+13> push %ecx │
│0x8048392 <main+14> fldpi │
│0x8048394 <main+16> fsqrt │
│0x8048396 <main+18> fld1 │
│0x8048398 <main+20> fsubrp %st,%st(1) │
│0x804839a <main+22> mov $0x0,%eax │
│0x804839f <main+27> pop %ecx │
│0x80483a0 <main+28> pop %ebp │
│0x80483a1 <main+29> lea -0x4(%ecx),%esp │
│0x80483a4 <main+32> ret
How do I know the value that will be in ST (0) before the main return? Thank.
source to share
Let's start with the first question .
It is not explicitly stated, but I think we can assume we are dealing with little-endian here (every computer you use today will use this). Thus, if you execute FLD m64p
on that memory location, the floating point stack will contain those bytes in reverse order - i.e. 00 00 00 00 00 00 00 01
... Let's see what the double precision format looks like:
Now this is actually a special case - since the exponent is zero, but the mantissa is not, we represent a subnormal number - one that cannot be expressed using a normalized mantissa, i.e. where the integer part is 1 ( 1.xxx
) - it needs leading zeros (remember that since the exponential object is biased (1023), zero actually means 1 - exponent (0) - 1023
here, so -1022
.
As Wikipedia tells us, we can calculate the value of a subnormal number using the following formula:
However, the least significant bit (and only that) in the mantissa is set, and this gives the mantissa a value 2^(-52)
(since we have 52 bits for the mantissa in double precision).
Therefore, if we use this formula, we get:, (-1)^0 x 2^(1-1023) x 2^(-52) = 1 x 2^(-1022) x 2^(-52) = 2^(-1022 - 52) = 2^(-1074)
which is the answer 2.
This is the smallest possible positive subnormal number - if this last bit was not set, the bits will represent a signed zero.
To test this (or find out more easily if you're feeling lazy :)), you can use OllyDbg for Windows, which allows you to modify your assembly code on the fly. Let's introduce the instruction given in the question:
and set the bytes to the required value:
Indeed, when we do this, we get the following:
Which is (almost) equal 2 ^ (-1074)
.
Now about the second question . Analyze the instructions you gave.
- Let's start with
fldpi
what is equivalentST(0) = PI
. - We carry out
fsqrt
, so now we haveST(0) = sqrt(PI)
. -
fld1
loads one intoST(0)
, so the stack looks like this:ST(0) = 1
,ST(1) = sqrt(PI)
. -
fsubrp
performs back subtraction and pops the register stack. Since this is a build of AT&T and buggy one , source first, so we subtractST(0)
fromST(1)
, store the result in,ST(1)
and push the register stack so thatST(1)
becomesST(0)
. Now effectively we haveST(0) = sqrt(PI) - 1
close to0.772
. This value remains atST(0)
when itmain
returns, as nothing changes the floating point stack later.
source to share