计算机系统基础 8 循环程序

news2024/12/24 10:37:43

概要

        两种实现方法——分支指令实现和专门的循环语句实现以及有关循环的优化。

分支指令实现

        倒计数

       ……

       MOV  ECX,循环次数

LOOPA:……

       ……

       DEC   ECX

       JNE   LOOPA     

        正计数 

       ……

       MOV  ECX,0

LOOPA

       ……

       INC  ECX

       CMP  ECX,  n

       JNE  LOOPA              

        循环次数不固定 

        比如要求一个以0为结束符的字符串的长度,需要通过指令来测试条件是否成立,决定继续循环还是结束循环。

下面例子(AX)中 1 出现的次数 -> CL     

MOV  CL, 0

L:  AND  AX , AX

    JZ   EXIT

    SAL  AX , 1

    JNC  L

    INC  CL

    JMP  L

EXIT:

或者这样

      MOV   CL,  0

      MOV   BX, 16

L:    SAL   AX , 1

      JNC   NEXT

      INC   CL

NEXT: DEC   BX

      JNZ   L

 专门的循环指令 

LOOP    标号

LOOPE   标号

LOOPNE  标号

JECXZ   标号

LOOP 

        ① (ECX) -1 ➡  ECX,

        ②若 (ECX)  不为0, 则转标号处执行。

    基本等价于: 

                  DEC   ECX

                  JNZ   标号

  (但LOOP指令对标志位无影响!)

LOOPE / LOOPZ 

        ①(ECX) - 1 ➡ ECX,

        ② 若(ECX)不为0, 且ZF=1,则转标号处执行。

   (等于或为0循环转移指令, 本指令对标志位无影响)

        32位段用 ECX16位段用 CX 

例:判断以BUF为首址的10个字节中是否有非0字节。

    有,则置ZF为0, 否则ZF置为1。                    

      MOV    ECX, 10

      MOV    EBX, OFFSET BUF -1

L3 :  INC    EBX

      CMP    BYTE PTR [EBX], 0

      LOOPE  L3

LOOPNE  / LOOPNZ  

        ①(ECX) -1 ➡ ECX

        ②若(ECX)≠0, 且ZF=0,则转标号处执行。

例:判断以MSG为首址的10个字节中的串中是否有空格字符。无空格字符,置ZF为0,否则为1。                               

       MOV     ECX,  10

       MOV     EBX,  OFFSET MSG -1

L4 :   INC     EBX

       CMP     BYTE PTR [EBX],‘ ’

       LOOPNE  L4

JECXZ  标号

     若 (ECX) 为0, 则转标号处执行。

    (先判断,后执行循环体时,可用此语句,标号为循环结束处)

 有关循环的优化方法

         循环展开

int  i = 0, sum = 0, a[5];

    ……

for  (i = 0; i < 5; i++)       sum += a[i];

Debug版本

00D71750  mov   dword ptr [i],0 

00D71757  jmp   f+62h (0D71762h) 

