【问题标题】:Why Would A Function Call Place its First Argument into CPU Register RDX? [closed]为什么函数调用会将其第一个参数放入 CPU 寄存器 RDX? [关闭]
【发布时间】:2021-03-05 21:08:27
【问题描述】:

当我在我的一个库中逐步执行一些新代码时,我注意到第一个参数似乎进入了 RDX 寄存器,而不是记录在案的 RCX 寄存器。虽然算不上一场世界末日的灾难,但我很好奇;为什么会这样,除非 RCX 被搁置以传递对 this 的引用,就像在 C++ 中发生的那样。同样,被调用的例程是实例上的静态方法可能很重要。

下面是整个函数的反汇编,是一个非常基础的语法糖函数。

        /// </summary>
        /// <param name="pastrAdditionalMessages">
        /// Pass in the optional list of additonal messages if needed. Status
        /// codes zero and one are covered by stanard messages that are pulled
        /// from the resource strings stored in WizardWrx.Common.dll.
        /// </param>
        /// <returns>
        /// The total number of messages is as described under <paramref name="pastrAdditionalMessages"/>.
        /// </returns>
        private static int ComputeMessageCount ( string [ ] pastrAdditionalMessages )
        {
00007FFED9688940  push        rbp  
00007FFED9688941  push        rdi  
00007FFED9688942  push        rsi  
00007FFED9688943  sub         rsp,30h  
00007FFED9688947  mov         rbp,rsp  
00007FFED968894A  mov         rsi,rcx  
00007FFED968894D  lea         rdi,[rbp+20h]  
00007FFED9688951  mov         ecx,4  
00007FFED9688956  xor         eax,eax  
00007FFED9688958  rep stos    dword ptr [rdi]  
00007FFED968895A  mov         rcx,rsi  
00007FFED968895D  mov         qword ptr [rbp+50h],rcx  
00007FFED9688961  cmp         dword ptr [7FFED95791F8h],0  
00007FFED9688968  je          WizardWrx.ConsoleAppAids3.ConsoleAppStateManager.ComputeMessageCount(System.String[])+02Fh (07FFED968896Fh)  
00007FFED968896A  call        00007FFF390CCBA0  
00007FFED968896F  nop  
            return pastrAdditionalMessages == null ? STANDARD_MESSAGE_COUNT : pastrAdditionalMessages.Length + STANDARD_MESSAGE_COUNT;
00007FFED9688970  cmp         qword ptr [rbp+50h],0  
00007FFED9688975  je          WizardWrx.ConsoleAppAids3.ConsoleAppStateManager.ComputeMessageCount(System.String[])+046h (07FFED9688986h)  
00007FFED9688977  mov         rax,qword ptr [rbp+50h]  
00007FFED968897B  mov         eax,dword ptr [rax+8]  
00007FFED968897E  add         eax,2  
00007FFED9688981  mov         dword ptr [rbp+20h],eax  
00007FFED9688984  jmp         WizardWrx.ConsoleAppAids3.ConsoleAppStateManager.ComputeMessageCount(System.String[])+04Dh (07FFED968898Dh)  
00007FFED9688986  mov         dword ptr [rbp+20h],2  
00007FFED968898D  mov         eax,dword ptr [rbp+20h]  
00007FFED9688990  mov         dword ptr [rbp+24h],eax  
00007FFED9688993  nop  
00007FFED9688994  jmp         WizardWrx.ConsoleAppAids3.ConsoleAppStateManager.ComputeMessageCount(System.String[])+056h (07FFED9688996h)  
        }   // private static int ComputeMessageCount
00007FFED9688996  mov         eax,dword ptr [rbp+24h]  
00007FFED9688999  lea         rsp,[rbp+30h]  
00007FFED968899D  pop         rsi  
00007FFED968899E  pop         rdi  
00007FFED968899F  pop         rbp  
00007FFED96889A0  ret  

【问题讨论】:

  • 你的反编译代码中rdx在哪里使用?

标签: c# assembly x86-64 calling-convention


【解决方案1】:

这不是你想的那样 - 在序言中:

00007FFED9688940  push        rbp       // SAVE RBP
00007FFED9688941  push        rdi       // SAVE RDI
00007FFED9688942  push        rsi       // SAVING RSI
00007FFED9688943  sub         rsp,30h   // ADD STACK SPACE
00007FFED9688947  mov         rbp,rsp   // SAVE STACK POINTER
00007FFED968894A  mov         rsi,rcx   // SAVING RCX - (Already contains your string[] argument)
00007FFED968894D  lea         rdi,[rbp+20h]  
00007FFED9688951  mov         ecx,4  
00007FFED9688956  xor         eax,eax  
00007FFED9688958  rep stos    dword ptr [rdi]  // STACK OPS ^^^
00007FFED968895A  mov         rcx,rsi  // *****  HERE Moving string[] back to RCX in preparation for the call
00007FFED968895D  mov         qword ptr [rbp+50h],rcx  
00007FFED9688961  cmp         dword ptr [7FFED95791F8h],0  
00007FFED9688968  je          WizardWrx.ConsoleAppAids3.ConsoleAppStateManager.ComputeMessageCount(System.String[])+02Fh (07FFED968896Fh)  
00007FFED968896A  call        00007FFF390CCBA0  

在调用函数之前,您的字符串数组似乎已经存在于 RCX 中。在方法调用之前,调用者保存 RBP、RDI 和 RSI,然后添加堆栈空间并将其当前的 RCX 指针保存到 RSI(将在函数返回后弹出)。

在此之后,有一些堆栈操作,然后为调用设置参数 - 只有一个,所以 mov rcx, rsi - 你的数组指针将进入 RCX,正如预期的那样。 RDX 在这个反汇编中没有出现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2019-10-19
    • 2016-02-15
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2014-12-30
    相关资源
    最近更新 更多