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

概要

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

分支指令实现

        倒计数

       ……

       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寄存器、成组运算等,减少指令

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

U-Boot menu菜单分析

文章目录 前言目标环境背景U-Boot如何自动调起菜单U-Boot添加自定义命令实践 前言 在某个厂家的开发板中&#xff0c;在进入它的U-Boot后&#xff0c;会自动弹出一个菜单页面&#xff0c;输入对应的选项就会执行对应的功能。如SD卡镜像更新、显示设置等&#xff1a; 目标 本…

ESP8266实现获取天气情况

利用太极创客提供的ESP8266 心知天气库获取天气情况并显示 心知天气库地址&#xff1a; ESP8266-心知天气: 本库主要功能为使用ESP8266物联网开发板通过心知天气 API 获取天气等信息。 clone到本地: git clone https://gitee.com/taijichuangke/ESP8266-Seniverse.git 安装该…

go语言的一些常见踩坑问题

开始之前&#xff0c;介绍一下​最近很火的开源技术&#xff0c;低代码。 作为一种软件开发技术逐渐进入了人们的视角里&#xff0c;它利用自身独特的优势占领市场一角——让使用者可以通过可视化的方式&#xff0c;以更少的编码&#xff0c;更快速地构建和交付应用软件&#…

ArkUI-X开发指南:【SDK配置和构建说明】

ArkUI-X SDK配置和构建说明 ArkUI-X SDK是ArkUI-X开源项目的编译产物&#xff0c;可将ArkUI-X SDK集成到现有Android和iOS应用工程中&#xff0c;使开发者基于一套ArkTS主代码&#xff0c;就可以构建支持多平台的精美、高性能应用。SDK内容包含ArkUI跨平台运行时&#xff0c;组…

【高频】从输入URL到页面展示到底发生了什么?

一、相关衍生面试问题&#xff1a; 浏览器输入美团网站&#xff0c;从回车到浏览器展示经历了哪些过程 &#xff1f; http输入网页之后的流程&#xff1f; 百度搜索页面&#xff0c;从点开搜索框&#xff0c;到显示搜索页面经历了什么&#xff1f; 二、探究各个过程&#x…

[Algorithm][回溯][记忆化搜索][最长递增子序列][猜数字大小Ⅱ][矩阵中的最长递增路径]详细讲解

目录 1.最长递增子序列1.题目链接2.算法原理详解3.代码实现 2.猜数字大小 II1.题目链接2.算法原理详解3.代码实现 3.矩阵中的最长递增路径1.题目链接2.算法原理详解3.代码实现 1.最长递增子序列 1.题目链接 最长递增子序列 2.算法原理详解 题目解析&#xff1a;从每个位置&am…

【BUG】Edge|联想电脑 Bing 搜索报错“Ref A: 乱码、 Ref B:乱码、Ref C: 日期” 的解决办法

文章目录 省流版前言解决办法 详细解释版前言问题描述与排查过程解决办法与总结 省流版 我原以为我解决了&#xff0c;才发的博客&#xff0c;晚上用了一下其他设备发现还是会出现这个问题… 这篇博客并未解决该问题&#xff0c;如果评论里有人解决了这个问题不胜感激&#x…

博客说明 5/12~5/24【个人】

博客说明 5/12~5/24【个人】 前言版权博客说明 5/12~5/24【个人】对比最后 前言 2024-5-24 13:39:23 对我在2024年5月12日到5月24日发布的博客做一下简要的说明 以下内容源自《【个人】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作…

Undet for SketchUp 2023.3 点云建模软件 支持支持草图大师sketchup2021-2022-2023

1.Undet for sketchup 2023.3支持草图大师sketchup2021-2022-2023。支持机载雷达扫描、车载扫描还是地面扫描&#xff0c;对AEC行业用户来说&#xff0c;真正需要的是如何将这些数据快速处理为三维模型&#xff0c;这样才能将这些信息延展到BIM领域发挥效用。因此面对这些海量的…

【真实项目中收获的提升】- 前后端联调

场景 小型项目前后端联调&#xff0c;不需要部署到sit或uat环境下。 解决方法 后端部署frp服务 下载frp软件 配置frpc.ini文件&#xff0c;先把文件设置可编辑(可同时配置多个 例如下面的chz 上面打码的是frp服务器地址) 然后起start.bat 其实就是执行frpc -c frpc.ini命令…

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…

DockerNetwork

Docker Network Docker Network 是 Docker 引擎提供的一种功能&#xff0c;用于管理 Docker 容器之间以及容器与外部网络之间的网络通信。它允许用户定义和配置容器的网络环境&#xff0c;以便容器之间可以相互通信&#xff0c;并与外部网络进行连接。 Docker Network 提供了以…

docker容器安装mysql

linux: centOS-7 hadoop: 3.3.6 前置章节&#xff1a; (图文并茂)基于CentOS-7搭建hadoop3.3.6大数据集群-CSDN博客 可选&#xff1a;zookeeper安装教程-CSDN博客 1.安装docker 1.1 添加docker的repo源 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

猫狗电子玩具底层方案开发

物在现代年轻人中的地位已经超越了简单的“宠物”定义&#xff0c;它们已经成为了家庭的一部分&#xff0c;是人们生活中不可或缺的伴侣和朋友。 因此营运而生了很多宠物用品&#xff0c;比如喂食器、电子逗猫棒、饮水机、说话按钮等等宠物电子玩具周边。宠物玩具在宠物生活中…

Python-3.12.0文档解读-内置函数hash()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 功能描述 参数 返回值 特性 使用示例 注意事项 记忆策略 常用场景 …

【数学建模】储药柜的设计

2014高教社杯全国大学生数学建模竞赛D题目 题目描述 储药柜的结构类似于书橱&#xff0c;通常由若干个横向隔板和竖向隔板将储药柜分割成若干个储药槽(如图1所示)。为保证药品分拣的准确率&#xff0c;防止发药错误&#xff0c;一个储药槽内只能摆放同一种药品。药品在储药槽…

SpringBoot实现增量部署

目录&#xff1a; 1、使用背景2、实现流程3、部署增量包到项目中并启动4、说明 1、使用背景 最近发现公司发布版本时候&#xff0c;很齐全&#xff0c;接口文档&#xff0c;部署方式等都很好&#xff0c;其中有个增量部署包&#xff0c;有点兴趣&#xff0c;不清楚怎么生成增量…

vue3+ts+vant4 实现购物车 前端代码

一、功能效果 二、前端代码 购物车的vue代码 <template><van-nav-bar left-text"返回" title"购物车" click-left"onClickLeft"><template #right><van-popover v-model:show"showPopover" placement"bot…

SQLite数据库免改造透明加密解决方案:给数据加把锁

在数字化时代&#xff0c;信息安全和隐私保护显得尤为重要。TDE透明加密技术&#xff0c;是一种在用户无感知的情况下对数据进行加密和解密的技术。它能够在数据生成、存储、传输和使用过程中自动进行加密处理&#xff0c;无需用户手动操作。透明加密技术的核心在于其透明性&am…

登录接口测试

登录接口测试 数据驱动