This question already has answers here:
Closed 7 months ago.
using inline assembly with GCC
(2个答案)
我正在尝试编写这个内联程序集,它使用
这是最初的x86英特尔语法代码:
笔记:
-这些依赖于当目标失败时将其设置为0。
-The
下面是问题代码中的问题列表:
-不在
-使用
-检查CF=0是否成功
-使用不是内联程序集本地的标签名称。
-不使用输出寄存器。
-返回零表示超时,而不是使用单独的错误指示。[注意,我没有修好这个。]
-使用
-在内联程序集中使用
(2个答案)
我正在尝试编写这个内联程序集,它使用
rdrand
指令返回一个随机数。数字存储在eax
寄存器中,然后移动到rng_num
变量。但我得到了标题中的错误。 uint32_t rng_num;
asm volatile("movl $100, %ecx\n\t"
"__trng_cpu_ret:\n\t"
"rdrand %%eax\n\t"
"jnc .__trng_cpu_end\n\t"
"loop __trng_cpu_ret\n\t"
".__trng_cpu_fail:\n\t"
"movl $0, %%eax\n\t"
".__trng_cpu_end:\n\t"
"ret\n\t"
: "=r" (rng_num)
:
:"%eax");
这是最初的x86英特尔语法代码:
mov ecx, 100 ;number of retries
retry:
rdrand eax
jnc .done ;carry flag is clear on success
loop retry
.fail:
;no random number available
.done:
;random number is is EAX
最佳答案
正如fuz和Peter在评论中提到的,正确的答案是不要使用内联汇编。
但这里有两种方法可以在内联程序集中编写。
uint32_t rng_num;
int iterations = 100;
asm volatile("1: rdrand %0\n\t"
"dec %1\n\t"
"ja 1b\n\t" // jump if CF=0 (from rdrand) and ZF=0 (from dec)
: "=r" (rng_num), "+r"(iterations));
// alternative that doesn't need partial-flag merging
asm volatile("1: rdrand %0\n\t"
"jc 2f\n\t"
"dec %1\n\t"
"jnz 1b\n\t"
"2:\n\t"
: "=r" (rng_num), "+r"(iterations));
笔记:
-这些依赖于当目标失败时将其设置为0。
-The
rdrand
instruction检查ja
指令中的C标志和rdrand
中的Z标志。这可能比使用两个独立的分支效率低,如在第二个示例中,这取决于组合两个部分寄存器的成本。我相信彼得能提供细节。(彼得说:CPU上没有新的、足以安装RDRAND的部分标志,应该没问题。)下面是问题代码中的问题列表:
-不在
dec
寄存器名上使用%%
前缀。-使用
ecx
而不使用blobber。-检查CF=0是否成功
ecx
,而不是CF=1。-使用不是内联程序集本地的标签名称。
-不使用输出寄存器。
-返回零表示超时,而不是使用单独的错误指示。[注意,我没有修好这个。]
-使用
rdrand
指令。-在内联程序集中使用
loop
指令。关于c - 错误:无效的“asm”:%字母后缺少操作数编号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55768290/
10-11 18:34