问题描述
当我逐步浏览我的一个库中的一些新代码时,我注意到第一个参数似乎进入 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
解决方法
这不是你想的那样 - 在序言中:
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 在这个反汇编中没有出现。