我有内联汇编代码:
#define read_msr(index, buf) asm volatile ("rdmsr" : "=d"(buf[1]), "=a"(buf[0]) : "c"(index))
使用此宏的代码:
u32 buf[2];
read_msr(0x173, buf);
我发现反汇编是(使用gnu工具链):
mov eax,0x173
mov ecx,eax
rdmsr
mov DWORD PTR [rbp-0xc],edx
mov DWORD PTR [rbp-0x10],eax
问题是0x173小于0xffff,为什么gcc不使用" mov cx,0x173"?请问gcc会分析以下指令" rdmsr&#34 ;? gcc是否总能知道正确的寄存器大小?`re
答案 0 :(得分:2)
取决于传递的值或变量的大小。
如果传递“short int”,它将设置“cx”并从“ax”和“dx”读取数据(如果buf也是短整数)。
对于char,它将访问“cl”等等。
所以“c”指的是“ecx”寄存器,但这可以通过“ecx”,“cx”或“cl”访问,具体取决于访问的大小,我认为这是有意义的。
要测试你可以尝试传递(unsigned short)0x173,它应该改变代码。
没有对内联汇编的分析(事实上它是在文本替换direclty复制到输出程序集之后,包括语法错误)。此外,没有默认寄存器大小,具体取决于您是否具有32位或64位目标。这将是限制的方式。
答案 1 :(得分:1)
我认为答案是因为当前的默认数据大小是32位。在64位长模式下,默认数据大小也是32位,除非使用“rex.w”前缀。
答案 2 :(得分:-1)
Intel将RDMSR指令指定为使用(全部)ECX来确定特定于模型的寄存器。既然如此,并且显然由您的宏指定,GCC完全有理由将您的常量加载到完整的ECX中。
所以关于它为什么不加载CX的问题似乎完全不合适。看起来GCC正在生成正确的代码。
(你没有问为什么它通过使用EAX来低效地分配ECX的负载;我不知道答案是什么。