Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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
X86 BTS给出了;无效组合“;,但仅当寻址内存时_X86_Nasm - Fatal编程技术网

X86 BTS给出了;无效组合“;,但仅当寻址内存时

X86 BTS给出了;无效组合“;,但仅当寻址内存时,x86,nasm,X86,Nasm,如果我使用nasm-felf64 test.asm组装此文件,则会出现以下错误: ; syntax: nasm default rel global main section .text main: call init ; do stuff ret init: lock bts [initted], 0 ; <-- error: invalid combination of opcode and operands

如果我使用
nasm-felf64 test.asm
组装此文件,则会出现以下错误:

; syntax: nasm
default rel
global main
 
section .text
main:
        call init
        ; do stuff
        ret
 
init:
        lock bts [initted], 0 ; <-- error: invalid combination of opcode and operands
        jc .continue
        ret
 
    .continue:
        ; do stuff
        ret
 
section .data
        initted db 0
任何组合
锁定
默认rel
也会发生这种情况

汇编的唯一功能是将其更改为
btsrax,0
。显然,这个程序没有任何线程,但是完整的线程会,如果多个线程试图同时运行init,它肯定会崩溃


我已经看了好几遍了,可能我遗漏了一些愚蠢的东西,但我不知道它是什么。

bts
没有8位格式,请看,所以不能在字节变量上使用它

如果将
initted
更改为
dw/dd/dq
,则可以使用
bts
,但必须指定操作数大小,例如
lock bts dword[initted],0


(我假设位偏移量为0的
bts
不应该修改操作数的低位字节以外的任何内容。因此
锁定bts字[initted],0
原则上可以用于
initted db 0
,前提是您可以确保它不在页面的最后一个字节,您可以通过将
align 2
放在它前面来保证这一点。除非您迫切需要节省内存,否则最好只将
initted
放大。

bts
没有8位格式,请参阅,所以不能在字节变量上使用它

如果将
initted
更改为
dw/dd/dq
,则可以使用
bts
,但必须指定操作数大小,例如
lock bts dword[initted],0



(我假设位偏移量为0的
bts
不应该修改操作数的低位字节以外的任何内容。因此
锁定bts字[initted],0
原则上可以用于
initted db 0
,前提是您可以确保它不在页面的最后一个字节,您可以通过将
align 2
放在它前面来保证。除非您非常想节省内存,否则最好将
initted
调大一些。)

,您通常希望使用某种双重检查锁定,首先测试
initted
,以查看另一个线程是否已完成init的运行。(就像GCC在函数范围内为
static int foo=non_constant_function();
使用保护变量一样。)你不希望每次都用原子RMW在保护变量上安装每个线程锤的代价和不可伸缩性。)@PeterCordes:就像解锁的
测试[inited],1
如果它不为零,则退出,否则,请尝试锁定的
bts
?@NateEldredge:您可能需要3种状态:完全初始化(1)、未启动(0),或者另一个线程已经赢得开始运行init代码的竞赛,但尚未完成(2或-1或其他,IDK)。所以
cmp字节[initted],1
/
可能在某处。(或
movzx load
/
cmp
/
jne
,取决于哪个更适合微+宏融合-
cmp字节[mem],不幸的是,imm
/
jne
不是英特尔前端的单一uop,特别是不是RIP rel。)IDK如果GCC使用独立于保护的锁变量,决定哪个线程将实际运行init函数,但似乎没有必要。哦,对了,假设您需要确保在继续之前初始化已经完成。然后我猜如果是其他线程启动了它,你必须旋转或等待它们完成。我现在看到的是
bt[initted],1
查看它是否完成,如果没有,则
锁定bts[initted],0
查看它是否已启动。如果有,它将以
bt[initted]旋转,1
(当然还有
暂停
)。完成初始化后,它会执行
bts[initted],1
。仅供参考,您通常希望使用某种双重检查锁定,首先测试
initted
,以查看另一个线程是否已完成init的运行。(就像GCC在函数范围内为
static int foo=non_constant_function();
使用保护变量一样。)你不希望每次都用原子RMW在保护变量上安装每个线程锤的代价和不可伸缩性。)@PeterCordes:就像解锁的
测试[inited],1
如果它不为零,则退出,否则,请尝试锁定的
bts
?@NateEldredge:您可能需要3种状态:完全初始化(1)、未启动(0),或者另一个线程已经赢得开始运行init代码的竞赛,但尚未完成(2或-1或其他,IDK)。所以
cmp字节[initted],1
/
可能在某处。(或
movzx load
/
cmp
/
jne
,取决于哪个更适合微+宏融合-
cmp字节[mem],不幸的是,imm
/
jne
不是英特尔前端的单一uop,特别是不是RIP rel。)IDK如果GCC使用独立于保护的锁变量,决定哪个线程将实际运行init函数,但似乎没有必要。哦,对了,假设您需要确保在继续之前初始化已经完成。然后我猜如果是其他线程启动了它,你必须旋转或等待它们完成。我现在看到的是
bt[initted],1
查看它是否完成,如果没有,则
锁定bts[initted],0
查看它是否已启动。如果有,它将以
bt[initted]旋转,1
(当然还有
暂停
)。初始化完成后,它会执行
bts[initted],1
。好的,这很有意义,我的印象是m64表示“内存中的东西,带有64位地址”,而实际上它的意思是“内存中的qword”。对。这个数字指定的是操作数大小,而不是地址大小。对于OP的用例,他们可以简单地使用
xchg
lock cmpxchg
,它们支持字节操作数,周围的代码略有不同。我不知道NASM为什么会拒绝
lock bts[inited],0<
...
        lea rax, [initted]
        lock bts [rax], 0 ; <-- same error
        jc .continue
...