- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
作为编译器项目的一部分,我必须为 x86 编写 GNU 汇编程序代码来比较浮点值。我试图找到有关如何在线执行此操作的资源,据我所知,它是这样工作的:
假设我要比较的两个值是浮点堆栈上的唯一值,那么 fcomi
指令将比较这些值并设置 CPU 标志,以便 je
, jne
, jl
, ... 可以使用指令。
我问是因为这只在某些时候有效。例如:
.section .data
msg: .ascii "Hallo\n\0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomi
jg leb
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit
不会打印“Hallo”,即使我认为它应该打印,如果你切换 f1 和 f2 它仍然不会,这是一个逻辑矛盾。 je
和 jne
不过似乎工作正常。
我做错了什么?
PS:fcomip 只弹出一个值还是同时弹出两个值?
最佳答案
TL:DR: 使用高于/低于条件(如无符号整数)来测试比较结果。
对于各种historical reasons (映射 from FP status word to FLAGS via fcom
/ fstsw
/ sahf
与 fcomi
(PPro 中的新功能)匹配),FP 比较集合 CF,而不是 OF/SF。另见 http://www.ray.masmcode.com/tutorial/fpuchap7.htm
现代 SSE/SSE2 标量与 FLAGS 比较 follow this as well , 与 [u]comiss
/sd
。 (不像 SIMD 比较,它有一个谓词作为指令的一部分,作为立即数,因为它们只为每个元素产生一个全零/全一结果,而不是一组标志。)
这全部来自 Intel 64 and IA-32 Architectures Software Developer's Manuals 的第 2 卷.
FCOMI
只设置了 CMP
所做的一些标志。您的代码有 %st(0) == 9
和 %st(1) == 10
。 (因为是栈上加载的),引用卷2A第3-348页的表格可以看到是这样的“ST0 < ST(i)”,所以会清除ZF和PF并置位CF。同时在 pg. 3-544 卷。 2A 您可以读到 JG
的意思是“如果大于(ZF=0 和 SF=OF)则跳转较短”。换句话说,它正在测试符号、溢出和零标志,但是 FCOMI
没有设置符号或溢出!
根据你想跳的条件,看可能的比较结果,决定什么时候跳。
+--------------------+---+---+---+| Comparison results | Z | P | C |+--------------------+---+---+---+| ST0 > ST(i) | 0 | 0 | 0 || ST0 < ST(i) | 0 | 0 | 1 || ST0 = ST(i) | 1 | 0 | 0 || unordered | 1 | 1 | 1 | one or both operands were NaN.+--------------------+---+---+---+
I've made this small table to make it easier to figure out:
+--------------+---+---+-----+------------------------------------+| Test | Z | C | Jcc | Notes |+--------------+---+---+-----+------------------------------------+| ST0 < ST(i) | X | 1 | JB | ZF will never be set when CF = 1 || ST0 <= ST(i) | 1 | 1 | JBE | Either ZF or CF is ok || ST0 == ST(i) | 1 | X | JE | CF will never be set in this case || ST0 != ST(i) | 0 | X | JNE | || ST0 >= ST(i) | X | 0 | JAE | As long as CF is clear we are good || ST0 > ST(i) | 0 | 0 | JA | Both CF and ZF must be clear |+--------------+---+---+-----+------------------------------------+Legend: X: don't care, 0: clear, 1: set
In other words the condition codes match those for using unsigned comparisons. The same goes if you're using FMOVcc
.
If either (or both) operand to fcomi
is NaN, it sets ZF=1 PF=1 CF=1
. (FP compares have 4 possible results: >
, <
, ==
, or unordered). If you care what your code does with NaNs, you may need an extra jp
or jnp
. But not always: for example, ja
is only true if CF=0 and ZF=0, so it will be not-taken in the unordered case. If you want the unordered case to take the same execution path as below or equal, then ja
is all you need.
Here you should use JA
if you want it to print (ie. if (!(f2 > f1)) { puts("hello"); }
) and JBE
if you don't (corresponds to if (!(f2 <= f1)) { puts("hello"); }
). (Note this might be a little confusing due to the fact that we only print if we don't jump).
Regarding your second question: by default fcomi
doesn't pop anything. You want its close cousin fcomip
which pops %st0
. You should always clear the fpu register stack after usage, so all in all your program ends up like this assuming you want the message printed:
.section .rodata
msg: .ascii "Hallo\n\0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomip
fstp %st(0) # to clear stack
ja leb # won't jump, jbe will
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit
关于x86 汇编程序 : floating point compare,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51801956/
我经常有一个 Comparator 类型,而我需要一个 Comparable 类型,反之亦然。是否有可重用的 JDK API 可以相互转换?类似的东西: public static Comp
我怎么能写这个 Comparator sort = (i1, i2) -> Boolean.compare(i2.isOpen(), i1.isOpen()); 像这样(代码不起作用): Compa
请帮助她。我有一个错误 Collections.sort(var4, new Comparator() { public int compare(TreeMap var1, TreeMa
学习 Kotlin,我试图了解 Java 的 Comparator接口(interface)有效 - 主要是 compare() 函数,这样我就可以利用它。 我已经尝试阅读 compare() 的文档
我有以下程序 List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); Collections.sort(numbers, (
我想根据嵌套类的属性对如下所示的列表进行排序。 class Test { private NestedClass nestedClass; private AnotherNes
我很好奇“Beyond Compare”的算法是如何工作的? 我猜想他们使用了一种标准的(众所周知的?)算法来实现“字符与字符”的比较。你知道这个算法的名字吗?谢谢 最佳答案 Beyond Compa
这个问题已经有答案了: How does the sort() method of the Collection class call the Comparable's compareTo()? (1
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicates: difference between compare() and compareTo() Java: What i
我被要求为某个类实现Comparable或Compartor,我们称之为V。 假设我有一个 V 的 Collection 或 Set(还不确定,但我认为这并不重要)。 V 有一个方法,可以评估它的“权
我正在查看Java8中实现的Comparator.comparing方法的源代码 这是代码 public static Comparator comparing( Function
假设我有一个类 ClassA,它的属性是 ClassB: public ClassA { private String attr; private ClassB classB; } p
我有一个自定义比较器,其比较逻辑如下: List l = new ArrayList(); l.add("tendercoupon"); l.add("giftcard
我正在努力实现一个处理 Comparator 和 Comparable 接口(interface)的层次结构。我不清楚的几件事: 如果我将比较器添加到比较器链中,这段代码究竟意味着什么 chain.a
正在关注 this question关于按另一个列表对列表进行排序,我尝试做同样的事情 - 但由于某种原因它对我不起作用。我错过了什么? List nums = Arrays.asList(5
假设我有一个像这样的领域模型: class Lecture { Course course; ... // getters } class Course { Teache
在表达式 > 中像这样的签名 public static > foo(T x) { ... } T的描述递归地依赖于Comparable . 如果T延伸Comparable ,和Comparable延
所有“数字”比较器(例如 Comparer.Default 、 Comparer.Default 等)返回 -1 的原因是什么? , 0或 1 ,但是 Comparer.Default和 Compar
(如果这是重复的,请指出正确的答案!我搜索并阅读了几个(> 5)个相关问题,但似乎没有一个是正确的。还查看了泛型常见问题解答和其他来源...) 当一个集合类接受一个比较器时,它应该具有 Compara
SBCL 1.3.1 综上所述,a是一个列表,'(7),b通过setq sbcl This is SBCL 1.3.1.debian, an implementation of ANSI Common
我是一名优秀的程序员,十分优秀!