Tag: 汇编

MOV和LEA有何区别?

我想知道这些说明之间的区别是什么: MOV AX, [TABLE-ADDR] 和 LEA AX, [TABLE-ADDR]

为什么没有包含EAX的更高字节的寄存器?

%AX = (%AH + %AL) 那么为什么没有%EAX = (%SOME_RESTIER + %AX)的一些注册%SOME_REGISTER ?

在执行uop数量不是处理器宽度倍数的循环时性能是否降低?

我想知道在近期的x86处理器上,各种尺寸的循环如何作为uops数量的函数。 彼得·科尔德斯(Peter Cordes)的一句话引起了另外一个问题 : 我还发现,如果循环不是4个uops的倍数,那么循环缓冲区中的uop带宽不是每个周期4个常量。 (即它是abc,abc,…;不是abca,bcab,…)。 Agner Fog的微文档不幸的是在循环缓冲区的限制上并不清楚。 这个问题是关于循环是否需要N个uop的倍数来执行最大uop吞吐量,其中N是处理器的宽度。 (即4个用于最近的英特尔处理器)。 谈论“宽度”并计数微波时,有许多复杂的因素,但我最想忽略这些因素。 特别是,假设没有微观或macros观融合。 彼得给出了下面的例子,在它的内部有7个uops循环: 一个7-uop循环将发出4 | 3 | 4 | 3 |组…我还没有testing过较大的循环(不适合在循环缓冲区中),以查看下一个指令是否可能迭代在同一组中发出,但是我认为不是。 更一般地说,声明是每个迭代循环的x uops在它的体内至less需要ceil(x / 4)迭代,而不是简单的x / 4 。 这对一些或所有最近的x86兼容处理器是否正确?

什么是“FS”/“GS”寄存器?

所以我知道下面的寄存器和它们的用途应该是什么样的: CS =代码段(用于IP) DS =数据段(用于MOV) ES =目标段(用于MOVS等) SS =堆栈段(用于SP) 但是,下面的寄存器有什么用途呢? FS =“文件段”? GS = ??? 注意:我并没有问任何特定的操作系统 – 我问他们打算如何使用CPU,如果有的话。

“多核”汇编语言是什么样的?

曾几何时,为了编写x86汇编程序,例如,您将会得到说明“将EDX寄存器加载到数值5”,“增加EDX”寄存器等。 对于具有4核(或更多)的现代CPU,在机器代码级,它看起来像是有4个独立的CPU(即只有4个不同的“EDX”寄存器)吗? 如果是这样,当你说“递增EDX寄存器”时,决定哪个CPU的EDX寄存器递增? x86汇编程序中是否有“CPU上下文”或“线程”的概念? 内核之间的通信/同步如何工作? 如果你正在编写一个操作系统,那么通过硬件公开了什么机制,让你能够在不同的内核上安排执行? 这是一些特殊的特权指令吗? 如果您正在为多核CPU编写一个优化的编译器/字节码虚拟机,那么您需要具体了解x86,才能生成可在所有内核之间高效运行的代码? 对x86机​​器代码进行了哪些更改以支持多核function?

EBP帧指针寄存器的用途是什么?

我是汇编语言的初学者,并且注意到编译器发出的x86代码通常会保持帧指针,即使在发布/优化模式下,也可以使用EBP寄存器来实现其他function。 我明白为什么帧指针可能会使代码更易于debugging,并且如果在函数中调用alloca(),则可能是必需的。 然而,x86有很less的寄存器,并且使用其中的两个来保存堆栈帧的位置就足够了,这对我来说是没有意义的。 为什么即使在优化/发布版本中,忽略帧指针也是一个糟糕的主意?

INC指令与ADD 1:有关系吗?

大多数情况下,我现在远离INC和DEC,因为他们做了部分条件代码更新,这可能会导致pipe道中有趣的停顿,而ADD / SUB则不会。 所以在哪里不重要(大多数地方),我使用ADD / SUB来避免摊位。 我只在保持代码小的时候才使用INC / DEC,例如,在一个或两个指令的大小足够大的caching行中进行匹配。 这可能是毫无意义的纳米[字面上!] – 优化,但我在我的编码习惯相当老派。 作者:@Ira Baxter 上面的片段来自INC和DEC指令为什么不影响进位标志? 而且我想问一下,为什么会导致pipe道堵塞,而添加不了? 毕竟,add和inc都会更新标志寄存器。 唯一的区别是inc不更新CF. 但为什么这很重要?

为memcpy增强了REP MOVSB

我想使用增强的REP MOVSB(ERMSB)为自定义memcpy获取高带宽。 ERMSB是与Ivy Bridge微架构一起推出的。 如果您不知道ERMSB是什么,请参阅英特尔优化手册中的“增强型REP MOVSB和STOSB操作(ERMSB)”部分。 我知道直接做这件事的唯一方法是使用内联汇编。 我从https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE获得了以下function static inline void *__movsb(void *d, const void *s, size_t n) { asm volatile ("rep movsb" : "=D" (d), "=S" (s), "=c" (n) : "0" (d), "1" (s), "2" (n) : "memory"); return d; } 然而,当我使用这个时,带宽比memcpyless得多。 使用我的i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2, __movsb获得15 GB / s, memcpy获得26 […]

`testl` eax反对eax?

我想了解一些程序集。 大会如下,我对testl行感兴趣: 000319df 8b4508 movl 0x08(%ebp), %eax 000319e2 8b4004 movl 0x04(%eax), %eax 000319e5 85c0 testl %eax, %eax 000319e7 7407 je 0x000319f0 我想了解%eax和%eax之间的testl点吗? 我认为这个代码的重要性并不重要,我只是试图用自己来理解testing – 这个价值永远不会是真的吗?

为什么GCC在执行整数除法时使用奇数乘法?

我一直在阅读关于div和mul汇编操作,我决定通过在C: 文件分割 #include <stdlib.h> #include <stdio.h> int main() { size_t i = 9; size_t j = i / 5; printf("%zu\n",j); return 0; } 然后生成汇编语言代码: gcc -S division.c -O0 -masm=intel 但看着生成的division.s文件,它不包含任何div操作! 相反,它做了一些与位移和魔术数字的黑魔法。 这是一个计算i/5的代码片段: mov rax, QWORD PTR [rbp-16] ; Move i (=9) to RAX movabs rdx, -3689348814741910323 ; Move some magic number to RDX (?) mul […]