Questions tagged «x86»

x86是派生自Intel 8086 CPU的体系结构。x86系列包括32位IA-32和64位x86-64架构,以及传统的16位架构。关于后者的问题应标记为[x86-16]和/或[emu8086]。如果您的问题特定于64位x86-64,请使用[x86-64]标记。对于x86 FPU,使用标签[x87]。对于SSE1 / 2/3/4 / AVX *,也请使用[sse],以及适用的[avx] / [avx2] / [avx512]中的任何一个

3
将参数std :: min更改为浮点数的编译器输出
我在Compiler Explorer中摆弄东西,发现传递给std :: min的参数顺序更改了发出的程序集。 这是Godbolt编译器资源管理器上的示例 double std_min_xy(double x, double y) { return std::min(x, y); } double std_min_yx(double x, double y) { return std::min(y, x); } 它将被编译(例如,在clang 9.0.0上用-O3)为: std_min_xy(double, double): # @std_min_xy(double, double) minsd xmm1, xmm0 movapd xmm0, xmm1 ret std_min_yx(double, double): # @std_min_yx(double, double) minsd xmm0, xmm1 ret 如果我将std :: …

2
在x86汇编中使用哪个可变大小(db,dw,dd)?
我是汇编的初学者,我不知道所有db,dw,dd的含义是什么。我试图编写一个执行1 + 1的小脚本,将其存储在变量中,然后显示结果。到目前为止,这是我的代码: .386 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib .data num db ? ; set variable . Here is where I don't know what data type to use. .code start: mov eax, 1 ; add 1 to eax register …

8
使用浮点数快两倍吗?
双精度值存储更高的精度,并且是浮点数的两倍,但是Intel CPU是否针对浮点数进行了优化? 也就是说,对于+,-,*和/,双精度运算是否与浮点运算一样快或更快? 对于64位体系结构,答案是否会改变?

3
std :: atomic的锁在哪里?
如果数据结构中包含多个元素,则其原子版本不能(始终)是无锁的。有人告诉我,这对于较大的类型是正确的,因为CPU无法在不使用某种锁的情况下原子地更改数据。 例如: #include <iostream> #include <atomic> struct foo { double a; double b; }; std::atomic<foo> var; int main() { std::cout << var.is_lock_free() << std::endl; std::cout << sizeof(foo) << std::endl; std::cout << sizeof(var) << std::endl; } 输出(Linux / gcc)为: 0 16 16 由于原子和foo的大小相同,因此我认为原子中不会存储锁。 我的问题是: 如果原子变量使用锁,它将存储在哪里,这对于该变量的多个实例意味着什么?
71 c++  c++11  x86  atomic  stdatomic 

6
用于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获得了以下功能 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; } 但是,当我使用它时,带宽远小于memcpy。 我的i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2可达到__movsb15 GB / …
71 c  gcc  assembly  x86  memcpy 

2
为什么std :: fill(0)比std :: fill(1)慢?
我在一个系统std::fill上观察到,与恒定值或动态值相比,将恒定值std::vector<int>设置为大时显着且始终较慢:01 5.8 GiB /秒和7.5 GiB /秒 但是,对于较小的数据,结果会有所不同,但fill(0)速度更快: 如果有多个线程,则在4 GiB数据大小下,fill(1)斜率更高,但峰值要低得多fill(0)(51 GiB / s与90 GiB / s): 这就提出了第二个问题,即为什么峰值带宽 fill(1)这么低。 为此的测试系统是双插槽Intel Xeon CPU E5-2680 v3,设置为2.5 GHz(通过/sys/cpufreq),带有8x16 GiB DDR4-2133。我使用GCC 6.1.0(-O3)和Intel编译器17.0.1(-fast)进行了测试,两者均得到相同的结果。GOMP_CPU_AFFINITY=0,12,1,13,2,14,3,15,4,16,5,17,6,18,7,19,8,20,9,21,10,22,11,23被设定。Strem / add / 24线程在系统上的速度为85 GiB / s。 我能够在不同的Haswell双套接字服务器系统上重现这种效果,但在任何其他体系结构上均无法重现。例如,在Sandy Bridge EP上,内存性能是相同的,而在高速缓存fill(0)中则要快得多。 这是要重现的代码: #include <algorithm> #include <cstdlib> #include <iostream> #include <omp.h> #include <vector> using value = …

4
x86汇编中的“锁定”指令是什么意思?
我在Qt的源代码中看到了一些x86程序集: q_atomic_increment: movl 4(%esp), %ecx lock incl (%ecx) mov $0,%eax setne %al ret .align 4,0x90 .type q_atomic_increment,@function .size q_atomic_increment,.-q_atomic_increment 从谷歌搜索,我知道lock指令将导致CPU锁定总线,但是我不知道CPU何时释放总线? 关于上面的整个代码,我不明白该代码如何实现Add?
69 c++  qt  assembly  x86 

