V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
doraos
V2EX  ›  问与答

大部分汇编是不是没有逻辑或.与.异操作,为什么

  •  
  •   doraos · 2019-01-27 17:12:18 +08:00 · 3336 次点击
    这是一个创建于 2126 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学汇编,发现无论 x86 还是 mips,都没有在 c 语言中非常重要的按逻辑&& || !操作(也有可能我没学到),(在网上也查不到&&这类的操作).这可能给编程带来很大的困扰,需要用别的指令来组合,不知道是不是这样子的

    22 条回复    2019-01-28 10:26:06 +08:00
    lance6716
        1
    lance6716  
       2019-01-27 17:32:39 +08:00 via Android   ❤️ 1
    哪个汇编不支持 and or …
    ech0x
        2
    ech0x  
       2019-01-27 17:34:58 +08:00 via iPhone   ❤️ 1
    你说的是汇编吗?汇编有布尔逻辑的指令的。
    LuGew
        3
    LuGew  
       2019-01-27 17:36:10 +08:00 via Android   ❤️ 1
    别说汇编了,最基础的物理原件就是 nand 门
    xenme
        4
    xenme  
       2019-01-27 17:44:38 +08:00 via iPhone   ❤️ 1
    这不是最基本操作么?怎么可能不支持
    momocraft
        5
    momocraft  
       2019-01-27 17:48:05 +08:00   ❤️ 1
    如果你在找 boolean 操作: 一般认为内存的最小操作单位是字节, 不会专门给 boolean 设计指令的, 用字节操作吧
    ThirdFlame
        6
    ThirdFlame  
       2019-01-27 18:32:17 +08:00   ❤️ 1
    随便找个程序 反汇编一下,就能看到一堆 and xor 之类的。
    hx1997
        7
    hx1997  
       2019-01-27 18:41:32 +08:00 via Android   ❤️ 1
    LZ 问的是逻辑与或非,不是按位与或非…… 5L 是对的。
    thedrwu
        8
    thedrwu  
       2019-01-28 00:16:47 +08:00 via Android   ❤️ 1
    因为不需要。。。即使哪个 arch 有这类操作,也不会像高级语言里一行(一条指令)能写得下。
    实在需要,可以用位操作代替一下,但是那样不能处理短路。
    doraos
        9
    doraos  
    OP
       2019-01-28 00:50:07 +08:00
    @lance6716 1 & 2 = 0 1&&2 = 1 汇编下 and 是& 吧, &&呢
    doraos
        10
    doraos  
    OP
       2019-01-28 00:52:34 +08:00
    @momocraft 请问如果我需要判断 A && B, 需要考虑到 1 && 2 情况(如果用 and 结果为 0),那么如果汇编没有提供一个像 c 那样按真值(非 0)的与运算,使用条件转移是否很浪费,还是我没有学到按真值的逻辑运算(查了表也没看见)
    mario85
        11
    mario85  
       2019-01-28 01:28:56 +08:00 via iPhone   ❤️ 1
    c 语言也是编译成条件转移的。
    CPU 里面就一个游标指示程序运行到哪,实现你说的真值表反而是浪费。
    sdijeenx
        12
    sdijeenx  
       2019-01-28 01:32:50 +08:00   ❤️ 1
    人类的本质之一:在网上查不到 == 自己没上网查
    谁说查不到 LZ 就是懒得找已。


    and, or, xor — Bitwise logical and, or and exclusive or
    These instructions perform the specified logical operation (logical bitwise and, or, and exclusive or, respectively) on their operands, placing the result in the first operand location.
    Syntax
    and <reg>,<reg>
    and <reg>,<mem>
    and <mem>,<reg>
    and <reg>,<con>
    and <mem>,<con>

    or <reg>,<reg>
    or <reg>,<mem>
    or <mem>,<reg>
    or <reg>,<con>
    or <mem>,<con>

    xor <reg>,<reg>
    xor <reg>,<mem>
    xor <mem>,<reg>
    xor <reg>,<con>
    xor <mem>,<con>

    Examples
    and eax, 0fH — clear all but the last 4 bits of EAX.
    xor edx, edx — set the contents of EDX to zero.

    not — Bitwise Logical Not
    Logically negates the operand contents (that is, flips all bit values in the operand).
    Syntax
    not <reg>
    not <mem>

    Example
    not BYTE PTR [var] — negate all bits in the byte at the memory location var.


    www.cs.virginia.edu/~evans/cs216/guides/x86.html
    doraos
        13
    doraos  
    OP
       2019-01-28 02:07:28 +08:00
    @sdijeenx 这都是位运算
    doraos
        14
    doraos  
    OP
       2019-01-28 02:09:13 +08:00
    @mario85 x86 提供了上千个指令,那些特别指令想必性能提升不会比提供一个 c 语言常用的运算强
    sdijeenx
        15
    sdijeenx  
       2019-01-28 03:05:19 +08:00   ❤️ 1
    刚才测试了下发现确实是组合指令,区别是&&用了 je,||用了 jne。
    mario85
        16
    mario85  
       2019-01-28 03:40:54 +08:00 via iPhone   ❤️ 1
    @doraos #14 那为什么他们就是不做实现呢?你再想想看吧
    zerozerone
        17
    zerozerone  
       2019-01-28 04:33:39 +08:00 via Android   ❤️ 1
    因为&&操作不够底层
    geelaw
        18
    geelaw  
       2019-01-28 05:38:57 +08:00 via iPhone   ❤️ 1
    学习编译原理,理解短路求值是怎么实现的。
    Akiyu
        19
    Akiyu  
       2019-01-28 08:25:27 +08:00   ❤️ 1
    默认 and, or 操作是位运算而并非逻辑
    我觉得应该是和 je 这种条件整合到了一起
    (毕竟你拿到 bool 值不也是要作为条件来跳转的嘛, (大多数情况下))

    而且位运算结果可以转化为 bool, 但是 bool 值不一定能转化为位运算的值
    还有就是像 #17 说的那样
    从汇编角度来看, && 应该是高层的抽象, 不应该由汇编来实现, 毕竟底层只有二进制
    Akiyu
        20
    Akiyu  
       2019-01-28 08:37:52 +08:00   ❤️ 1
    我试了一下汇编, 看了看结果
    这是测试用的 c++ 代码:
    --------------------
    int i = 1, i2 = 10;
    printf("%d\n", i & i2);
    printf("%d\n", i && i2);
    --------------------
    编译选项为 g++ -std=c++0x -S t.cpp, 编译器版本 4.4.7

    以下是汇编代码
    --------------------
    subq $16, %rsp
    movl $1, -8(%rbp)
    movl $10, -4(%rbp)
    movl -4(%rbp), %eax
    movl -8(%rbp), %edx
    andl %edx, %eax
    movl %eax, %esi
    movl $.LC0, %edi
    movl $0, %eax
    call printf
    cmpl $0, -8(%rbp)
    je .L2
    cmpl $0, -4(%rbp)
    je .L2
    movl $1, %eax
    jmp .L3
    .L2:
    movl $0, %eax
    .L3:
    movzbl %al, %eax
    movl %eax, %esi
    movl $.LC0, %edi
    movl $0, %eax
    call printf
    movl $0, %eax
    leave
    --------------------
    && 是将 i 和 i2 都与 0 做对比,
    一旦结果相同(je), 直接跳转 .L2 赋值为 0, 否则默认赋值为 1, 然后跳转 .L3
    所以你这样认为, && 只是语言对汇编做的封装, 对于编译器来说, 没有这个操作
    (当然, 这个例子不怎么好, dalao 轻点喷我)
    lance6716
        21
    lance6716  
       2019-01-28 10:03:26 +08:00 via Android   ❤️ 1
    @doraos 1 && 2 这个具体表达的是 true && true 的意思,如果 A、B 存在 rax、rbx 里
    test rax rax
    jz 0logic
    test rbx rbx
    jz 0logic
    all1logic

    我认为这个是处理 0 表示 false,非 0 表示 true 比较复杂,没法直接套用 and
    AnsonUTF8
        22
    AnsonUTF8  
       2019-01-28 10:26:06 +08:00 via iPhone   ❤️ 1
    了解下 risc 和 cisc
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   924 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 22:18 · PVG 06:18 · LAX 14:18 · JFK 17:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.