- 搞清楚调用约定
stdcall
、cdecl
、fastcall
,决定了参数传递、谁平衡栈。
- 不能以
push
的个数来确定参数的个数。
- 如果有参数,看
ret
平栈状态。
优化
ebp
省略优化。(帧优化)
- 内联优化
- 全程序优化(高版本限定):
内联优化
使用\Ob0|1|2|3
来设置内联优化级别。
0
/Od 下的默认值。 禁用内联扩展。
1
仅允许对标记为 inline、__inline 或 __forceinline 的函数或是在类声明中定义的 C++ 成员函数中进行扩展。
2
/O1 和 /O2 下的默认值。 允许编译器扩展任何未明确标记为无内联的函数。
3
此选项指定比 /Ob2 更积极的内联,但具有相同的限制。 /Ob3 选项自 Visual Studio 2019 起可用。
库函数容易被内联优化strlen
,且没有逆向恢复价值,release
版会被内联优化。
- 库函数强制内联。
- 可以使用
#pragma function(strcpy, strlen)
在msvc
中强制库函数使用内建函数,而不进行内联。
内联后特征
strlen
mov eax, DWORD PTR _argv$[esp-4]
mov eax, DWORD PTR [eax]
将首地址给到eax
。
lea edx, DWORD PTR [eax+1]
,edx
中存放首地址+1的地址值。
- 使用循环不断
test
结束符。
- 找到之后与
edx
相减,得到字符串长度。
strcpy
ecx
存放argv
的首元素,ecx+4
前往下一个元素(指针4个字节)。
mov BYTE PTR [eax], dl
将元素每次拷贝一个字节,传送到buf
中。
strcmp
如果发现字符不相等:
- 使用
sbb eax, eax
和 or eax, 1
来设置 eax
的值为 -1
或 1
,取决于哪个字符串更大。
- 这种逻辑是
strcmp
的标准返回值定义:正数、零、负数。
调用约定
cdecl
C调用约定
汇编特征:
stdcall
标准调用约定
fastcall
快速调用约定
ecx
、edx
作为前两个参数,多余的参数,从右往左入栈。
- 函数内部平栈。
汇编特征:
函数返回值
x86
机器上返回64
位返回值->edx.eax
值。