这个汇编循环中的第五个参数是什么?

问题描述

我正在为我的CIS班学习汇编,并且遇到了以下问题:

考虑以下x86-64代码

loop:
   movq %rsi,%rcx
   movl $1,%eax
   movl $0,%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当然是返回值,我相信%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 $1,%eax     <=> RetVal = 1
    movl $0,%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;
}