Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 锁前缀的范围是什么?_Assembly_Linux Kernel_X86_Kernel - Fatal编程技术网

Assembly 锁前缀的范围是什么?

Assembly 锁前缀的范围是什么?,assembly,linux-kernel,x86,kernel,Assembly,Linux Kernel,X86,Kernel,据说以“lock”为前缀的汇编指令是原子指令。我想知道“锁”是否只能影响一条汇编指令;汇编指令本身不是原子指令吗 以下是linux内核中原子函数的示例: static __inline__ int atomic_sub_and_test(int i, atomic_t *v) { unsigned char c; __asm__ __volatile__( LOCK "subl %2,%0; sete %1" :"=m" (v->counter), "=qm" (c)

据说以“lock”为前缀的汇编指令是原子指令。我想知道“锁”是否只能影响一条汇编指令;汇编指令本身不是原子指令吗

以下是linux内核中原子函数的示例:

static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
 { unsigned char c;
 __asm__ __volatile__(
 LOCK "subl %2,%0; sete %1" 
    :"=m" (v->counter), "=qm" (c) 
     :"ir" (i), "m" (v->counter) : "memory"); 
return c; }

在本例中,subl和sete可以被中断吗?

只有极少数特定的汇编指令是原子指令。x86在很大程度上是一种CISC体系结构,这意味着单个指令可以完成大量工作,其中单个指令可以将值从内存地址加载到寄存器中,对其执行操作,然后将结果存储回内存。这是一个复杂的操作,需要很多时间和CPU周期来执行;为了提高性能,许多这样的指令是流水线的,它们的执行顺序是相互交织的


基本上,汇编语言和其他语言一样。特别是在谈到CISC体系结构时,有许多“高级”构造和操作可以在单个命令中执行,除非在指令文档中或使用
lock
修饰符明确指定,否则不能保证它们以原子方式执行。

对于在其他CPU内核上同时运行的其他指令,指令不是原子的。
LOCK
前缀的作用是锁定总线,以便在锁定的指令运行时,其他内核无法访问内存,从而防止两个内核试图同时访问同一位置时发生冲突。

锁定前缀影响单个指令

当指令修改多个CPU之间共享的内存时,它们就不再是原子指令。涉及读取内存操作数、对其执行某些操作(如AND、XOR、INC等)然后将其写回的修改不会被其他CPU视为原子修改。锁定前缀“锁定”内存位置,因此3个步骤(读取、修改、写入)看起来是一个步骤,即其他CPU只能观察锁定指令之前和之后的内容

请参阅英特尔或AMD的官方CPU文档


编辑:在您新添加的示例中,如果我们讨论的是中断,则这些指令都不能被中断。中断发生在整个指令之间。锁定前缀使
sub
指令原子化。
sete
指令不是原子指令,它用于将
ZF
标志转换为零或非零整数值。

我为这个问题添加了一个示例。我的意思是两条指令之间是否会发生中断?是的,它们可以。这有什么问题吗?AlexeyFrunze:我猜@venus.w担心两条指令之间的中断可能会违反标志寄存器,导致ste结果错误。但实际上,当中断返回时,标志寄存器将被恢复。