【问题标题】:What is the fld qword[EBP+8] in this quadratic equation code and also what does fadd ST0 do with just one argument?这个二次方程代码中的 fld qword[EBP+8] 是什么? fadd ST0 只用一个参数做什么?
【发布时间】:2019-04-19 07:03:15
【问题描述】:
    ; 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

【问题讨论】:

  • ray.masmcode.com/tutorial/index.html 涵盖了 x87 指令的基本功能以及寄存器堆栈。
  • 似乎有nasm -felf64 和gcc 命令的片段散布在您的代码中,例如-c rootsglobal _roots 指令中间。所以这完全是一团糟,如果没有一些编辑,实际上不会组装。 (如果你将它构建为 64 位,它会崩溃,这使用 32 位 EBP 所以使用nasm -felf / gcc -m32)。顺便说一句,它看起来效率低下:fchs / faddp 应该是 fsubrp st1 (反向减去而不是更改符号和添加。)而不是从内存中加载两次,您可以 fld st0 复制顶部堆栈。

标签: assembly x86 nasm x87


【解决方案1】:

这一行

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

从给定地址(在堆栈帧中)读取double 值并将其推入协处理器堆栈上的寄存器ST0,同时将所有其他寄存器移至一个。

我以前没有见过这种语法,只有一个寄存器

fadd    ST0                     ; 2a

但这意味着使用ST 作为另一个操作数和目标寄存器。在这种情况下,它会将ST0 添加到自身。

请观察 cmets,其中列出了协处理器寄存器内容 ST0ST1... 等。寄存器形成堆栈,以便按顺序执行下一条指令

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

将相同值的另一个副本推入寄存器堆栈,同时移动其他寄存器内容,如注释所示。

【讨论】:

  • 谢谢,最后一个问题是什么是 qword 用于
  • 表示操作数大小为8字节。对于 floatdoublelong double C 类型,数据可以是 4 (DWORD)、8 (QWORD) 或 10 (TBYTE) 字节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
相关资源
最近更新 更多