【发布时间】:2017-10-30 21:41:00
【问题描述】:
我最近正在阅读 CSAPP,并且对汇编代码示例有疑问。这是一个来自 CSAPP 的例子,代码如下:
long pcount_goto
(unsigned long x) {
long result = 0;
result += x & 0x1;
x >>= 1;
if(x) goto loop;
return result;
 而对应的汇编代码为:
movl $0, %eax # result = 0
.L2: # loop:
movq %rdi, %rdx
andl $1, %edx # t = x & 0x1
addq %rdx, %rax # result += t
shrq %rdi # x >>= 1
jne .L2 # if (x) goto loop
rep; ret
我的问题可能看起来很幼稚,因为我对汇编代码很陌生,但如果有人能帮助我解决这些问题,我将不胜感激。
%eax、%rax(还有 %edx、%rdx)有什么区别。我已经看到它们出现在汇编代码中,但它们似乎指的是相同的空间/地址。使用两个不同的名称有什么意义?
-
在代码中
andl $1, %edx # t = x & 0x1我知道 %edx 现在存储 t,但是 x 到哪里去呢?
-
在代码中
shrq %rdi我觉得
shrq 1, %rdi应该更好吗?
-
对于
jne .L2 # if (x) goto loop如果 (x) 去哪里了?我看不到任何判断。
【问题讨论】:
-
源缺少
loop:标签(尽管不难想象它属于哪里)。如果您对edx与rdx的区别感到困惑,那么在 Jester 回答之后,您应该会说“啊哈,但如果and只屏蔽 32b,为什么add使用 64b”...答案是,当使用e变体时,x86-64 将清除寄存器的高位 32b,因此andl $1,%edx与andq $1,%rdx具有相同的结果,但机器码短了 1 个字节。