error: invalid 'asm': operand number missing after %-letter
error: invalid 'asm': operand number missing after %-letter
我正在尝试编写这个内联汇编,其中 returns 使用 rdrand
指令的随机数。该数字存储在 eax
寄存器中,然后移至 rng_num
变量。但是我得到了标题中的错误。
uint32_t rng_num;
asm volatile("movl 0, %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 [=10=], %%eax\n\t"
".__trng_cpu_end:\n\t"
"ret\n\t"
: "=r" (rng_num)
:
:"%eax");
这是原始的 x86 Intel 语法代码:
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));
备注:
- 这些依赖于 rdrand
在失败时将目标设置为 0。
- The ja
instruction 检查来自 rdrand
指令的 C 标志和来自 dec
的 Z 标志。这可能比使用两个单独的分支效率低,如第二个示例中所示,具体取决于组合两个部分寄存器的成本。我相信 Peter 可以提供详细信息。 (Peter 说:在足够新的 CPU 上没有部分标志停顿以具有 RDRAND,应该没问题。)
问题中代码问题列表如下:
- 不在 ecx
注册名称上使用 %%
前缀。
- 使用 ecx
没有破坏。
- 检查 CF=0 是否成功 rdrand
而不是 CF=1.
- 使用非内联程序集本地的标签名称。
- 不使用输出寄存器。
- Returns 零表示超时,而不是使用单独的错误指示。 [注意,我没有修复这个。]
- 使用 loop
指令。
- 在内联汇编中使用 ret
指令。
我正在尝试编写这个内联汇编,其中 returns 使用 rdrand
指令的随机数。该数字存储在 eax
寄存器中,然后移至 rng_num
变量。但是我得到了标题中的错误。
uint32_t rng_num;
asm volatile("movl 0, %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 [=10=], %%eax\n\t"
".__trng_cpu_end:\n\t"
"ret\n\t"
: "=r" (rng_num)
:
:"%eax");
这是原始的 x86 Intel 语法代码:
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));
备注:
- 这些依赖于 rdrand
在失败时将目标设置为 0。
- The ja
instruction 检查来自 rdrand
指令的 C 标志和来自 dec
的 Z 标志。这可能比使用两个单独的分支效率低,如第二个示例中所示,具体取决于组合两个部分寄存器的成本。我相信 Peter 可以提供详细信息。 (Peter 说:在足够新的 CPU 上没有部分标志停顿以具有 RDRAND,应该没问题。)
问题中代码问题列表如下:
- 不在 ecx
注册名称上使用 %%
前缀。
- 使用 ecx
没有破坏。
- 检查 CF=0 是否成功 rdrand
而不是 CF=1.
- 使用非内联程序集本地的标签名称。
- 不使用输出寄存器。
- Returns 零表示超时,而不是使用单独的错误指示。 [注意,我没有修复这个。]
- 使用 loop
指令。
- 在内联汇编中使用 ret
指令。