Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 当arg为64位长时,为什么gcc使用mov%esi,%ecx进行移位计数?_Assembly_X86_X86 64 - Fatal编程技术网

Assembly 当arg为64位长时,为什么gcc使用mov%esi,%ecx进行移位计数?

Assembly 当arg为64位长时,为什么gcc使用mov%esi,%ecx进行移位计数?,assembly,x86,x86-64,Assembly,X86,X86 64,因此,我正在阅读《计算机系统:程序员的观点》第三版。对于其中一个实践问题解决方案,它说以下函数: long shift(long x, long n) { x <<= 4; x >>= n; return x; } 长移位(长x,长n) { x=n; 返回x; } 输出汇编代码,其中一部分将是(及其注释): #x在%rdi中,n在%rsi中 movq%rdi,%rax#得到x salq$4,%rax#x=n 假设基于x86-64 linux,

因此,我正在阅读《计算机系统:程序员的观点》第三版。对于其中一个实践问题解决方案,它说以下函数:

long shift(long x, long n)
{
    x <<= 4;
    x >>= n;
    return x;
}
长移位(长x,长n)
{
x=n;
返回x;
}
输出汇编代码,其中一部分将是(及其注释):

#x在%rdi中,n在%rsi中
movq%rdi,%rax#得到x
salq$4,%rax#x=n
假设基于x86-64 linux,“long”是四字大小


我的问题是关于我添加“问题”的那一行。既然n是“long”类型,为什么那行不是“movq%rsi,%rcx”?我认为这不是一个打字错误,因为他们特别添加了“Get n(4字节)”。

只使用了
rcx
cl
)的低位字节。但是,
movb%sil,%cl
可能会导致部分寄存器暂停,而
movl%esi,%ecx
不会(AFAIK),因为它会隐式清除
rcx
的上半部分。虽然只有8位
cl
用作
sar
的参数,但实际上只有
cl
的低6位用于移位,即,对于
n=0x12345678
而言,CPU执行的实际移位仅为
0x78&0x3F=0x38=56
位移位。对于32位目标,仅使用5位,以此类推:。。。定义为64b长的
n
在这种特定情况下已经在C源代码级别上过多了。这让我想知道,C操作符
>
是否是
n>63
的UB。。。关于设置完整
rcx
的原因(写入
ecx
set
rcx
)=性能。现在不用担心了?因为编译器知道该值将以任何方式被截断为6位(通过
sar
指令-我的意思是暂时截断,用于移位,而不是将其写回
cl
truncated),并且
mov%esi,%ecx
的操作码(-1B)比
mov%rsi,%rcx
短,因此,它具有相同或更好的性能。(较短的机器代码会使指令缓存变得不那么杂乱,因此它为性能关键型代码提供了更大的缓冲区)为什么
movb%sil,%cl
次优:它需要一个REX前缀。它不会直接导致部分寄存器暂停,@Michael,(因为您以后不会阅读
%rcx
的其余部分),但
mov
本身确实会在某些CPU上创建错误的依赖关系:。32位
mov
是最佳选择,因为它只有2个字节,而
mov%rsi,%rcx
也需要一个REX前缀。可能重复:。我认为这些问答涵盖了这一点,尤其是评论。如果有人认为它需要自己的答案,我们可以重新打开它。
# x in %rdi, n in %rsi
movq %rdi, %rax        # Get x
salq $4, %rax          # x <<= 4 
movl %esi, %ecx        # Get n (4 bytes) **QUESTION**
sarq %cl, %rax         # x >>= n