【问题标题】:Assembly: JA and JB work incorrectly装配:JA 和 JB 工作不正确
【发布时间】:2016-12-26 16:50:36
【问题描述】:

由于我的主要操作系统是 linux 并且在 Visual Studio 上有项目,我决定使用在线编译器来实现它。我找到了很多人建议的this。所以这是我的代码:

#include <iostream>

using namespace std;
int main(void) {
float a = 1;
float b = 20.2;
float res = 0;
float res1 = 0;

_asm { 

    FLD a
    FCOM b
    JA midi
    JMP modi           

    midi:
    FST res
    JMP OUT

    modi:
    FST res1
    JMP OUT


}
    OUT:
cout << "res = " << res << endl;
cout << "res1 = " << res1 << endl;
return 0;
}

我的目标很简单,如果a 大于b,则将a 放入res,否则放入res1。但似乎我在变量a 中拥有的任何东西总是跳到midi 上,结果总是res = whatever is in a。希望你能帮忙。对不起,如果我的问题很愚蠢,我刚刚开始学习组装。谢谢 :)

附注
JB 也是如此,但相反。它总是打印res1 = whatever is in b

【问题讨论】:

    标签: c++ assembly x86 fpu


    【解决方案1】:

    来自this page

    FCOM 将 ST0 与给定的操作数进行比较,并设置 FPU 标志 相应地。

    但是您的 JA midi 正在测试 CPU 标志。

    继续:

    FCOMI 和 FCOMIP 的工作方式类似于 FCOM 和 FCOMP 的相应形式, 但将他们的结果直接写入 CPU 标志寄存器而不是 比 FPU 状态词,所以它们可以紧跟在后面 条件跳转或条件移动指令。

    【讨论】:

    • 我收到一条错误消息:source_file.cpp(13): error C2414: illegal number of operands
    • @Rasty 似乎FCOMI 无法获取内存操作数 - 将其加载到寄存器中。但是你有你的代码不起作用的基本原因。
    • 抱歉,我发帖的时候没有看到你的答案:(我已经写好了,所以我保留它
    • @MargaretBloom 当然 - 你的研究得更好。
    • 请注意,FCOMIFCOMIPFUCOMIFUCOMIP 需要 Pentium Pro 或更高版本的处理器。这对于所有在 16 位模拟器中学习汇编的人来说可能很重要!
    【解决方案2】:

    这是一个常见的陷阱,FCOM 没有在标志寄存器中设置标志,它在 FPU 状态字中设置条件代码标志。
    来自Intel manual 2

    比较寄存器ST(0)的内容和源值并在FPU中设置条件码标志C0C2C3 根据结果​​的状态字(见下表)

    你可以看到C3扮演ZFCFC1角色。

    使用FCOMI/FUCOMI(和变体)相应地设置标志。

    对寄存器 ST(0) 和 ST(i) 的内容进行无序比较,并设置状态标志 ZF、PF 和 CF根据EFLAGS寄存器中的结果[表同上,其中C2PF]。

    FCOMIFUCOMI 之间的区别在于后者允许无序操作数,即 qNaN。


    或者,您仍然可以使用FCOM,但随后将条件代码移动到标志:

    fnstsw ax        ;FP Not-checked STore Status Word in AX
    sahf             ;Store AH into flags
    

    英特尔将fnstsw 设计为与sahf 兼容。
    前者将C3C2C1分别移动到AH的bit6、bit2和bit0。
    后者将标志设置为RFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH


    您也可以在fnstsw ax 之后直接test ax,如manual 18.3.6.1 在x87 FPU 条件代码上的分支 部分所述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-05
      • 2015-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      相关资源
      最近更新 更多