【发布时间】:2019-03-18 17:02:01
【问题描述】:
一个函数test_two有如下整体结构:
long test_two(unsigned long x) {
long val = 0;
int i;
for(i=64; i != 0; i--) {
val = (val<<1)|(x & 0x1);
x>>=1;
}
return val;
}
gcc C 编译器生成以下汇编代码:
test_two:
movl $64, %edx
movl $0, %eax
.L10:
movq %rdi, %rcx
andl $1, %ecx
addq %rax, %rax
orq %rcx, %rax
shrq %rdi
subq $1, %rdx
jne .L10
rep ret
我误解了 cmp 指令。所以我编辑了我原来的问题,我希望有些人不会混淆我的问题。对不起他们。
【问题讨论】:
-
for(i=64 , i != 0 , i--)无法编译。请发布显示问题的Minimal, Complete, and Verifiable example。 -
像
addq这样的指令不仅处理操作,它们还根据操作的结果设置一些标志,比如零标志。jne如果未设置零标志,则执行跳转。 -
您的 asm 与您的 C 不匹配,即使您将
for中的,更改为;。short在 x86-64 System V ABI 和 Windows x64 中都是 16 位类型,因此您会得到subw。 godbolt.org/z/Jq6EZb(但编译器可以将大多数其他操作提升为 dword 操作数大小以提高效率,因为有符号溢出是 UB。)更重要的是,结构不同:它以movl $64, %edx开头,然后像你一样将 EAX 归零期望来自 C 源代码。 -
@WeatherVane 是的,你是对的。我认为教科书不正确。
标签: c for-loop assembly x86-64