From what I've read, seems like there are 9 different flags. Is it possible to read/change them directly? I know I can know for example if the zero flag is set after doing a cmp/jmp instruction, but I'm asking if it's possible to do something like
mov eax, flags
Run Code Online (Sandbox Code Playgroud)
or something.
Also, for writing, is it possible to set them by hand?
使用以下代码是否存在任何执行速度差异:
cmp al, 0
je done
Run Code Online (Sandbox Code Playgroud)
以下内容:
or al, al
jz done
Run Code Online (Sandbox Code Playgroud)
我知道JE和JZ指令是相同的,并且使用OR可以提供一个字节的大小改进.但是,我也关心代码速度.逻辑运算符似乎比SUB或CMP更快,但我只是想确定.这可能是规模和速度之间的权衡,或双赢(当然代码将更加不透明).
在 x86-64 中设置和清除零标志 (ZF) 的最有效方法是什么?
无需具有已知值的寄存器或根本没有任何空闲寄存器即可工作的方法是首选,但如果在这些或其他假设为真时有更好的方法可用,则也值得一提。
我刚刚查看了彼得·科德斯(Peter Cordes)的回答,他说,
如果读取标志,则部分标志停顿会发生,如果它们确实发生的话。P4永远不会有部分标志停顿,因为它们永远不需要合并。相反,它具有错误的依赖关系。几个答案/评论混淆了术语。它们描述了一个错误的依赖关系,但随后将其称为部分标志停顿。这是由于仅写入一些标志而导致的速度下降,但是术语“部分标志停顿”是指必须合并部分标志写入时在SnB之前的Intel硬件上发生的情况。英特尔SnB系列CPU插入一个额外的uop来合并标志而不会停顿。Nehalem和更早的失速约7个周期。我不确定AMD CPU会受到多大的损失。
我感觉我还不明白什么是“部分国旗摊位”。我怎么知道一个人发生了?除了读取标志的某些时间之外,什么触发事件?合并标志是什么意思?在什么情况下会“写一些标志”,但不会发生部分标志合并?我需要了解哪些有关旗位的知识才能理解它们?
在编写x86-64用户空间程序集并比较两个指针值时,我们应该使用带符号的条件(例如jl
和)jge
还是使用无符号的条件(例如jb
和)jae
?
直觉上,我认为指针是无符号的,在64位进程的情况下,指针从0到2 ^ 64-1,并且我认为该模型对于32位代码是准确的。我想这就是大多数人对他们的看法。
但是,在64位代码中,我认为您无法有效地跨越0x7FFFFFFFFFFFFFFF
(2 ^ 63-1)处的有符号不连续性,并且许多有趣的内存区域倾向于聚集在有符号0附近(对于代码和静态数据,有时甚至是有时)堆的大小取决于实现),并且0x00007fffffffffff
在某些实现1的堆栈地址和堆附近接近规范地址空间下半部分的最大地址(类似于当今的大多数系统)。
因此,我不确定应该采用哪种方式对待它们:带符号的优点是它在0附近是安全的,因为那里没有间断;而无符号的优点是在2 ^ 63附近,因为那里没有间断。但是实际上,您不会在2 ^ 63附近看到任何地址,因为当前商用硬件的虚拟地址空间限制为小于50位。这是否指向签名?
1 ...,有时堆和其他映射区域不靠近地址空间的底部或顶部。