Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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
C++ 内联程序集分支目标超出范围_C++_Assembly_X86_Inline Assembly - Fatal编程技术网

C++ 内联程序集分支目标超出范围

C++ 内联程序集分支目标超出范围,c++,assembly,x86,inline-assembly,C++,Assembly,X86,Inline Assembly,我不熟悉组装。最近,我需要Visual Studio 2013中的内联程序集来提高性能 但我来谈谈分支目标范围问题: _asm { mov ecx, cnt; jecxz AZERO: AL1: /*Some operation codes here, but may be exceed 128 byte*/ loop AL1; AZERO: } 我知道原因是“操作码”的大小超过了128字节 我的简单解决方案是: for (int i =

我不熟悉组装。最近,我需要Visual Studio 2013中的内联程序集来提高性能

但我来谈谈分支目标范围问题:

_asm
{
    mov ecx, cnt;
    jecxz AZERO:
    AL1:
       /*Some operation codes here, but may be exceed 128 byte*/
    loop AL1;
    AZERO:
}
我知道原因是“操作码”的大小超过了128字节

我的简单解决方案是:

for (int i = 0; i < cnt; i++) {
    _asm
    {
       /*Some operation codes here, but may be exceed 128 byte*/
    }
}
for(int i=0;i
这似乎奏效了

但我不知道这个方法是否足够好


有没有什么好方法可以在不引起分支范围问题的情况下处理循环部分?

您看到的原因是
loop
jecxz
†都是短跳转指令。您使用的C循环没有使用
循环
;它使用
jcc
进行分支(包括短形式和近形式)

如果需要,您仍然可以使用完全组装。您不能使用
循环

    mov ecx, cnt
    jmp ATEST
AL1:
    /* fun happens here */
ATEST:
    dec ecx
    jns AL1
用技术术语来说:

  • 短跳转使用有符号的1字节偏移量(从下一条指令开始),它提供了[-128128]的范围(正如您已经计算出的)
  • 近跳转使用有符号的2字节(在16位模式下)或4字节(在32位和64位模式下)偏移量,分别提供[-32768、32768]和[-2147483648、2147483648]的范围。
    • 在16位和32位模式下,这意味着近跳转可以访问当前代码段中的任何位置
†请注意,
jecxz
从技术上讲不是
jcc
指令;它不在
jcc
操作码范围内,不检查标志,也没有相应的
cmovcc
setcc
表单


——为了完整性,
jmp
(但不包括
jcc
)还支持近间接跳转、远跳转和远间接跳转。

您看到的原因是
loop
jecxz
†都是短跳转指令。您使用的C循环不使用
loop
;它使用
jcc
进行分支(具有短跳转和近跳转形式)

如果需要,您仍然可以使用完整汇编。您只是不能使用
循环

    mov ecx, cnt
    jmp ATEST
AL1:
    /* fun happens here */
ATEST:
    dec ecx
    jns AL1
用技术术语来说:

  • 短跳转使用有符号的1字节偏移量(从下一条指令开始),它提供了[-128128]的范围(正如您已经计算出的)
  • 近跳转使用有符号的2字节(在16位模式下)或4字节(在32位和64位模式下)偏移量,分别提供[-32768、32768]和[-2147483648、2147483648]的范围。
    • 在16位和32位模式下,这意味着近跳可以访问当前代码段中的任何位置
†请注意,
jecxz
从技术上讲不是
jcc
指令;它不在
jcc
操作码范围内,不检查标志,也没有相应的
cmovcc
setcc
表单


‡为了完整起见,
jmp
(但不是
jcc
)也支持近间接跳转、远跳转和远间接跳转。

jecxz
也有一个短操作数。@gsg从技术上讲
jecxz
不是
jcc
指令(它不在
jcc
指令的操作码范围内,它不查看标志,也没有
setcc
表单),但由于某种原因,它列在《英特尔手册》的
jcc
部分,我将更新我的答案以解决这个问题。谢谢!
jecxz
也有一个短操作数。@gsg从技术上讲
jecxz
不是
jcc
指令(它不在
jcc
指令的操作码范围内,它不看标志,也没有
setcc
表单),但由于某种原因,它被列在英特尔手册的
jcc
部分,我将更新我的答案以解决这个问题。谢谢!