当前位置:网站首页>【循环语句】
【循环语句】
2022-07-23 02:49:00 【小鸡岛~】
一. while
提出问题
- while语句用什么指令进行跳转的呢?答:jmp,je指令
- 在哪个地方存放这条指令呢?
C++
ListNode* deleteDuplicates(ListNode* head) {
if (!head) {
return head;
}
ListNode* cur = head;
while (cur->next) {
if (cur->val == cur->next->val) cur->next = cur->next->next;
else cur = cur->next;
}
return head;
}
汇编语句
007E1002 in al,dx
007E1003 push ecx
007E1004 cmp dword ptr [ebp+8],0
007E1008 jne 007E100F
007E100A mov eax,dword ptr [ebp+8]
007E100D EB 3D jmp 007E104C
007E100F mov eax,dword ptr [ebp+8]
007E1012 mov dword ptr [ebp-4],eax
007E1015 mov ecx,dword ptr [ebp-4]
007E1018 cmp dword ptr [ecx+4],0
007E101C je 007E1049
007E101E mov edx,dword ptr [ebp-4]
007E1021 mov eax,dword ptr [edx+4]
007E1024 mov ecx,dword ptr [ebp-4]
007E1027 mov edx,dword ptr [ecx]
007E1029 cmp edx,dword ptr [eax]
007E102B jne 007E103E
007E102D mov eax,dword ptr [ebp-4]
007E1030 mov ecx,dword ptr [eax+4]
007E1033 mov edx,dword ptr [ebp-4]
007E1036 mov eax,dword ptr [ecx+4]
007E1039 mov dword ptr [edx+4],eax
007E103C jmp 007E1047
007E103E mov ecx,dword ptr [ebp-4]
007E1041 mov edx,dword ptr [ecx+4]
007E1044 mov dword ptr [ebp-4],edx
007E1047 jmp 007E1015
007E1049 mov eax,dword ptr [ebp+8]
机器码
EC
51
83 7D 08 00
75 05
8B 45 08
EB 3D
8B 45 08
89 45 FC
8B 4D FC
83 79 04 00
74 2B
8B 55 FC
8B 42 04
8B 4D FC
8B 11
3B 10
75 11
8B 45 FC
8B 48 04
8B 55 FC
8B 41 04
89 42 04
EB 09
8B 4D FC
8B 51 04
89 55 FC
EB CC
8B 45 08
设计实验:
int main()
{
int* pWorth = NULL;
while (pWorth)
{
std::cout << "有意义";
}
}
汇编
mov dword ptr [ebp-4],0
cmp dword ptr [ebp-4],0
je 00871026
push 873138h
mov eax,dword ptr ds:[00873068h]
push eax
call 008710B0
add esp,8
jmp 0087100B
当执行完第二行的cmp指令后,ZF位的值改变了,说明ZF影响je指令是否会跳转

发现规律
- 当ZF为1,je指令会被执行,使EIP的值改变,从而跳转到指定的内存地址;当ZF为0,je指令只会使EIP寄存器+2;
知识点:
- ZF位:零标志位,代表指令运算的结果为零时会设置为1,代表了两个数是否相等
得出结论
- while语句的本质是mov , cmp, je, jmp指令的组合
- jmp指令的作用是跳到while语句的首地址,以实现重复执行指令
- je指令的作用是跳转到jmp指令后面的的地址,避免死循环的结果,需要与cmp指令,mov指令配合使用
- 注意点:while代码块里面的代码中必须要有让循环退出的数据或break语句,否则会使程序进入****死循环状态

二.do{}while()
猜测:该语句也有cmp,je,mov指令,只不过跟jmp指令放在了一起
C++
int main()
{
int* pWorth = NULL;
do
{
std::cout << "有意义";
}while (pWorth == NULL);
}
汇编
00791002 in al,dx
00791003 push ecx
00791004 mov dword ptr [ebp-4],0
0079100B push 793138h
00791010 mov eax,dword ptr ds:[00793068h]
00791015 push eax
00791016 call 007910B0
0079101B add esp,8
0079101E cmp dword ptr [ebp-4],0
00791022 je 0079100B
00791024 xor eax,eax
00791026 mov esp,ebp
00791028 pop ebp
00791029 ret
机器码:
EC
51
C7 45 FC 00 00 00 00
68 38 31 79 00
A1 68 30 79 00
50
E8 95 00 00 00
83 C4 08
83 7D FC 00
74 E7
33 C0
8B E5
5D
C3
发现规律:
do while 语句是由cmp指令,跳转指令(jne,je)组合而成的,而跳转的地址是代码块的首地址
得出结论:
- do while 代码块里面的指令必须要有改动数据的代码或break语句,否则会造成程序的死循环

