有人可以帮助我了解https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html中提供的汇编程序吗
它是这样的:
uint64_t msr;
asm volatile ( "rdtsc\n\t" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n\t" // Shift the upper bits left.
"or %%rdx, %0" // 'Or' in the lower bits.
: "=a" (msr)
:
: "rdx");
与以下内容有何不同?
uint64_t msr;
asm volatile ( "rdtsc\n\t"
: "=a" (msr));
为什么我们需要移位和或运算,而rdx到底需要做什么?
编辑:添加了对原始问题仍不清楚的内容。
“ \ n \ t”有什么作用?
“:”做什么?
分隔符输出/输入/分隔符...
最后的rdx等于0吗?
只是回顾一下。第一行将时间戳加载到寄存器eax和edx中。第二行将值转换为eax并存储在rdx中。第三行将edx中的值与rdx中的值进行运算,然后将其保存在rdx中。第四行将rdx中的值分配给我的变量。最后一行将rdx设置为0。
为什么前三行没有“:”?
它们是模板。输出第一行带有“:”,第二行是可选输入,第三行是Clobbers(已更改的寄存器)的可选列表。
实际上是eax和d-edx吗?这是硬编码的吗?
再次感谢! :)
EDIT2:回答了我的一些问题...
最佳答案
uint64_t msr;
asm volatile ( "rdtsc\n\t" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n\t" // Shift the upper bits left.
"or %%rdx, %0" // 'Or' in the lower bits.
: "=a" (msr)
:
: "rdx");
因为
rdtsc
指令返回的结果是edx
和eax
,而不是64位计算机上的直接64位寄存器(有关更多信息,请参见intel系统的编程手册;它是x86指令),因此第二名指令将
rdx
寄存器左移32位,这样edx
将位于高32位而不是低32位。"=a" (msr)
将eax
的内容移到msr
(%0
)中,即移入它的低32位,因此总共有edx
(高32位)和eax
(低32位)到rdx
的msr
中。rdx
是一个表示msr
C变量的内容。类似于在C中执行以下操作:
static inline uint64_t rdtsc(void)
{
uint32_t eax, edx;
asm volatile("rdtsc\n\t", "=a" (eax), "=d" (edx));
return (uint64_t)eax | (uint64_t)edx << 32;
}
和:
uint64_t msr;
asm volatile ( "rdtsc\n\t"
: "=a" (msr));
这一个,只会给您
eax
的内容到msr
中。编辑:
1)“ \ n \ t”用于使生成的程序集看起来更清晰且没有错误,因此您不会遇到诸如
movl $1, %eaxmovl $2, %ebx
之类的东西2)rdx末尾等于0吗?左移执行此操作,它将删除
rdx
中已经存在的位。3)实际上是eax和d-edx吗?这是硬编码的吗?是的,有一张表格描述了什么字符代表什么寄存器,例如“ D”为
rdi
,“ c”为ecx
,...