5
如何编写反汇编程序?[关闭]
从目前的情况来看,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我有兴趣将x86分解器编写为一个教育项目。 我发现的唯一真正的资源是Spiral Space的“如何编写反汇编程序”。尽管这对反汇编程序的各个组件进行了很好的高级描述,但我对一些更详细的资源感兴趣。我也快速浏览了NASM的源代码,但这是一个值得借鉴的重要内容。 我意识到这个项目的主要挑战之一是我将要处理的相当大的x86指令集。我也对基本结构,基本反汇编程序链接等感兴趣。 谁能指出我编写x86反汇编程序的详细资源?
68 x86  disassembly 

3
这是“不应发生”崩溃的AMD Fusion CPU错误吗?
由于我们的程序由于系统上的访问冲突而崩溃,因此我的公司已经开始吸引许多客户。 崩溃发生在SQLite 3.6.23.1中,我们将其作为应用程序的一部分提供。(为了提供与应用程序其余部分相同的VC ++库,我们提供了一个自定义版本,但这是库存的SQLite代码。) 当pcache1Fetch执行时发生崩溃call 00000000,如WinDbg调用栈所示: 0b50e5c4 719f9fad 06fe35f0 00000000 000079ad 0x0 0b50e5d8 719f9216 058d1628 000079ad 00000001 SQLite_Interop!pcache1Fetch+0x2d [sqlite3.c @ 31530] 0b50e5f4 719fd581 000079ad 00000001 0b50e63c SQLite_Interop!sqlite3PcacheFetch+0x76 [sqlite3.c @ 30651] 0b50e61c 719fff0c 000079ad 0b50e63c 00000000 SQLite_Interop!sqlite3PagerAcquire+0x51 [sqlite3.c @ 36026] 0b50e644 71a029ba 0b50e65c 00000001 00000e00 SQLite_Interop!getAndInitPage+0x1c [sqlite3.c @ 40158] 0b50e65c 71a030f8 …

1
x86指令是否需要自己的编码以及所有参数同时出现在内存中?
我试图弄清楚是否有可能运行仅由单个物理页面支持其RAM的Linux VM。 为了模拟这一点,我修改了KVM中的嵌套页面错误处理程序,以从所有嵌套页面表(NPT)条目中删除当前位,但与当前正在处理的页面错误相对应的位除外。 在尝试启动Linux guest虚拟机时,我观察到使用内存操作数的汇编指令,例如 add [rbp+0x820DDA], ebp 导致页面错误循环,直到我恢复包含指令的页面以及操作数中引用的页面的当前位(在本示例中[rbp+0x820DDA])。 我想知道为什么会这样。CPU是否不应该按顺序访问内存页面,即先读取指令然后访问内存操作数?还是x86要求同时访问指令页面以及所有操作数页面? 我正在AMD Zen 1上进行测试。

2
可比性测试比%运算符更快?
我注意到计算机上有一件奇怪的事情。*手写除数测试比%操作员快得多。考虑最小的示例: * AMD锐龙Threadripper 2990WX,GCC 9.2.0 static int divisible_ui_p(unsigned int m, unsigned int a) { if (m <= a) { if (m == a) { return 1; } return 0; } m += a; m >>= __builtin_ctz(m); return divisible_ui_p(m, a); } 该示例受奇数a和限制m > 0。但是,可以很容易地将其推广到所有a和m。该代码只是将除法转换为一系列的加法。 现在考虑使用以下命令编译的测试程序-std=c99 -march=native -O3: for (unsigned int a …

1
为什么GCC聚合数组的初始化会首先用零填充整个东西,包括非零元素?
为什么gcc用零而不是仅剩余的96个整数填充整个数组?非零初始值设定项都在数组的开头。 void *sink; void bar() { int a[100]{1,2,3,4}; sink = a; // a escapes the function asm("":::"memory"); // and compiler memory barrier // forces the compiler to materialize a[] in memory instead of optimizing away } MinGW8.1和gcc9.2都使asm像这样(Godbolt编译器资源管理器)。 # gcc9.2 -O3 -m32 -mno-sse bar(): push edi # save call-preserved EDI which …

1
为什么在加载.COM文件后DOS将SP寄存器设置为0xFFFE?
在有关.COM文件https://en.wikipedia.org/wiki/COM_file的wikpedia页面上,其内容为: DOS中的.COM文件将所有x86段寄存器设置为相同的值,而SP(堆栈指针)寄存器设置为0xFFFE,因此,堆栈从内存段的最顶部开始,并从那里开始向下工作。 但这实际上将堆栈设置为在该段的顶部下方开始一个单词。当将值压入堆栈时,CPU会将SP递减至0xFFFC并将其存储在该值中,从而浪费了该段的最高字。DOS不将SP设置为0的原因是什么?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.