x86相关内容

_start 中 RET 上的 Nasm 分段错误

section .text全局_start_开始:没有主要的:移动轴,1mov ebx, 2异或 eax, eax退 我用这些命令编译: nasm -f elf main.asmld -melf_i386 -o main main.o 当我运行代码时,Linux抛出一个segmentation fault错误 (我使用的是 Linux Mint Nadia 64 位).为什么会产生这个 ..
发布时间:2021-12-03 13:21:28 服务器开发

如何在程序集 NASM 中打印数字?

假设我在寄存器中有一个整数,我如何打印它?你能展示一个简单的示例代码吗? 我已经知道如何打印诸如“hello, world"之类的字符串. 我正在 Linux 上开发. 解决方案 如果您已经在使用 Linux,则无需自己进行转换.只需使用 printf 代替: ;;组装和链接:;nasm -f elf printf-test.asm &&gcc -m32 -o printf- ..
发布时间:2021-12-03 13:10:49 服务器开发

如何在内联汇编中通过 syscall 或 sysenter 调用系统调用?

在x86 Linux下如何直接使用sysenter/syscall实现系统调用?有人可以提供帮助吗?如果能把amd64平台的代码也展示一下就更好了. 我知道在 x86 中,我们可以使用 __asm__(" movl $1, %eax \n"" movl $0, %ebx \n"" 呼叫 *%gs:0x10 \n"); 间接路由到 sysenter. 但是我们如何直接使用 sysen ..
发布时间:2021-12-03 13:03:28 服务器开发

堆栈上局部变量分配的顺序