00D71759  mov   eax,dword ptr [i

00D7175C  add   eax,1 

00D7175F  mov   dword ptr [i],eax 

00D71762  cmp   dword ptr [i],5    

00D71766  jge   f+77h (0D71777h) 

00D71768  mov   eax,dword ptr [i]

00D7176B  mov   ecx,dword ptr [sum] 

00D7176E  add   ecx,dword ptr a[eax*4] 

00D71772  mov   dword ptr [sum],ecx 

00D71775  jmp   f+59h (0D71759h)

00D71777  // 循环结束

Release版本:

 mov  eax,dword ptr [ebp-8] 

 add  eax,dword ptr [ebp-0Ch] 

 add  eax,dword ptr [ebp-10h] 

 add  eax,dword ptr [ebp-14h] 

 add  eax,dword ptr [ebp-18h] 

 mov  sum, eax

若循环变量从5改为n

          mov  edi, sum  ; edi来存放 和

          xor  eax, eax  ; eax 对应 i

          mov  edx, n    ; edx 对应 n

          jmp  main+0C5h (05E1145h)

005E1140  add  edi,dword ptr [ebp+eax*4-18h] 

005E1144  inc  eax 

005E1145  cmp  eax,edx 

005E1147  jl   main+0C0h (05E1140h)

变量与寄存器绑定,语句数量大幅减少,循环部分由 10 条语句减为 4 条语句

        传输优化

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void main()
{
char  buf1[20];
char  buf2[20];
int   i;
scanf("%s", buf1); 
for (i = 0;i < 20;i++)
   buf2[i] = buf1[i];
printf("%s\n", buf2);
return;
}

for (i = 0;i < 20;i++)

buf2[i] = buf1[i];

printf("%s\n", buf2);

0025109E  mov         eax,dword ptr [ebp-8] 

002510A1  movups      xmm0,xmmword ptr [buf1] 

002510A5  mov         dword ptr [ebp-1Ch],eax 

002510A8  lea         eax,[buf2] 

002510AB  push        eax 

002510AC  push        offset string "%s\n" (0252104h) 

002510B1  movups      xmmword ptr [buf2],xmm0 

002510B5  call        printf (0251020h) 

可以看到,ebp - 8就是buf1+16

buf1 的前16个字节拷贝到 xmm0,后4个字节拷贝到 eax,再分别送到 buf2 相应位置

 但是像这种,就不好优化

void main()
{
char  buf1[20];
char  buf2[20];
int   i;
scanf("%s", buf1); 
……
printf("%s\n", buf2);
return;
}
void fcopy(char* dst, char* src)
{
    int i;
    for (i = 0;i < 20;i++)
    {
       *dst = *src;
       dst++;
       src++;
    }
}

scanf("%s", buf1);

003D1090  lea         eax,[ebp-18h] 

003D1093  push        eax 

003D1094  push        3D2100h 

003D1099  call        003D1050 

003D109E  add         esp,8 

003D10A1  xor         eax,eax 

fcopy(buf1-20, buf1);

003D10A3  mov         cl,byte ptr [ebp+eax-18h] 

003D10A7  mov         byte ptr [ebp+eax-2Ch],cl 

003D10AB  inc         eax 

003D10AC  cmp         eax,14h 

003D10AF  jl          003D10A3 

printf("%s\n", buf2);

总结

编译优化

  • 循环展开:消除了循环
  • 与寄存器绑定:减少访存操作,减少指令
  • XMM寄存器、成组运算等,减少指令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1687407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka-集群管理者(Controller)选举机制、任期(epoch)机制

Kafka概述 Kafka-集群管理者&#xff08;Controller&#xff09;选举机制 Kafka中的Controller是Kafka集群中的一个特殊角色&#xff0c;负责对整个集群进行管理和协调。Controller的主要职责包括分区分配、副本管理、Leader选举等。当当前的Controller节点失效或需要进行重新…

【CALayer-CALayer的transform属性 Objective-C语言】

一、接下来,我们来说的是这个,transform的属性 1.layer的transform属性, 把最后一份代码command + C、command + V、一份儿,改个名字, Name:04-CALayer的transform属性, 我们把这个代码稍微修改一下, 我们先添加了一个layer,到控制器的view上, 然后呢,这两句话不…

【安装笔记-20240524-Windows-安装测试 7-Zip】

安装笔记-系列文章目录 安装笔记-20240524-Windows-安装测试 7-Zip 文章目录 安装笔记-系列文章目录安装笔记-20240524-Windows-安装测试 7-Zip 前言一、软件介绍名称&#xff1a;7-Zip主页官方介绍7-Zip 主要特征 二、安装步骤测试版本&#xff1a;24.05 (2024-05-14) for Wi…

保安维稳,四信以科技构筑高速公路安全智慧防线

近日&#xff0c;广东梅大高速发生严重塌方事故&#xff0c;造成了严重的人员伤亡和财产损失。这一事件在公众心中敲响了安全的警钟&#xff0c;再次引起了公众对于交通设施运营安全性的重点关注。 国务院安委会办公室和国家防灾减灾救灾委员会办公室等主管机构先后印发紧急通知…

CentOS7 部署单机版 elasticsearch

一、环境准备 1、准备一台系统为CentOS7的服务器 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) 2、创建新用户&#xff0c;用于elasticsearch服务 # elastic不允许使用root账号启动服务 [rootlocalhost ~]# useradd elastic [rootlo…

58同城如何降低 80%的机器成本 | OceanBase案例

本文作者&#xff1a;58同城架构师刘春雷 一、背景介绍 58同城作为中国互联网生活服务领域的领军者&#xff0c;其平台规模居国内之首&#xff0c;涵盖了包括车辆交易、房产服务、人才招聘、本地生活服务以及金融等多元化的业务场景。 因其业务的广泛性和多样性&#xff0c;我…

自主创新助力科技强军,麒麟信安闪耀第九届军博会

由中国指挥与控制学会主办的中国指挥控制大会暨第九届北京军博会于5月17日-19日在北京国家会议中心盛大开展&#xff0c;政府、军队、武警、公安、交通、人防、航天、航空、兵器、船舶、电科集团等从事国防军工技术与产业领域的30000多名代表到场参加。 麒麟信安作为国产化方案…

【okhttp】小问题记录合集