三. for(){}
提出问题:
- 在括号里的变量i为什么在for循环外不能使用?
- i++指令什么地方执行呢?猜测:在jmp指令后面 答案:
- 第一个分号前的代码会被多次执行吗?
C++
vector<int> twoSum(vector<int>& nums, int target){
vector<int> ret;
for (int i = 0; i < nums.size(); i++)
{
for (int y = i + 1; y < nums.size(); y++)
{
if (nums[i] + nums[y] == target) {
ret.push_back(i);
ret.push_back(y);
break;
};
}
}
return ret;
}
汇编
00C813A0 push 0Ch
00C813A2 lea ecx,[ret]
00C813A5 call std::vector<int,std::allocator<int> >::__autoclassinit2 (0C81480h)
00C813AA lea ecx,[ret]
00C813AD call std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (0C817F0h)
00C813B2 mov dword ptr [ebp-4],0
00C813B9 mov dword ptr [ebp-20h],0
00C813C0 jmp twoSum+5Bh (0C813CBh)
i++
00C813C2 mov eax,dword ptr [ebp-20h]
00C813C5 add eax,1
00C813C8 mov dword ptr [ebp-20h],eax
00C813CB mov ecx,dword ptr [nums]
00C813CE call std::vector<int,std::allocator<int> >::size (0C815C0h)
00C813D3 cmp dword ptr [ebp-20h],eax
00C813D6 jae twoSum+0CAh (0C8143Ah)
00C813D8 mov ecx,dword ptr [ebp-20h]
00C813DB add ecx,1
00C813DE mov dword ptr [ebp-24h],ecx
00C813E1 jmp twoSum+7Ch (0C813ECh)
00C813E3 mov edx,dword ptr [ebp-24h]
00C813E6 add edx,1
00C813E9 mov dword ptr [ebp-24h],edx
00C813EC mov ecx,dword ptr [nums]
00C813EF call std::vector<int,std::allocator<int> >::size (0C815C0h)
00C813F4 cmp dword ptr [ebp-24h],eax
00C813F7 jae twoSum+0C8h (0C81438h)
00C813F9 mov eax,dword ptr [ebp-20h]
00C813FC push eax
00C813FD mov ecx,dword ptr [nums]
00C81400 call std::vector<int,std::allocator<int> >::operator[] (0C815A0h)
00C81405 mov esi,eax
00C81407 mov ecx,dword ptr [ebp-24h]
00C8140A push ecx
00C8140B mov ecx,dword ptr [nums]
00C8140E call std::vector<int,std::allocator<int> >::operator[] (0C815A0h)
00C81413 mov edx,dword ptr [esi]
00C81415 add edx,dword ptr [eax]
00C81417 cmp edx,dword ptr [target]
00C8141A jne twoSum+0C6h (0C81436h)
00C8141C lea eax,[ebp-20h]
00C8141F push eax
00C81420 lea ecx,[ret]
00C81423 call std::vector<int,std::allocator<int> >::push_back (0C815F0h)
00C81428 lea ecx,[ebp-24h]
00C8142B push ecx
00C8142C lea ecx,[ret]
00C8142F call std::vector<int,std::allocator<int> >::push_back (0C815F0h)
00C81434 jmp twoSum+0C8h (0C81438h)
00C81436 jmp twoSum+73h (0C813E3h)
00C81438 jmp twoSum+52h (0C813C2h)
机器码
6A 0C
8D 4D E4
E8 D6 00 00 00
8D 4D E4
E8 3E 04 00 00
C7 45 FC 00 00 00 00
C7 45 E0 00 00 00 00
EB 09
8B 45 E0
83 C0 01
89 45 E0
8B 4D 0C
E8 ED 01 00 00
39 45 E0
73 62
8B 4D E0
83 C1 01
89 4D DC
EB 09
8B 55 DC
83 C2 01
89 55 DC
8B 4D 0C
E8 CC 01 00 00
39 45 DC
73 3F
8B 45 E0
50
8B 4D 0C
E8 9B 01 00 00
8B F0
8B 4D DC
51
8B 4D 0C
E8 8D 01 00 00
8B 16
03 10
3B 55 10
75 1A
8D 45 E0
50
8D 4D E4
E8 C8 01 00 00
8D 4D DC
51
8D 4D E4
E8 BC 01 00 00
EB 02
EB AB
EB 88
设计实验
jae指令
当ZF = 0时,CF = 0时时,jae指令会跳转到对应的内存地址
当ZF = 1时,CF = 0时时,jae指令会跳转到对应的内存地址
当ZF = 0时,CF = 1时时,jae指令会使EIP+2
得出结论
- for语句由以下模块组成的汇编指令, 第一次执行指令到i++,会跳过直接比较
- 当程序符号条件就进行重复执行指令阶段,直到数据不符合条件为止,因此代码块里必须有让条件不符合的数据或break语句

边栏推荐
猜你喜欢

Is the sub database and sub table really suitable for your system? Talk about how to select sub databases, sub tables and newsql

实现方法pathListToMap,能够将输入的pathList转化为具有层级结构的map类型

【HiFlow】定期发送腾讯云短信发送群

Reverse pairs in an array

spark分区算子partitionBy、coalesce、repartition

分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择

Excel简单使用宏

用现代化的开发方法和思维,打跑遗留系统“拦路虎”

隐藏网站服务器响应头中 PHP 版本信息

567. Arrangement of strings
随机推荐
This is how the permission system is designed, yyds
中信期货网上开户是否安全,网上开户会被骗吗?
线程池面试
中信期货是正规的期货公司吗,开户是否安全?
Verilog grammar basics HDL bits training 04
数组中的逆序对
笔记——记录@RefreshScope动态刷新配置失效的解决方式
non-Boost Asio 笔记: UDP UART SocketCAN Multicast UDS
[introduction to node basics] - node middle layer does interface forwarding to realize cross domain requests
权限系统就该这么设计,yyds
本地提权的学习
31岁才转行程序员,目前34了,我来说说我的经历和一些感受吧...
抖音白天与晚上触发不同特效的Graph节点编写
kali下安装go环境
构建一个CPU模拟器
Is it safe for outsiders to open accounts in Huatai? Will you be cheated
Hide the PHP version information in the response header of the website server
可视化全链路日志追踪
技术分享 | 大事务阻塞 show master status
毕业1年,放弃实习机会,在家自学软件测试,同学实习刚结束,我已成月薪12k测试工程师