看看这两个函数: void function1() {整数 x;输入 y;内部 z;int *ret;}无效函数2(){字符缓冲区1[4];字符缓冲区2[4];字符缓冲区3[4];int *ret;} 如果我在 gdb 中的 function1() 处中断,并打印变量的地址,我会得到: (gdb) p &x$1 = (int *) 0xbffff380(gdb) p &y$2 = (int ..
发布时间:2021-12-02 08:19:57 其他开发

使用自修改代码观察 x86 上的陈旧指令提取

我被告知并阅读了英特尔的手册,可以将指令写入内存,但指令预取队列已经获取过时的指令并将执行那些旧指令.我没有成功地观察到这种行为.我的方法如下. 英特尔软件开发手册第 11.6 节指出 写入当前缓存在处理器中的代码段中的内存位置会导致相关的缓存线(或多条线)无效.该检查基于指令的物理地址.此外,P6 系列和奔腾处理器会检查对代码段的写入是否会修改已预取以供执行的指令.如果写入影响预取指 ..
发布时间:2021-12-02 08:07:08 其他开发

在 C++ 内联 asm 中使用基指针寄存器

我希望能够在内联汇编中使用基指针寄存器 (%rbp).一个玩具示例如下: void Foo(int &x){asm volatile ("pushq %%rbp;"//'序言'"movq %%rsp, %%rbp;"//'序言'“subq $12,%%rsp;"//腾地方"movl $5, -12(%%rbp);"//一些汇编指令"movq %%rbp, %%rsp;"//'尾声'“popq % ..
发布时间:2021-12-01 15:22:40 C/C++开发

如何从 C++ 获取 x86_64 中的 CPU 周期数?

我在 SO 上看到了这篇文章,其中包含用于获取最新 CPU 周期计数的 C 代码: C/C++ 中基于 CPU 周期计数的分析Linux x86_64 有什么方法可以在 C++ 中使用此代码(欢迎使用 windows 和 linux 解决方案)?尽管用 C 编写(并且 C 是 C++ 的子集),但我不太确定这段代码是否可以在 C++ 项目中运行,如果不能,如何翻译它? 我使用的是 ..
发布时间:2021-12-01 14:58:36 C/C++开发

x86 上交换锁与比较交换锁的相对性能

两种常见的锁定习惯用法是: if (!atomic_swap(lockaddr, 1))/* 得到了锁 */ 和: if (!atomic_compare_and_swap(lockaddr, 0, val))/* 得到锁 */ 其中 val 可以只是一个常量或新的潜在锁所有者的标识符. 我想知道的是,两者在 x86(和 x86_64)机器上是否存在明显的性能差异.我知道这是一个相当 ..
发布时间:2021-11-30 14:56:36 其他开发

如何在 C 中进行原子增量和获取?

我正在寻找一种方法来原子地增加一个 short,然后返回那个值.我需要在内核模式和用户模式下都这样做,所以它是在 C 中,在 Linux 下,在英特尔 32 位架构上.不幸的是,由于速度要求,互斥锁不是一个好的选择. 有没有其他方法可以做到这一点?在这一点上,似乎唯一可用的选择是内联一些程序集.如果是这种情况,有人可以指出我的适当说明吗? 解决方案 GCC 支持原子操作: gc ..
发布时间:2021-11-30 14:51:45 服务器开发

在 x86/x86_64 处理器上使用 LFENCE 指令有意义吗?

通常在互联网上,我发现 LFENCE 在 x86 处理器中毫无意义,即它什么也不做,因此我们可以完全轻松地使用 SFENCE,因为 MFENCE = SFENCE + LFENCE = SFENCE + NOP =SFENCE. 但是如果 LFENCE 没有意义,那么为什么我们有四种方法可以在 x86/x86_64 中实现顺序一致性: LOAD(无围栏)和 STORE + MFENCE ..
发布时间:2021-11-30 14:48:06 其他开发

原子 x86 指令与 MS 的 InterlockedCompareExchange 文档的对齐要求?

Microsoft 提供了 InterlockedCompareExchange 用于执行原子比较和交换操作的函数.还有一个 _InterlockedCompareExchange 内在. 在 x86 上,这些是使用 lock cmpxchg 指令实现的. 然而,通读关于这三种方法的文档,他们似乎在对齐要求上不一致. 英特尔的参考手册 没有提及对齐(除了那如果对齐检查已启用并且进 ..
发布时间:2021-11-30 14:47:39 其他开发

布尔读/写操作在 x86 上不是原子的吗?

假设我们有两个线程,一个在循环中读取 bool,另一个可以在特定时间切换它.我个人认为这应该是原子的,因为 C++ 中的 sizeof(bool) 是 1 个字节,您不会部分读/写字节,但我想 100% 确定. 是还是不是? 编辑: 为了将来参考,同样适用于 int 吗? 解决方案 这完全取决于您对“原子"一词的实际含义. 您的意思是“最终值将一次性更新"(是的,在 ..
发布时间:2021-11-30 14:47:22 C/C++开发

std::atomic 的锁在哪里?

如果一个数据结构中有多个元素,它的原子版本不能(总是)是无锁的.有人告诉我,这对于较大的类型是正确的,因为 CPU 不能在不使用某种锁的情况下原子地更改数据. 例如: #include #include 结构 foo {双一;双 b;};std::atomic无功;int main(){std::cout ..
发布时间:2021-11-30 14:46:13 C/C++开发

x86 上的原子性

8.1.2 总线锁定 Intel 64 和 IA-32 处理器提供一个 LOCK# 信号,该信号被断言在某些关键内存操作期间自动锁定系统总线或等效链路.当这个输出信号被断言时,来自其他处理器或总线代理的总线控制请求被阻止.软件可以指定其他场合当LOCK语义之后是将 LOCK 前缀添加到说明. 它来自英特尔手册,第 3 卷 听起来像内存上的原子操作将直接在内存(RAM)上执行.我很 ..
发布时间:2021-11-30 14:45:59 C/C++开发

英特尔内存模型是否使 SFENCE 和 LFENCE 变得多余?

英特尔内存模型保证: 商店不会与其他商店重新订购 负载不会与其他负载重新排序 http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/ 我看到有人声称由于 Intel 内存模型,SFENCE 在 x86-64 上是多余的,但从来没有 LFENCE.上述内存模型规则是否使任一指令变得多余? ..
发布时间:2021-11-30 14:45:40 其他开发

x86 CMPXCHG 是原子的,如果是,为什么需要 LOCK?

英特尔文档 说 该指令可以与 LOCK 前缀一起使用,以允许指令自动执行. 我的问题是 CMPXCHG 可以用内存地址操作吗?从文档看来不是,但谁能确认只适用于寄存器中的实际 VALUE,而不适用于内存地址? 如果CMPXCHG 不是原子的,并且必须通过LOCK CMPXCHG(使用LOCK)实现高级语言级别的CAS前缀),引入这样的指令的目的是什么? (我是从高级语 ..
发布时间:2021-11-30 14:45:21 其他开发

SSE指令:哪些CPU可以做原子16B内存操作?

考虑 x86 CPU 上的单个内存访问(单个读取或单个写入,而不是读取 + 写入)SSE 指令.该指令正在访问 16 个字节(128 位)的内存,并且访问的内存位置对齐到 16 个字节. 文档“英特尔® 64 位架构内存订购白皮书"指出,对于“读取或写入地址在 8 字节边界上对齐的四字(8 字节)的指令",内存操作似乎作为单个内存执行访问与内存类型无关. 问题:是否存在 Intel/A ..
发布时间:2021-11-30 14:44:44 其他开发

为什么在 x86 上自然对齐的变量原子上的整数赋值是原子的?

我一直在阅读关于原子操作的这篇文章,并提到 32 位整数赋值在 x86 上是原子的,只要变量自然对齐即可. 为什么自然对齐可以保证原子性? 解决方案 “自然"对齐意味着对齐到它自己的类型宽度.因此,加载/存储永远不会跨越任何比自身更宽的边界(例如页面、缓存行,或者用于不同缓存之间数据传输的更窄的块大小). CPU 经常以 2 的幂大小的块的形式在内核之间执行缓存访问或缓存线传输 ..
发布时间:2021-11-30 14:44:23 C/C++开发

REP 做什么设置?

引用英特尔® 64 和 IA-32 架构优化参考手册,第 2.4.6 节“REP 字符串增强": 使用 REP 字符串的性能特征可归因于两个组成部分:启动开销和数据传输吞吐量. [...] 对于较大粒度数据传输的REP字符串,作为ECX值增加,REP String 的启动开销呈阶梯式增加: 短字符串(ECX 20 个周期, 快速字符串(ECX >= 76:不包括 RE ..
发布时间:2021-11-30 11:17:38 其他开发