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

2019-01-27 17:12:18 +08:00
 doraos

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

3135 次点击
所在节点    问与答
22 条回复
lance6716
2019-01-27 17:32:39 +08:00
哪个汇编不支持 and or …
ech0x
2019-01-27 17:34:58 +08:00
你说的是汇编吗?汇编有布尔逻辑的指令的。
LuGew
2019-01-27 17:36:10 +08:00
别说汇编了,最基础的物理原件就是 nand 门
xenme
2019-01-27 17:44:38 +08:00
这不是最基本操作么?怎么可能不支持
momocraft
2019-01-27 17:48:05 +08:00
如果你在找 boolean 操作: 一般认为内存的最小操作单位是字节, 不会专门给 boolean 设计指令的, 用字节操作吧
ThirdFlame
2019-01-27 18:32:17 +08:00
随便找个程序 反汇编一下,就能看到一堆 and xor 之类的。
hx1997
2019-01-27 18:41:32 +08:00
LZ 问的是逻辑与或非,不是按位与或非…… 5L 是对的。
thedrwu
2019-01-28 00:16:47 +08:00
因为不需要。。。即使哪个 arch 有这类操作,也不会像高级语言里一行(一条指令)能写得下。
实在需要,可以用位操作代替一下,但是那样不能处理短路。
doraos
2019-01-28 00:50:07 +08:00
@lance6716 1 & 2 = 0 1&&2 = 1 汇编下 and 是& 吧, &&呢
doraos
2019-01-28 00:52:34 +08:00
@momocraft 请问如果我需要判断 A && B, 需要考虑到 1 && 2 情况(如果用 and 结果为 0),那么如果汇编没有提供一个像 c 那样按真值(非 0)的与运算,使用条件转移是否很浪费,还是我没有学到按真值的逻辑运算(查了表也没看见)
mario85
2019-01-28 01:28:56 +08:00
c 语言也是编译成条件转移的。
CPU 里面就一个游标指示程序运行到哪,实现你说的真值表反而是浪费。
sdijeenx
2019-01-28 01:32:50 +08:00
人类的本质之一:在网上查不到 == 自己没上网查
谁说查不到 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
2019-01-28 02:07:28 +08:00
@sdijeenx 这都是位运算
doraos
2019-01-28 02:09:13 +08:00
@mario85 x86 提供了上千个指令,那些特别指令想必性能提升不会比提供一个 c 语言常用的运算强
sdijeenx
2019-01-28 03:05:19 +08:00
刚才测试了下发现确实是组合指令,区别是&&用了 je,||用了 jne。
mario85
2019-01-28 03:40:54 +08:00
@doraos #14 那为什么他们就是不做实现呢?你再想想看吧
zerozerone
2019-01-28 04:33:39 +08:00
因为&&操作不够底层
geelaw
2019-01-28 05:38:57 +08:00
学习编译原理,理解短路求值是怎么实现的。
Akiyu
2019-01-28 08:25:27 +08:00
默认 and, or 操作是位运算而并非逻辑
我觉得应该是和 je 这种条件整合到了一起
(毕竟你拿到 bool 值不也是要作为条件来跳转的嘛, (大多数情况下))

而且位运算结果可以转化为 bool, 但是 bool 值不一定能转化为位运算的值
还有就是像 #17 说的那样
从汇编角度来看, && 应该是高层的抽象, 不应该由汇编来实现, 毕竟底层只有二进制
Akiyu
2019-01-28 08:37:52 +08:00
我试了一下汇编, 看了看结果
这是测试用的 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 轻点喷我)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/531035

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX