Linux 64。
GCC 4.8.2(-O3 -march = native)
左手下方的x86_64 abi,在第21页打开。
int main (int argc, char ** argv) {
int16_t h = atoi(argv[1]) ;
int16_t p;
__asm__ ("mov %2, %0\n\t"
"rol $8,%1\n\t"
: "=r" (p) /* output operands */
: "0"(p),"g"(h)/* input operands */
:"cc"); /* clobbered operands */
printf("%d %d\n", h, p);
return 0;
}
...
movl $10, %edx
movq 8(%rsi), %rdi
xorl %esi, %esi
call strtol
xorl %edx, %edx
movl $.LC0, %edi
#APP
# 1627 "test2ptr.c" 1
movl %ax, %dx <- set in %dx
rol $8,%dx
# 0 "" 2
#NO_APP
movswl %ax, %esi
movswl %dx, %edx <- Then this line should not appear
xorl %eax, %eax
call printf
xorl %eax, %eax
...
如果我评论它,结果很好。
但是我不能依赖于修改源代码(不可维护:每次在源代码中改变某些内容时,必须返回该位置以确保它仍在工作...不要去。)
为什么行movswl %dx, %edx
会被保留?
它应该长篇大论。但它已经由我完成并且花了我一个多余的时钟。
有没有解决方法?
这只是我没有设定的选项吗?
由于
答案 0 :(得分:1)
由于您指定了16位类型,但printf
需要32位整数,因此需要对结果进行符号扩展,这就是该代码的作用。然而,如果您使用printf
的正确格式,则两个版本都应生成相同的输出。
像往常一样,你不需要内联asm来进行旋转,如果你在内联中使用mov
,你可能会做错了。
答案 1 :(得分:0)
确定,
所以解决方法是设置int32_t而不是int16_t。
现在代码是...... 2个cpu周期更快。
这太荒谬了。
但我现在非常喜欢装配:)