这个汇编循环中的第五个参数是什么?
What is the fifth argument in this assembly loop?
我正在为我的 CIS class 学习汇编,我遇到了以下问题:
考虑以下 x86-64 代码:
loop:
movq %rsi, %rcx
movl , %eax
movl [=10=], %edx
.L2:
testq %rax, %rax
je .L4
movq %rax, %r8
andq %rdi, %r8
orq %r8, %rdx
salq %cl, %rax
jmp .L2
.L4:
movq %rdx, %rax
ret
上面的代码是通过编译 C 代码(使用 Arch gcc)生成的,具有以下总体形式:
long loop(long a, long b) {
long result = 0;
for (long mask = ?; mask != ?; mask <<= ?) {
result |= (? & ?);
}
return result;
}
将上面的x86-64代码复制到C文件中作为注释。根据 x、y、结果和掩码对 x86-64 代码的每一行进行注释。
好吧,所以 %rax
当然是 return 值,我相信 %rdi, %rsi, %rdx, %rcx
分别是 a, b, result, mask
。但让我感到困惑的是代码中假定的第五个参数,%r8
。我是否误解了汇编语言中的参数,或者汇编语言中的 for 循环有什么不同?非常感谢任何反馈!
好了,看完这些评论,我想我找到了答案。似乎我误解了寄存器参数——认为它们 必须 连接到 C 代码中的变量。事实证明他们没有。所以我把 C 代码放在一边,坐下来分析程序集,我想我已经正确地写出了每个步骤正在做的事情(然后是等效的 C 代码)。不过,如果有人能够的话,我希望得到一些确认。
汇编函数:
%eax, %rax = RetVal
%rdi = Arg1 = a
%rsi = Arg2 = b
%edx, %rdx = Arg3 = result
%cl, %rcx = Arg4 = mask
%r8 = Arg5
loop:
movq %rsi, %rcx <=> Arg4 = Arg2
movl , %eax <=> RetVal = 1
movl [=10=], %edx <=> Arg3 = 0
.L2:
testq %rax, %rax <=> if RetVal == 0
je .L4 <=> go to .L4
movq %rax, %r8 <=> Arg5 = RetVal
andq %rdi, %r8 <=> Arg5 = (Arg5 & Arg1)
orq %r8, %rdx <=> Arg3 = (Arg3 | Arg5)
salq %cl, %rax <=> RetVal = (RetVal << Arg4)
jmp .L2 <=> go to .L2
.L4:
movq %rdx, %rax <=> RetVal = Arg3
ret <=> return RetVal
等效的 C 代码(?):
long loop(long a, long b) {
long result = 0;
for (long mask = b; mask != 0; mask <<= 1) {
result |= (mask & a);
}
return result;
}
我正在为我的 CIS class 学习汇编,我遇到了以下问题:
考虑以下 x86-64 代码:
loop:
movq %rsi, %rcx
movl , %eax
movl [=10=], %edx
.L2:
testq %rax, %rax
je .L4
movq %rax, %r8
andq %rdi, %r8
orq %r8, %rdx
salq %cl, %rax
jmp .L2
.L4:
movq %rdx, %rax
ret
上面的代码是通过编译 C 代码(使用 Arch gcc)生成的,具有以下总体形式:
long loop(long a, long b) {
long result = 0;
for (long mask = ?; mask != ?; mask <<= ?) {
result |= (? & ?);
}
return result;
}
将上面的x86-64代码复制到C文件中作为注释。根据 x、y、结果和掩码对 x86-64 代码的每一行进行注释。
好吧,所以 %rax
当然是 return 值,我相信 %rdi, %rsi, %rdx, %rcx
分别是 a, b, result, mask
。但让我感到困惑的是代码中假定的第五个参数,%r8
。我是否误解了汇编语言中的参数,或者汇编语言中的 for 循环有什么不同?非常感谢任何反馈!
好了,看完这些评论,我想我找到了答案。似乎我误解了寄存器参数——认为它们 必须 连接到 C 代码中的变量。事实证明他们没有。所以我把 C 代码放在一边,坐下来分析程序集,我想我已经正确地写出了每个步骤正在做的事情(然后是等效的 C 代码)。不过,如果有人能够的话,我希望得到一些确认。
汇编函数:
%eax, %rax = RetVal
%rdi = Arg1 = a
%rsi = Arg2 = b
%edx, %rdx = Arg3 = result
%cl, %rcx = Arg4 = mask
%r8 = Arg5
loop:
movq %rsi, %rcx <=> Arg4 = Arg2
movl , %eax <=> RetVal = 1
movl [=10=], %edx <=> Arg3 = 0
.L2:
testq %rax, %rax <=> if RetVal == 0
je .L4 <=> go to .L4
movq %rax, %r8 <=> Arg5 = RetVal
andq %rdi, %r8 <=> Arg5 = (Arg5 & Arg1)
orq %r8, %rdx <=> Arg3 = (Arg3 | Arg5)
salq %cl, %rax <=> RetVal = (RetVal << Arg4)
jmp .L2 <=> go to .L2
.L4:
movq %rdx, %rax <=> RetVal = Arg3
ret <=> return RetVal
等效的 C 代码(?):
long loop(long a, long b) {
long result = 0;
for (long mask = b; mask != 0; mask <<= 1) {
result |= (mask & a);
}
return result;
}