x86 程序集:比较(GAS 语法)

Posted

技术标签:

【中文标题】x86 程序集:比较(GAS 语法)【英文标题】:x86 Assembly: Comparisons (GAS syntax) 【发布时间】:2013-08-08 10:00:55 【问题描述】:

我相信在 x86 中实现跳转的标准方法是与以下内容进行比较:

cmpl %ebx, %eax

它将结果存储在 eflags 寄存器中,然后下面的跳转命令使用该 eflags 寄存器:

je some_label

但是如果我想保存比较的结果以便以后进行跳转怎么办?我想过做类似的事情:

    cmpl %eax, %ebx
    je storetrue
storefalse:
    pushl $0
    jmp done
storetrue:
    pushl $1
done:
    ...

我需要这样做还是有不需要额外跳转的更直接的方法?

【问题讨论】:

Flags registers - Can we read or write them directly? 使用conditional move 指令。 这很有用,但没有准确解释在复制(部分)标志寄存器时如何得出比较结果 有条件的移动正是我想要的,谢谢。 还有SETcc 【参考方案1】:

我想到了一些方法。

    正如问题 cmets 中已经提到的,您可以使用条件移动指令。 您可以使用 SETxx 指令将 8 位寄存器之一设置为 0 或 1。 您可以使用 PUSHF 指令将 EFLAGS 寄存器的副本保存到堆栈中。可以使用 POPF 指令恢复。 您可以精心设计您的代码,以便下次您希望使用该比较的结果时,它不会使用修改 EFLAGS 寄存器的指令。 根据您的用例,您可以制作一个简单的算术表达式,该表达式将产生 0 或 1 或其他所需值(我个人更喜欢 0 或 -1 的组合,因为这样转换变得微不足道任何 X 或 Y 对,使用 AND 后跟 ADD)。

希望这会有所帮助。

【讨论】:

所以如果我要使用比较,然后 pushf,做一些改变 cflags 的东西,然后 popf,然后跳转,我实际上是在做同样的跳转,如果我会做的话初步比较后直接跳了吗? @AlexJ136 - 只要您使用 POPF 从堆栈中弹出的数据与您使用 PUSHF 压入堆栈的数据相同,那么可以。

以上是关于x86 程序集:比较(GAS 语法)的主要内容,如果未能解决你的问题,请参考以下文章

将 scanf 与 x86-64 GAS 程序集一起使用

x86 AT&T 语法程序集的注释语法

x86 程序集:“subl”命令如何在 AT&T 语法中工作

我可以将 x86 程序集的 Intel 语法与 GCC 一起使用吗?

NASM 与 GAS(实际差异)

cmp 不工作 - Intel x86 (IA32) 程序集