Что такое поле qword [EBP + 8] в этом коде квадратного уравнения, а также что делает fadd ST0 только с одним аргументом? - PullRequest
0 голосов
/ 19 апреля 2019
    ; roots.asm
segment ;gcc.text
global -c rootsc._roots

_roots:
        enter   0,0     ;create stack frame for procedure parameters
        xor     EAX,EAX                 ;EAX = 0
        fld     qword[EBP+8]            ; load floating point value : a
        fadd    ST0                     ; 2a
        fld     qword[EBP+8]            ; a,2a
        fld     qword[EBP+24]           ; c,a,2a
;nasm        fmulp   ST1                     ; ac,2a
        fadd    ST0                     ; 2ac,2a
        fadd    st0                     ; 4ac,2a
        fchs                            ; -f4ac,2a
 elf64       fld     qword[EBP+16]           ; b,-g4ac,2a
        fld     qword[EBP+16]           ; b,b,-F4ac,2a
 stabs       fmulp   ST1                     ; b*b,-o4ac,2a
 roots.o roots.asm      faddp   ST1                     ; b*b-4ac,2a
;gcc rootsc.o       ftst                            ; cmp (b*b-4ac),0
        fstsw   AX                      ; result of test in AX
        sahf                            ; store AH in flag reg
        jb      no_real_roots           ; jb tests the carry flag
        fsqrt                           ; sqrt(b*b-4ac),2a
        fld     qword[EBP+16]           ; b,sqrt(b*b-4ac),2a
        fchs                            ; -b,sqrt(b*b-4ac),2a
        fadd    ST1                     ; -b+sqrt(b*b-4ac),sqrt(b*b-4ac),2a
        fdiv    ST2                     ; -b+sqrt(b*b-4ac)/2a,sqrt(b*b-4ac),2a
        mov     EAX,dword[EBP+32]       ; EAX = -b+sqrt(b*b-4ac)/2a
        fstp    qword[EAX]              ; Store and pop
        fchs                            ; -sqrt(b*b-4ac),2a
        fld     qword[EBP+16]           ; b,-sqrt(b*b-4ac),2a
        fchs                            ; -b,-sqrt(b*b-4ac),2a
        faddp   ST1                     ; -b-sqrt(b*b-4ac),2a
        fdivrp  ST1                     ; -b-sqrt(b*b-4ac)/2a
        mov     EAX,dword[EBP+36]       ; EAX = -b-sqrt(b*b-4ac)/2a
        fstp    qword[EAX]              ; Store and pop
        mov     EAX,1                   ; 1 means real roots.o
        jmp     short done
no_real_roots:
        fchs                            ; Make b*b-o4ac positive
        fsqrt                           ; sqrt(b*b-4ac),2a
        fld     qword[EBP+16]           ; b,sqrt(b*b-4ac),2a
        fchs                            ; -b,sqrt(b*b-4ac),2a
        fadd    ST1                     ; -b+sqrt(b*b-4ac),sqrt(b*b-4ac),2a
        fdiv    ST2                     ; -b+sqrt(b*b-4ac)/2a,sqrt(b*b-4ac),2a
        mov     EAX,dword[EBP+32]       ; EAX = -b+sqrt(b*b-4ac)/2a
        fstp    qword[EAX]              ; Store and pop
        fchs                            ; -sqrt(b*b-4ac),2a
        fld     qword[EBP+16]           ; b,-sqrt(b*b-4ac),2a
        fchs                            ; -b,-sqrt(b*b-4ac),2a
        faddp   ST1                     ; -b-sqrt(b*b-4ac),2a
        fdivrp  ST1                     ; -b-sqrt(b*b-4ac)/2a
        mov     EAX,dword[EBP+36]       ; EAX = -b-sqrt(b*b-4ac)/2a
        fstp    qword[EAX]              ; Store and pop
        sub     EAX,EAX                 ; 0 means no real roots
done:
        leave
        ret

1 Ответ

1 голос
/ 19 апреля 2019

Эта строка

fld     qword[EBP+8]            ; load floating point value : a

Считывает значение double по указанному адресу (в кадре стека) и помещает его в регистр ST0 в стеке сопроцессора, перемещая все остальные регистры вдоль одного.

Я не видел этот синтаксис раньше, с одним регистром

fadd    ST0                     ; 2a

, но это подразумевает использование ST в качестве другого операнда и регистра назначения. В этом случае он добавляет ST0 к себе.

Обратите внимание на комментарии, в которых перечислено содержимое регистра сопроцессора ST0, ST1 ... и т. Д. Регистры образуют стек, поэтому следующая инструкция в последовательности

fld     qword[EBP+8]            ; a,2a

помещает другую копию того же значения в стек регистров, перемещая другое содержимое регистра вдоль одного, как показано в комментарии.

...