背景:
Linux 64
GCC 4.8.2 (与-O3 -march=native)
我左手下的x86_64 abi,在第21页打开。
C代码:
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要保留这条线?
一言以蔽之,应该是长的。但它已经由我做了,并使我失去了一个多余的时钟。
有什么解决办法吗?
这只是我没有设定的选择吗?
谢谢
发布于 2015-02-20 19:45:53
因为您指定了16位类型,但是printf需要32位整数,所以您的结果需要进行符号扩展,这就是该代码所做的。然而,如果您对printf使用了适当的格式,那么两个版本都应该产生相同的输出。
像往常一样,您不需要内联的asm进行旋转,而且如果您曾经在内联asm中使用mov,那么很可能您做错了。
发布于 2015-02-20 20:09:40
好的,
因此,解决办法是设置int32_t而不是int16_t。
现在密码是..。2个cpu周期更快。
这太荒谬了。
但我现在非常喜欢集会:)
https://stackoverflow.com/questions/28636763
复制相似问题