序言
为了提高可读性,我添加了这一段,另外由于我用的是VS2017,会出现一些奇怪的错误,也一并在这里解决。
例如本次出现了这个错误(安全检查错误):错误 C4996 ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. Project1 e:\projects\c\project1\project1\no.3.c 17
解决办法:#define _CRT_SECURE_NO_WARNINGS
在代码中加上这个宏定义,最好是在最上方加。其他方法自行问度娘。
C代码
这个实例很简单,就是计算两个整数的乘积,下面看代码:
/*
算法:
{
提示用户输入数据;
输入变量x和y的值;
计算乘积;
输出乘积;
}
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int x, y, m;
printf("Please input x and y\n");
scanf("%d %d", &x, &y);
m = x * y;
printf("%d * %d = %d\n", x, y, m);
getchar();
getchar();
return 0;
}
我对书中的代码稍稍添加了一些,getchar()
函数防止运行的时候一闪而过。
汇编代码
我在 int main
处下的断点,直接调试查看反汇编代码,如下:
--- e:\projects\c\project1\project1\no.3.c -------------------------------------
1: /*
2: 算法:
3: {
4: 提示用户输入数据;
5: 输入变量x和y的值;
6: 计算乘积;
7: 输出乘积;
8: }
9: */
10:
11: #define _CRT_SECURE_NO_WARNINGS
12:
13: #include <stdio.h>
14:
15: int main()
16: {
00171920 55 push ebp # 开始老套路,提升堆栈,开辟缓冲区,保存现场
00171921 8B EC mov ebp,esp
00171923 81 EC E8 00 00 00 sub esp,0E8h
00171929 53 push ebx
0017192A 56 push esi
0017192B 57 push edi
0017192C 8D BD 18 FF FF FF lea edi,[ebp-0E8h]
00171932 B9 3A 00 00 00 mov ecx,3Ah
00171937 B8 CC CC CC CC mov eax,0CCCCCCCCh
0017193C F3 AB rep stos dword ptr es:[edi]
0017193E A1 04 A0 17 00 mov eax,dword ptr [__security_cookie (017A004h)]
00171943 33 C5 xor eax,ebp
00171945 89 45 FC mov dword ptr [ebp-4],eax
00171948 B9 03 C0 17 00 mov ecx,offset _00E4A959_no@3@c (017C003h)
0017194D E8 C5 F8 FF FF call @__CheckForDebuggerJustMyCode@4 (0171217h)
17: int x, y, m;
18: printf("Please input x and y\n");
00171952 68 30 7B 17 00 push offset string "Please input x and y\n" (0177B30h) //从内存中取出,压入堆栈中
00171957 E8 EF F6 FF FF call _printf (017104Bh) //调用函数
0017195C 83 C4 04 add esp,4 // 外平栈,一个参数+4,就是上面的字符串
19: scanf("%d %d", &x, &y);
0017195F 8D 45 E8 lea eax,[y] //取局部变量y的地址,存入eax寄存器
00171962 50 push eax //将eax压入堆栈
00171963 8D 4D F4 lea ecx,[x] //同上
00171966 51 push ecx
00171967 68 4C 7B 17 00 push offset string "%d %d" (0177B4Ch)
0017196C E8 2F F7 FF FF call _scanf (01710A0h)
00171971 83 C4 0C add esp,0Ch // C是十进制的12,也就是由三个参数
20: m = x * y;
00171974 8B 45 F4 mov eax,dword ptr [x] //将内存地址为变量x的地址中数据存入eax中
00171977 0F AF 45 E8 imul eax,dword ptr [y] //有符号乘法运算,在将Y中的数据与eax进行有符号乘法运算
//结果存入eax寄存器
0017197B 89 45 DC mov dword ptr [m],eax //将eax中的结果存入变量m的内存地址中
21: printf("%d * %d = %d\n", x, y, m);
0017197E 8B 45 DC mov eax,dword ptr [m] //下面的都不难理解,不一一叙说
00171981 50 push eax
00171982 8B 4D E8 mov ecx,dword ptr [y]
00171985 51 push ecx
00171986 8B 55 F4 mov edx,dword ptr [x]
00171989 52 push edx
0017198A 68 54 7B 17 00 push offset string "%d * %d = %d\n" (0177B54h)
0017198F E8 B7 F6 FF FF call _printf (017104Bh)
00171994 83 C4 10 add esp,10h
22: getchar();
00171997 8B F4 mov esi,esp
00171999 FF 15 70 B1 17 00 call dword ptr [__imp__getchar (017B170h)]
0017199F 3B F4 cmp esi,esp
22: getchar();
001719A1 E8 7B F8 FF FF call __RTC_CheckEsp (0171221h)
23: getchar();
001719A6 8B F4 mov esi,esp
001719A8 FF 15 70 B1 17 00 call dword ptr [__imp__getchar (017B170h)]
001719AE 3B F4 cmp esi,esp
001719B0 E8 6C F8 FF FF call __RTC_CheckEsp (0171221h)
24: return 0;
001719B5 33 C0 xor eax,eax
25: }
就截取这些代码,main函数后的检查esp是否正常的代码就没截取。
新接触了一个指令:imul
指令意思是有符号数乘法运算,拓展一下, mul
是无符号数的乘法运算,指令格式如下:
IMUL al,r/m8 : AX <= AL * r/m
IMUL ax,r/m16 : DX:AX <= AX * r/m
IMUL eax,r/m32 : EDX:EAX <= EAX * r/m
IMUL r16,r/m16 : 字寄存器 <= 字寄存器 * r/m
IMUL r32,r/m32 : 双字寄存器 <= 双字寄存器 * r/m 双字
IMUL r16,r/m16,imm8 : 字寄存器 <= r/m16 * 符号扩展的立即数字节
IMUL r32,r/m32,imm8 : 双字寄存器 r/m32 * 符号扩展的立即数字节
IMUL r16,imm8 : 字寄存器 <= 字寄存器 * 符号扩展的立即数字节
IMUL r32,imm8 : 双字寄存器 <= 双字寄存器 * 符号扩展的立即数字节
IMUL r16,r/m16,imm16 : 字寄存器 <= r/m16 * 立即数字
IMUL r32,r/m32,imm32 : 双字寄存器 <= r/m32 * 立即数双字
IMUL r16,imm16 : 字寄存器 <= r/m16 * 立即数字
IMUL r32,imm32 : 双字寄存器 <= r/m32 * 立即数双字
r表示寄存器,32,16表示位数
m表示内存
imm表示立即数
结语
又学习了一部分,之前还没在反汇编代码中遇到imul,见得太少了,要多加练习。
PS:今天早上接到通知,要出差,很懵逼,第一次出差哎~,还好有同事一块,希望一切顺利!
如有错误,敬请指出,感谢指正! —2019-05-15 22:00:51 于苏州
最新评论
这个软件有bug的,客户端windows有些键不能用如逗号、句号
没有收到邮件通知
我的评论通知貌似坏掉了,定位一下问题
测试一下重新部署后的邮件功能
居然看到自己公司的MIB库,诚惶诚恐
那可能是RobotFramework-ride的版本问题。我装的1.7.4.2,有这个限制。我有空再尝试下旧版本吧,感谢回复。
你好!我在python2.7中安装RobotFramework-ride的时候提示wxPython的版本最高是2.18.12,用pip下载的wxPython版本是4.10,而且我在那个路径下没有找到2
真的太好了,太感谢了,在bilibili和CSDN上都找遍了,终于在你这里找到了