Tag: x86 64

适用于Windows的硬件性能计数器API

我想使用硬件性能计数器 ,特别是x86 CPU来获取缓存未命中或分支错误预测。 性能计数器在英特尔VTune等高级分析器中大量使用。 请不要在Windows操作系统上混淆性能计数器。 为了在C / C ++程序中使用这些计数器,可以使用PAPI: http : //icl.cs.utk.edu/papi/ 这使您可以轻松使用性能计数器,但仅限Linux。 PAPI曾经支持Windows,但现在不支持。 是否有人最近尝试使用PAPI或其他API在Windows上使用硬件性能计数器?

在C中将32位应用程序转换为64位应用程序

我目前正致力于将32位应用程序转换为C语言中的64位应用程序。此应用程序目前正在开发x86架构(Windows,osx,Unix,Linux)。 因此,在开始编码之前,我想知道在转换应用程序时我需要考虑什么。

x86_64汇编程序中RBP寄存器的用途是什么?

所以我正在尝试学习一点assembly,因为我需要它用于计算机体系结构类。 我写了一些程序,比如打印Fibonacci序列。 我认识到每当我编写程序时,我都会使用这3行(正如我从gcc生成的汇编代码与它的C等价物进行比较所学到的): pushq %rbp movq %rsp, %rbp subq $16, %rsp 我有2个问题: 首先,为什么我使用%rbp ? 使用%rsp是不是更简单,因为它的内容在第二行被移动到%rbp ? 为什么我要从%rsp减去任何东西? 我的意思是它并不总是16 (当我printf 7行或8行变量时,我会减去24或28 我在虚拟机(4 GB RAM),Intel 64位处理器上使用Manjaro 64位

为什么这个内存地址%fs:0x28(fs )有一个随机值?

我写了一段C代码,我已经拆解了它,并且读取了寄存器以了解程序在汇编中的工作原理。 int test(char *this){ char sum_buf[6]; strncpy(sum_buf,this,32); return 0; } 我一直在研究的代码是测试function。 当我反汇编输出我的测试function时,我得到… 0x00000000004005c0 : mov %fs:0x28,%rax => 0x00000000004005c9 : mov %rax,-0x8(%rbp) … stuff .. 0x00000000004005f0 : xor %fs:0x28,%rdx 0x00000000004005f9 : je 0x400600 0x00000000004005fb : callq 0x4004a0 0x0000000000400600 : leaveq 0x0000000000400601 : retq 我想知道的是mov %fs:0x28,%rax真的在做什么?

为什么x86的INC指令不是primefaces的?

我已经读过x86的INC指令不是primefaces的。 我的问题是怎么来的? 假设我们在x86-64上递增64位整数,我们可以用一条指令来完成,因为INC指令适用于内存变量和寄存器。 那么为什么它不是primefaces的呢?

根据AMD64 ABI,什么样的C11数据类型是arrays

我正在研究在OSX上使用的x86_64的调用约定,并且在System V x86-64 ABI标准中阅读了名为“Aggregates and Unions”的部分。 它提到了数组,我认为这就像一个固定长度的c数组,例如int[5] 。 我下到“3.2.3参数传递”来读取数组是如何传递的,如果我理解正确的话,像uint8_t[3]这样的东西应该在寄存器中传递,因为它小于规则1规定的4个8字节的限制。聚合类型的分类(第18页靠近底部)。 编译后,我看到它被作为指针传递。 (我正在使用OSX 10.11.6上的Xcode 7.3.1中的clang-703.0.31进行编译)。 我用来编译的示例源如下: #include #define type char extern void doit(const type[3]); extern void doitt(const type[5]); extern void doittt(const type[16]); extern void doitttt(const type[32]); extern void doittttt(const type[40]); int main(int argc, const char *argv[]) { const char a[3] = { 1, 2, 3 }; const […]

为什么整数除以-1(负一)导致FPE?

我的任务是表达一些看似奇怪的C代码行为(在x86上运行)。 我可以很容易地完成其他所有事情,但是这个让我很困惑。 代码段1输出-2147483648 int a = 0x80000000; int b = a / -1; printf(“%d\n”, b); 代码片段2不输出任何内容,并提供Floating point exception int a = 0x80000000; int b = -1; int c = a / b; printf(“%d\n”, c); 我很清楚代码片段1( 1 + ~INT_MIN == INT_MIN )的结果的原因,但我不太明白整数除法-1如何生成FPE,也不能在我的Android手机上重现它(AArch64 ,海湾合作委员会7.2.0)。 代码2只输出与代码1相同,没有任何例外。 它是x86处理器的隐藏bugfunction吗? 该任务没有告诉任何其他内容(包括CPU架构),但由于整个课程基于桌面Linux发行版,您可以放心地假设它是一个现代的x86。 编辑 :我联系了我的朋友,他在Ubuntu 16.04(Intel Kaby Lake,GCC 6.3.0)上测试了代码。 结果与所指定的任何内容一致(代码1输出所述内容,代码2与FPE崩溃)。

gcc中有128位整数吗?

我想要128位整数,因为我想存储两个64位数的乘法结果。 在gcc 4.4及以上版本中有没有这样的东西?

使用背靠背rdtsc进行负时钟周期测量?

我正在编写一个C代码,用于测量获取信号量所需的时钟周期数。 我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销。 我在for循环中重复了这么多次,然后我使用平均值作为rdtsc开销。 这是正确的,首先要使用平均值吗? 尽管如此,这里的一个大问题是,有时我会得到开销的负值(不一定是平均值,但至少是for循环中的部分值)。 这也会影响sem_wait()操作所需的cpu周期数的连续计算,有时也会产生负数。 如果我写的不清楚,这里有一部分我正在编写的代码。 为什么我会得到这样的负值? (编者注:请参阅获取CPU周期计数?以获得完整的64位时间戳的正确和可移植方式。 “=A” asm约束仅在编译为x86-64时获得低或高32位,具体取决于寄存器分配是否恰好为uint64_t输出选择RAX或RDX。它不会选择edx:eax 。) (编辑的第二个注释:哎呀,这就是为什么我们得到负面结果的答案。仍然值得留下一个注释,作为警告不要复制这个rdtsc实现。) #include #include #include #include #include static inline uint64_t get_cycles() { uint64_t t; // editor’s note: “=A” is unsafe for this in x86-64 __asm volatile (“rdtsc” : “=A”(t)); return t; } int num_measures = 10; int main () { int i, value, res1, […]

为什么对mmap的内存进行未对齐访问有时会在AMD64上出现段错误?

我有这段代码在AMD64兼容CPU上运行Ubuntu 14.04时会出现段错误: #include #include #include int main() { uint32_t sum = 0; uint8_t *buffer = mmap(NULL, 1<<18, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); uint16_t *p = (buffer + 1); int i; for (i=0;i<14;++i) { //printf("%d\n", i); sum += p[i]; } return sum; } 如果使用mmap分配内存,则仅此段错误。 如果我使用malloc ,堆栈上的缓冲区或全局变量,它不会发生段错误。 如果我将循环的迭代次数减少到少于14的次数,则不再是段错误。 如果我从循环内打印数组索引,它也不再是段错误。 为什么未对齐的内存访问能够访问未对齐地址的CPU上的段错误,为什么只有在这种特定情况下呢?