- 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/
我知道问题的标题听起来很奇怪,但我不知道该怎么调用它。 首先,我有一个网格布局,我希望我的 .search-wrapper 宽度为 50% 并向右浮动。在我的演示中 jsfiddle整个 .searc
我们正在使用 QA-C 来实现 MISRA C++ 一致性,但是该工具会为这样的代码喷出错误: float a = foo(); float b = bar(); float c = a - b; 据
考虑 float a[] = { 0.1, 0.2, 0.3}; 我很困惑a稍后传递给函数 foo(float* A) .不应该是 float* 类型的变量指向单个浮点数,对吗?就像这里提到的tu
这可能是我一段时间以来收到的最好的错误消息,我很好奇出了什么问题。 原代码 float currElbowAngle = LeftArm ? Elbow.transform.localRotation
刚开始学习 F#,我正在尝试为 e 生成和评估泰勒级数的前 10 项。我最初编写了这段代码来计算它: let fact n = function | 0 -> 1 | _ -> [1
我已经使用 Erlang 读取二进制文件中的 4 个字节(小端)。 在尝试将二进制转换为浮点时,我一直遇到以下错误: ** exception error: bad argument in
假设我有: float a = 3 // (gdb) p/f a = 3 float b = 299792458 // (gdb) p/f b = 29979244
我每次都想在浏览器顶部修复这个框。但是右边有一些问题我不知道如何解决所以我寻求帮助。 #StickyBar #RightSideOfStickyBar { float : right ; }
我正在研究 C# 编译器并试图理解数学运算规则。 我发现在两种不同的原始类型之间使用 == 运算符时会出现难以理解的行为。 int a = 1; float b = 1.0f; Cons
假设我有: float a = 3 // (gdb) p/f a = 3 float b = 299792458 // (gdb) p/f b = 29979244
Denormals众所周知,与正常情况相比,表现严重不佳,大约是 100 倍。这经常导致 unexpected软件 problems . 我很好奇,从 CPU 架构的角度来看,为什么非规范化必须是 那
我有一个由两个 float 组成的区间,并且需要生成 20 个随机数,看起来介于两个 float 定义的区间之间。 比方说: float a = 12.49953f float b = 39.1123
我正在构建如下矩阵: QMatrix4x3 floatPos4x3 = QMatrix4x3( floatPos0.at(0), floatPos1.at(0), floatPos2.at(0),
给定归一化的浮点数f,在f之前/之后的下一个归一化浮点数是多少。 通过微动,提取尾数和指数,我得到了: next_normalized(double&){ if mantissa is n
关于 CSS“float”属性的某些东西一直让我感到困惑。为什么将“float”属性应用到您希望 float 的元素之前的元素? 为了帮助可视化我的问题,我创建了以下 jsFiddle http://
关于 CSS“float”属性的某些东西一直让我感到困惑。为什么将“float”属性应用到您希望 float 的元素之前的元素? 为了帮助可视化我的问题,我创建了以下 jsFiddle http://
我有一个新闻源/聊天框。每个条目包含两个跨度:#user 和#message。我希望#user 向左浮动,而#message 向左浮动。如果#message 导致行超过容器宽度,#message 应该
我想创建一个“记分卡”网格来输出一些数据。如果每个 div.item 中的数据都具有相同的高度,那么在每个 div.item 上留下一个简单的 float 会提供一个漂亮的均匀布局,它可以根据浏览器大
我正在学习使用 CSS float 属性。我想了解此属性的特定效果。 考虑以下简单的 HTML 元素: div1 div2 This is a paragraph 以及以下 CSS 规则: div {
我正在尝试从可以是 int 或 float 的文件中提取数据。我发现这个正则表达式将从文件 (\d+(\.\d+)?) 中提取这两种类型,但我遇到的问题是它将 float 拆分为两个。 >>> imp
我是一名优秀的程序员,十分优秀!