Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在汇编中做某事与让汇编人员做某事_Assembly_X86 - Fatal编程技术网

Assembly 在汇编中做某事与让汇编人员做某事

Assembly 在汇编中做某事与让汇编人员做某事,assembly,x86,Assembly,X86,以下两种方法中哪一种更适合获得2^n-1?为什么一个比另一个更受欢迎 # (2a) -- instructions mov $1, %eax shl $X, %eax dec %eax # (2b) -- assembler mov $((1 << X) - 1), %eax 我个人觉得第一个更可读,但我很确定可读性不是asm的重点。总是在每次构建时在汇编时尽可能多地执行一次,而不是在运行时,因为在运行时它会消耗代码大小,并且每次执行此块都会消耗时间 它们都以相同的mov$imm

以下两种方法中哪一种更适合获得2^n-1?为什么一个比另一个更受欢迎

# (2a) -- instructions
mov $1, %eax
shl $X, %eax
dec %eax

# (2b) -- assembler
mov $((1 << X) - 1), %eax
我个人觉得第一个更可读,但我很确定可读性不是asm的重点。

总是在每次构建时在汇编时尽可能多地执行一次,而不是在运行时,因为在运行时它会消耗代码大小,并且每次执行此块都会消耗时间

它们都以相同的mov$imm32、%eax形式的mov开始,但是第一个版本浪费了2条额外的指令,所以它完全是垃圾,没有任何优势,对于习惯于考虑效率的人来说,它看起来超级丑陋和疯狂

没有编译器可以将您的代码优化为CPU可以高效运行的内容,这取决于您如何实现。如果您不关心性能,基本上没有理由一开始就乱搞asm 1,不管是手工编写还是考虑编译器输出

<> P>你甚至不得不问这是一个标志,你要么错过汇编语言的性能,要么你错误地认为ASM和编译C++语言一样。您需要调整您的心智模型,以考虑您正在创建的机器代码、CPU将执行的机器代码,以及如何使其尽可能高效

你需要像编译器一样思考;如何在前端以尽可能少的UOP实现这一点,以字节为单位的最小代码大小作为连接断路器。或者,根据您的目标,可能会优化代码大小而不是速度。但无论如何,编译器会积极地评估表达式,并尽可能地进行常量传播,以便将源代码中的常量组合到编译时工作中,而不是运行时

脚注1: 在这种情况下,用一种有很好的优化编译器的语言编写,例如C或Rust,让它为您创建机器代码。尽管公平地说,如果您对asm和C都同样熟悉,那么asm中的一些事情比C更容易,例如扩展精度数学。很少有高级语言可以使使用其他操作的进位输出变得容易

可读性:

您100%正确地认识到,在asm中,可读性通常不是最重要的;在任何值得手工编写asm的情况下,代码大小和/或性能总是处于次要地位。但在这些限制条件下,我们当然可以尽可能追求可读性

您的运行时计算方式对于阅读您的代码的有经验的asm用户来说是非常令人惊讶的,而且一点也不习惯。如果我在其他健全的代码中遇到这个问题,我需要花一些时间来仔细检查并确保我正确理解它。例如,可能毕竟有一些非常量输入,或者可能这会以某种方式设置标志,这也是以后需要的

在运行时执行工作的唯一原因是,它不可能在编译时执行,因为它不是常量,所以看到输入来自的移位是非常令人惊讶的。如果我看到在生产代码中创建32位常量的3条指令序列,而不是关于堆栈溢出的初学者问题,我会对编写它的人的无能感到震惊,因为他们发现它只是创建了一个32位常量

除此之外,运行时版本还有2条指令需要读取,如果这是作为更大代码块的一部分出现的话。在asm中,以每源代码行完成的数量表示的代码密度已经很低,所以最小化指令计数通常有利于函数的整体可读性

除了用替换像div这样的慢指令这样的情况外,它通常也有利于提高效率。但这对于可读性来说已经足够糟糕了,如果性能不是该函数或代码块的最高优先级,例如,因为它不经常运行,那么手工编写的asm将一个立即数移动到寄存器,然后按它进行div就不会太奇怪了。除非除数是2的幂,否则它只是一个比右移更愚蠢、更不方便的选择


1如有可能,让装配工进行装配。这在运行时节省了时间。@fuz ok-汇编程序能够做算术以外的事情吗,或者主要是这样吗?除了常数和命名常数的算术之外,我们可以利用两个标签之间的差异,通常很方便,并且可以从标签中偏移。并非所有的汇编程序都能计算编译时常量,因为它需要汇编程序表达式求值、解析和解释的实际工作,并且需要与常规指令进行语法区分,这在某些情况下非常有用,因此一个认真的汇编人员应该……。。@carl.hias您可以编写宏来完成更多复杂的事情。你有什么想法?没有正确的答案,一个是特定于工具的,所以不总是有效的。但归根结底,这是个人的偏好,你们使用汇编语言是因为你们想控制局面还是因为你们想使用高级语言。是th吗 说明的可读性或控制性等。主要基于意见。
#define SHIFT2MASK(x_)  ((1<<x_)-1)

...
X=3

mov   $SHIFT2MASK(X), %eax

and   $SHIFT2MASK(4), %ecx