Search code examples
assemblyx86fpux87

How to get all variables an put it on FPU stack?


I have the following code (this is the code written by my lecturer) which calculates the root of the number (a).

    [bits 32]

    call getaddr ; get the runtime addres of format

    format db "delta = %lf", 0xA, 0
    offset equ $ - format
    a      dq 6.0 ;
    b      dq 10.0
    c      dq 16.0

    getaddr:

        finit

        mov eax, [esp]
        lea eax,[eax+offset]

        fld qword[eax]
        fsqrt

        lea eax, [esp+4]
        fstp qword[eax]

        call[ebx+3*4]; start screen print instuctions 
        add esp, 3*4

        push 0
        call[ebx+0*4]

Now, I need to modify this code to perform several operations on the three numbers given, and here is my problem because I have no idea how to put them on the FPU stack. Can anyone tell me what should I do? I tried to do the same as above, but refer to the next elements of the stack (below my attempt) but unfortunately it does not work properly (the program does not display anything). I will be very grateful for any help. A few days ago I added a similar question, I got some advice on how to improve the code so that it is more readable and better at all, but my lecturer does not accept solutions other than what he presented. My attempt to get b variable instead of a:

    mov eax, [esp+4]
    lea eax,[eax+offset]

    fld qword[eax]
    fsqrt

    lea eax, [esp+4]
    fstp qword[eax]

    call[ebx+3*4]; start screen print instructions
    add esp, 3*4

    push 0
    call[ebx+0*4]

Solution

  • It seems you put the +4 to access the next variable (i.e. b) into the wrong place. You start off with mov eax, [esp+4] instead of mov eax, [esp]. However, you should rather change lea eax, [eax+offset] to lea, eax, [eax+offset+8] instead.

    Note that you need +8, because the qword values are 64-bit and thus take 8 bytes each.

    And here is the reason why:

    The very first instruction is a call getattr, which is really just a dirty trick to do push ADRESS_OF_FORMAT. So, on the stack (at position [esp]) you have the address of the data structure at the very beginning of the code. However, as far as the code is concerned, there is nothing there at [esp+4]—there is really just this one address on the stack.

    With mov eax, [esp] you then load this address into eax. So, eax is now a pointer to the string "delta = ...". By adding offset to it (lea eax, [eax+offset] is a fancy way for add eax, offset), you get the address of the variable a. It is here that you now need to add 8 more to get the address of b.