Tag: x86

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

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

如何使用gcc生成英特尔语法的汇编代码?

gcc -S选项会在AT&T语法中生成汇编代码,有没有一种方法可以在英特尔语法中生成文件? 或者有没有办法在两者之间进行转换?

在执行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兼容处理器是否正确?

rep rep是什么意思?

我在Visual Studio 2008上testing了一些代码,并注意到了security_cookie 。 我可以理解它的意义,但我不明白这个指令的目的是什么。 rep ret /* REP to avoid AMD branch prediction penalty */ 当然我可以理解评论:)但是这个前缀exaclty和ret上下文是什么关系?如果ecx是!= 0会发生什么? 显然ecx的循环计数在debugging的时候会被忽略,这是可以预料的。 我发现这里的代码是在这里(由编译器注入安全): void __declspec(naked) __fastcall __security_check_cookie(UINT_PTR cookie) { /* x86 version written in asm to preserve all regs */ __asm { cmp ecx, __security_cookie jne failure rep ret /* REP to avoid AMD branch prediction penalty */ […]

从64位进程调用32位代码

我有一个应用程序,我们试图从32位迁移到64位。 它是.NET,使用x64标志进行编译。 但是,我们有大量编译为32位的FORTRAN 90编写的DLL。 FORTRAN DLL中的函数非常简单:将数据放入数据中; 没有任何forms的状态。 我们也没有花太多时间,总共有3%,但是它所执行的计算逻辑是非常宝贵的。 我可以以某种方式从64位代码调用32位DLL? MSDNbuild议我不能,期限。 我做了一些简单的黑客行为,并validation了这一点。 一切都会引发无效的入口点exception。 目前唯一可能的解决scheme是为所有32位DLL函数创buildCOM +包装器,并从64位进程调用COM。 这似乎相当头痛。 我们也可以在WoW模拟中运行这个过程,但是内存的上限不会增加,上限为1.6GB左右。 有没有其他的方式来从64位CLR过程调用32位DLL?

什么是“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 […]