大家好,这是一项家庭作业。我给了一个由MSVC 32位Release生成的程序集,并进行了优化,我应该将其解码回C++。我在遇到问题的那一行中包含了函数的顶部。这些评论是我的,我是在尝试理解时写的。
注意:代码据说是从C++生成的。不是传统的ASM。
注意2:代码中有一个未定义行为的区域。
这是我坚持的路线
TheFunction: ; TheFunction(int* a, int s);
0F2D4670 push ebp ; Push/clear/save ebp
0F2D4671 mov ebp,esp ; ebp now points to top of stack
0F2D4673 push ecx ; Push/clear/save ecx
0F2D4674 push ebx ; Push/clear/save ebs
0F2D4675 push esi ; Push/clear/save esi
0F2D4676 mov ebx,edx ; ebx = int s
0F2D4678 mov esi,1 ; esi = 1
0F2D467D push edi ; calling convention ; Push/clear/save edi
0F2D467E mov edi,dword ptr [a (0F2D95E8h)] ; edi = a[0]
0F2D4684 cmp ebx,esi ; if(s < 1)
0F2D4686 jl SomeFunction+3Ch (0F2D46ACh) ; Jump to return
0F2D4688 nop dword ptr [eax+eax] ; !! <-- No op involving dereferencing? What does this do?
0F2D4690 mov eax,dword ptr [edi+esi*4-4] ; !! <-- edi is *a, while esi is 1. There is no address
here!
..... More code but I've figured these out ....
我或多或少地了解了该功能的要点。它是一个函数,该函数需要一个指向int的指针,一个基础数组和一个大小。然后,它从最后到第一个遍历数组中的每个元素,将其添加到随后的每个元素中并打印出来。但是,我仍然没有提供详细信息,需要帮助
两个问题,都在代码段的末尾。取消引用指针上的操作没有什么作用,我是否正在阅读最后一行以尝试取消引用内存中没有的内容?
最佳答案
nop dword ptr [eax+eax]
指令不执行任何操作。它甚至不访问操作数给定的内存位置。它实际上不执行任何操作。
它就在那里,因此下一条指令与16字节边界对齐。您会注意到下一条指令地址是0F2D4690,该地址以0结尾,这意味着它是16字节对齐的。这样可以提高循环的性能。某个地方会有一条指令作为循环的一部分跳回到0F2D4690。之所以使用这种特殊形式的NOP指令,是因为它以8个字节编码单个NOP指令。
该指令没有相应的C++代码。您不应该尝试在C++代码中表示它,而只是忽略它。
另请注意,您对mov edi,dword ptr [a (0F2D95E8h)]
的评论不正确。与其说是edi = a[0]
,不如说是edi = a
。变量a
根本不是参数,而是位于内存位置0F2D95E8h
的全局(或文件级静态)变量。该指令仅从内存中加载值。
关于c++ - MSVC 32位版本(作业)中的解码程序集。无操作是做什么的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60273483/