【问题标题】:If Statement with And operator condition in AT&T AssemblyAT&T 程序集中带有 And 运算符条件的 If 语句
【发布时间】:2018-11-05 11:20:01
【问题描述】:

我将如何在AT&T Assembly 中使用 and 运算符作为条件执行 if 语句?

assume x = 0x60
assume y = 0x45

例如:

if(x and y)
    //do something

这是正确的代码吗?

.globl func

func:
    push %r10     //r10 = x
    push %r11     //r11 = y
    movq $0x60, %r10        
    movq $0x45, %r11
    jmp .loop

.loop:
     movq %r10, %r12
     and $r11, %r12
     cmpq $0xFF, %r12
     je .if
     jmp .done
.if:
     //Do something here
     jmp .done     
.done:
    pop %r10     //r10 = x
    pop %r11     //r11 = y
    ret

【问题讨论】:

  • 您的and 运算符是按位与还是逻辑与?

标签: if-statement assembly conditional-statements operator-keyword


【解决方案1】:

代码审查:

您的代码过于复杂。 (但这对于初学者来说很正常;如果你在 asm 方面有更多经验后再回顾这一点,你会说同样的话。)

您不需要保存/恢复 r10 或 r11:允许函数破坏它们。即他们被呼叫破坏。通常,您会使用诸如 eax/rax 和 edx/rdx 之类的“传统”寄存器(由于您的数字很小,因此具有 32 位操作数大小)来节省代码大小。但是您可以担心以后保存 REX 前缀; r10 和 r11 没问题。

您不需要任何jmp 指令。 下一行的jmp 是多余的,并且无操作:执行会自行落到下一行,无论是否有标记那里与否。

如果条件为假,您只需要一个jejne 即可跳过.if 块。


if 分支

您的and/cmp 条件对于布尔值或按位and 没有意义。为什么只有设置了所有 8 位才成立?像pcmpeqb 这样的 SSE2 SIMD 指令会产生 0 或 0xFF 比较结果,但如果两个输入操作数都不为零,则没有指令会产生 0xFF。 (所以你实现的是if ((x&y) == 0xFF)

对于按位,if(x & y),使用test %r10,%r11 / jz .done。对于布尔值,x 上的测试和分支非零(test %r10,%r10 / jz .done,然后对 y 重复。

.globl bitwise_and     # args:  x in RDI,   y in RSI
bitwise_and:           # x86-64 System V calling convention

    test  %rdi, %rsi     # set flags according to x&y
    jz    .Lfalse        # skip the next block if (x&y) == 0
        # if condition was true, fall into the if block

    .Lfalse:
    ret

或布尔值

.globl boolean_and     # args:  x in RDI,   y in RSI
boolean_and:

    test  %rdi, %rdi
    jz    .Lfalse
    test  %rsi, %rsi
    jz    .Lfalse
        # if condition was true, fall into the if block

    .Lfalse:
    ret

不幸的是,x86 没有一种非常好的方法来仅使用一条分支指令来检查任一输入是否为零。像 C 的 x && y 运算符的短路行为一样分别检查每个输入是编译器经常做的。

对于x || y,这要好得多:x || yx | y 为真时相同的情况下为真,所以我们可以只做or %rdi, %rsi,它根据结果设置标志。如果 OR 结果为零,则jz 跳过if 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    相关资源
    最近更新 更多