can’t create native thread 问题描述 OkHttpClient 每次使用都new创建&#xff0c;造成OOM&#xff0c;提示can’t create native thread… 问题分析 没有将OkHttpClient单例化. 每个client对象都有自己的线程池和连接池&#xff0c;如果为每个请求都创建一个client对象&a…

Java设计模式 _行为型模式_中介者模式

一、中介者模式 1、中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型模式。主要通过一个中介类&#xff0c;该类通常处理不同类之间的通信&#xff0c;并支持松耦合&#xff0c;使代码易于维护。 2、实现思路 &#xff08;1&#xff09;、定义实体…

入门级指纹密码智能锁方案简析以及适用芯片SSD210介绍

上篇我们大概讲了一下门锁的发展历史&#xff0c;近几年家用智能门锁行业中近几年的市场增长变化&#xff0c;举例说明了智能猫眼门锁在类市场份额最大的产品的一些技术参数以及芯片功能框架。 智能猫眼锁核心解决方案以及适用的芯片推荐简介https://blog.csdn.net/Chipsupply…

基于Pytorch的卷积神经网络MNIST手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 手写数字识别是计算机视觉和模式识别领域的一个经典问题。MNIST数据集是一个包含大量手写数字图片的…

军工单位如何做到安全跨网文件交换与导出的

在现代信息化战争中&#xff0c;军工单位在信息安全方面的需求尤为突出。跨网文件交换与导出作为军工单位日常运营的重要环节&#xff0c;面临着网络带宽限制、数据安全风险、合规性要求和传输稳定性等挑战。下面&#xff0c;我们将从以下几个方面探讨军工单位如何实现安全、高…

【UE5.1 多线程 异步】“Async Blueprints Extension”插件使用记录

目录 一、异步生成Actor示例 二、异步计算示例 参考视频 首先需要在商城中下载“Async Blueprints Extension”插件 一、异步生成Actor示例 2. 创建一个线程类&#xff0c;这里要指定父类为“LongAsyncTask”、“InfiniteAsyncTask”、“ShortAsyncTask”中的一个 在线程类…

成品短视频APP源码搭建

在数字化时代&#xff0c;短视频已成为全球范围内的流行趋势&#xff0c;吸引了大量的用户和内容创作者。对于有志于进入短视频领域的企业和个人来说&#xff0c;成品短视频APP源码搭建提供了一条快速、高效的路径。本文将探讨成品短视频APP源码搭建的过程及其优势&#xff0c;…

sheng的学习笔记-docker部署Greenplum

目录 docker安装gp数据库 mac版本 搭建gp数据库 连接数据库 windows版本 搭建gp数据库 连接数据库 docker安装gp数据库 mac版本 搭建gp数据库 打开终端&#xff0c;输入代码&#xff0c;查看版本 ocker search greenplum docker pull projectairws/greenplum docker…

uni-starter创建App项目最全流程(日后还有其他功能会不断更新)

一、创建项目 在HbuilderX中点击创建项目&#xff0c;选择uni-starter模板&#xff0c;选择阿里云、Vue3&#xff0c;填写项目名称后点击创建。如果没有下载过uni-starter会自动下载该插件&#xff0c;如下图&#xff1a; 二、 创建云服务器并关联项目 如果是第一次使用&#…

Linux中gcc/g++的基本使用

目录 gcc/g的使用gcc/g是如何生成可执行文件的预处理编译汇编链接 库.o文件是如何与库链接的&#xff1f; debug版本和release版本 gcc/g的使用 在windows中&#xff0c;我们在VS中编写好了代码之后就可以直接在VS中对源码进行编译等操作后运行 而在Linux下&#xff0c;我们可…

C++_vector操作使用

文章目录 &#x1f680;1.1 vector介绍&#x1f680;1.2 vector的初始化&#x1f680;1.3 vector的常用内置函数&#x1f680;1.4 vector的遍历 &#x1f680;1.1 vector介绍 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元…

领域知识 | 智能驾驶安全领域部分常见概论

Hi&#xff0c;早。 最近想买个新能源车&#xff0c;这个车吧相比于之前的内燃车&#xff0c;新能源车与外界的交互多了很多。比如娱乐的第三方应用&#xff0c;OTA升级等应用。 交互带来的便利越多&#xff0c;暴露的风险自然也就越大&#xff0c;相比于手机等消费者终端设备…

tomcat三级指导

版本 ./catalina.sh linux version.bat win 1.确认是否使用了tomcat管理后台 我们先找到配置文件&#xff1a;tomcat主目录下/conf/server.xml 可以查看到连接端口&#xff0c;默认为8080 然后查看manager-gui管理页面配置文件&#xff0c;是否设置了用户登录 配置文件…