计算机系统基础 7 分支程序的实现

简单条件转移指令

        根据单个标志位的值(CF, SF,OF,PF,ZF)来确定是否转移, 如果条件成立,则(EIP) + 位移量 ➡ EIP,否则什么也不做。

        注意,这里的EIP在执行本条指令时就已经变成当前指令的下一条指令的地址了,如下例, 0096827D是jnz l1的下一条指令地址,加上机器码75 07中表示偏移量的07就是l1所在处00968284

   mov  eax, x
00968270   A1 11 90 9D 00       mov   eax,dword ptr [x (09D9011h)]  
   cmp  eax, y
00968275  3B 05 15 90 9D 00    cmp  eax,dword ptr [y (09D9015h)]  
   jnz  l1
0096827B  75 07                       jne   l1 (0968284h)  
   mov  ecx,1
0096827D   B9 01 00 00 00        mov    ecx,1  
   jmp  l2
00968282   EB 05                      jmp    l1+5h (0968289h)  
l1: mov  ecx,0
00968284  B9 00 00 00 00          mov         ecx,0  
l2:
00968289   ……

JZ / JE       ZF=1时,转移

JNZ / JNE     ZF=0时,转移

JS            SF=1时,转移

JNS           SF=0时,转移

JO            OF=1时,转移

JNO           OF=0时,转移

JC            CF=1时,转移

JNC           CF=0时,转移

JP / JPE      PF=1时,转移

JNP / JPO     PF=0时,转移

无符号条件转移指令  

JA / JNBE   标号   ( CF=0 且 ZF=0,转移)

JAE / JNB   标号   ( CF=0 或 ZF=1,转移)

JB / JNAE   标号   ( CF=1 且 ZF=0,转移)

JBE / JNA   标号   ( CF=1 或 ZF=1,转移)

有符号条件转移指令 

JG / JNLE   标号:当 SF=OF 且 ZF=0时,转移

JGE / JNL   标号:当 SF=OF 或者 ZF=1时,转移

JL / JNGE   标号:当 SF≠OF 且 ZF=0时,转移

JLE / JNG   标号:当 SF≠OF 或者 ZF=1时,转移

 两种JMP格式

        间接转移方式中,除了立即数寻址方式外,其它方式均可以使用。

 功能等价的转移指令:

1. JMP L1

2. JMP BUF

3. LEA EBX,BUF

    JMP DWORD PTR [EBX]

4. MOV EBX,BUF

    JMP EBX

指令地址列表 

         如果要根据不同的输入跳转执行不同的程序片段,如果要JMP来写会非常麻烦。采用的方法是构造指令地址列表

        比如,

        FUNCTAB  DD  LP1, LP2, LP3

        JMP  FUNCTAB[EBX*4]

        (EBX)=0;跳转到 LP1

        (EBX)=1;跳转到 LP2

         又如,

void arraysubtract_colsfirst( )  {……}

void arraysubtract_rowsfirst( )  {……}

void arraysubtract_onedim ( )  {……}

int main()

{

    int   i;

    void (*funcp[3])() = { arraysubtract_colsfirst ,

                                    arraysubtract_rowsfirst,

                                    arraysubtract_onedim };

    funcp[i]();   // i=0,1,2 会执行不同的函数

    …….

}

这样也做到了从多分支到无分支的转化,比如下面例子

6.3.1 多分支向无分支的转化

例:当x==1时,显示‘HelloOne’

    x==2时,显示‘Two’

    x==3时,显示‘Welcome,Three’,……,

    x为不同的值,显示不同的串。

void myprint()
{   int  x;
    char msg1[] = "Hello,One";
    char msg2[] = "Two";
    char msg3[] = "Welcome, Three";
    char *p[3] = { msg1,msg2,msg3 };
    printf("please input 0,1,2 \n");
    scanf("%d", &x);
    printf("%s\n", p[x]);
}

编译优化上的利用

编译层面上可以利用这种转化实现优化:

比如对下面这个子函数的优化:

​​​​​​​int absdiff(int x, int y)

{

    int result;

    if (x < y)

        result = y - x;

    else

        result = x - y;

    return result;

}

无分支的写法:

int absdiff(int x, int y)

; _x$ = ecx

; _y$ = edx

push  esi

mov   esi, ecx

mov   eax, edx

sub   esi, edx

sub   eax, ecx

cmp   ecx, edx

cmovge eax, esi

pop   esi

ret   0

这样,先分别计算出x - y 和 y - x, 然后通过cmp、cmovge来实现选择。

Switch语句 

         Switch语句就是采用这种方式,如下例

        

#include <stdio.h>
int main(int argc, char* argv[])
{	int  x = 3, y = -1,  z;
	char c;
	c = getch();
	switch (c) {
	case '+':
	case 'a': // 用 字符’a’来表示‘+’
		z = x + y;
		break;
	case '-':
	case 's': // 用 字符’s’来表示‘-’
		z = x - y;
		break;
	default: z = 0;
	}
	printf(" %d %c %d = %d \n", x,c,y,z);
	return 0;
}

可以看出,是通过几种选择的值与其中最小值的差作为偏移量从内存中取数,取出的数作为在一个数组取数的下标,取出的数就是跳转到的地址,实际上就是用指令地址列表来实现的。

与转移指令功能类似的指令 

        带条件的数据传输指令

                上一篇详细写过。

语句格式:cmov***  r32,r32/m32

功    能:在条件“***”成立时,

          传送数据,即(r32/m32)→r32。

          cmov 是Conditional MOVe的缩写。

要    求:

   ① r32 表示一个32位的寄存器;

   ② m32位表示一个内存地址;

      m32对应直接、间接、变址、基址加变址寻址;

      m32对应的单元的数据类型是双字,即32位。

        字节指令 

语句格式:set***  opd

功    能:在条件“***”成立时,(opd)⬅ 1,否则 (opd)⬅ 0 。

      opd 一般为 一个字节寄存器

如:

    cmp   eax,  ebx

    setg  cl

    seta  cl

    sete  cl

使用单个标志位 设置

sete/setzsetcsetssetosetp

条件:ZF=1     CF=1    SF=1   OF=1  PF=1 

setne/setnzsetncsetnssetnosetnp

条件:ZF=0     CF=0      SF=0    OF=0   PF=0

使用多个标志位组合设置

setasetbsetgsetl

setaesetbesetgesetle​​​​​​​

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

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

相关文章

c# 将数据库连接字符串写到配置文件中,及获取

考虑到代码的安全性&#xff0c;已经修改起来的方便性&#xff0c;我们常常不会将数据库连接字符串直接放在代码中&#xff0c;而是将这个字符串放到一个App.config配置文件中&#xff0c;赋值给一个变量&#xff0c;然后再在代码中引用这个变量。 具体做法如下: ①展开项目名称…

微星笔记本618爆款推荐清单,好评有礼活动火热进行中

微星笔记本618爆款推荐清单&#xff0c;好评有礼活动火热进行中 又是一年一度的618大促&#xff0c;作为电子数码产品的主场&#xff0c;准备选购笔记本的消费者早已翘首以盼有更实惠的价格~ 不负期待&#xff0c;微星笔记本携多款性价比爆款笔记本、Claw掌上游戏机&#xff0…

Google Find My Device:科技守护,安心无忧

在数字化的时代&#xff0c;我们的生活与各种智能设备紧密相连。而 Google Find My Device 便是一款为我们提供安心保障的实用工具。 一、Find My Decice Netword的定义 谷歌的Find My Device Netword旨在通过利用Android设备的众包网络的力量&#xff0c;帮助用户安全的定位所…

记录一个更新adobe软件导致加载PDF文件异常的问题

最近由于项目需要,没有办法把原有的adobe正版软件进行了卸载,换了个盗版软件,结果导致我的pdf文件加载的时候出现异常。 报错的语句是这个 string str = System.Environment.CurrentDirectory; // string fileName = MyOpenFileDialog(); axAcroPDF1.LoadFile(…

abs(-2147483648) == 2147483648?

从数学意义上&#xff0c;这是对的。但是&#xff0c;就怕但是。 #include int main() {long long v;v abs(-2147483648);printf("%lld\n", v);return 0; } 输出: -2147483648 我们从source code中一一解开. /* Return the absolute value of I. */ int abs (…

uniapp星空效果

uniapp星空效果 背景实现思路代码实现尾巴 背景 之前在网上看到过一个视频&#xff0c;使用纯css实现过一个星空效果。具体出处找不到了&#xff0c;我们按照他那个思路来实现一个类似的效果&#xff0c;还是先上一张图镇楼&#xff1a; 实现思路 首先我们这个效果使用的是…

Php composer 基础教程

一、什么是Composer&#xff1f; Composer 是 PHP 中的依赖管理工具。它允许声明项目所依赖的库&#xff0c;并且它将为您管理&#xff08;安装/更新&#xff09;它们。 二、如何安装&#xff1f; Linux 系统和 MacOS 系统 直接下载最新稳定版&#xff1a; 然后执行下列命令&…

去中心化的 S3,CESS 首创去中心化对象存储 DeOSS

Web3 在各个领域的应用和发展已成为讨论的焦点&#xff0c;尽管行业对 Web3 的定义各不相同&#xff0c;但一个普遍的共识是 Web3 赋予了用户对其数据的所有权和自主权。这一转变在我们的生活和工作与数字化越来越深入地融合之际至关重要&#xff0c;这意味着所有人类活动很快将…

【Linux】Centos7安装JDK

【Linux】Centos7安装JDK 下载 Oracle 官网下载 JDK17 https://www.oracle.com/cn/java/technologies/downloads/#java17 安装 使用rz命令上传 jdk tar 包&#xff0c;上传失败直接用 xftp 上传 在安装图形界面时&#xff0c;有勾选开发工具&#xff0c;会自动安装 JDK 需要先…

D435相机内参标定(无法直接应用在相机上)

打开roscore和相机 输入 rostopic echo /camera/color/camera_info 从而得到相机的内参 cameraInfo包含D、K、R、P四个矩阵。 矩阵D是失真系数&#xff0c;包括(k1, k2, t1, t2, k3) 矩阵K是相机内参&#xff0c;即 矩阵R是一个3✖3的旋转矩阵&#xff0c;仅对双目相机有效&…

每日5题Day9 - LeetCode 41 - 45

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;41. 缺失的第一个正数 - 力扣&#xff08;LeetCode&#xff09; 今天这道题没有ac&#xff0c;写不动了&#xff0c;下次再通过吧&#xff0c;先给个半成品下次回…

微信小程序画布显示图片绘制矩形选区

wxml <view class"page-body"><!-- 画布 --><view class"page-body-wrapper"><canvas canvas-id"myCanvas" type"2d" id"myCanvas" classmyCanvas bindtouchstart"touchStart" bindtouchmo…

HackTheBox-Machines--Bank

文章目录 0x01 信息收集0x02 文件上传漏洞利用0x03 权限提升方法一&#xff1a;SUID提权方法二&#xff1a;配置不当提权 Bank 测试过程 0x01 信息收集 1.端口扫描 发现 ssh(22)、DNS(53)、HTTP(80) 端口 nmap -sC -sV 10.129.29.200访问 80 端口&#xff0c;页面为Apache2 U…

数据挖掘与机器学习——机器学习概述

一、什么是机器学习 机器学习的英文名称叫Machine Learning&#xff0c;简称ML&#xff0c;该领域主要研究的是如何使计算机能够模拟人类的学习行为从而获得新的知识。 机器学习与数据挖掘的联系&#xff1a;简单来说&#xff0c;机器学习就是让计算机从大量 的数据中学习到相关…

软管的高速非接触外径测量方案!单双轴测径仪多种类型!

一、传统测量方式的局限 在软管外径的测量领域&#xff0c;传统方式往往面临多重挑战&#xff1a; 1、挤压变形&#xff1a;传统的测量方式可能导致软管因挤压而变形&#xff0c;进而影响测量数据的准确性。 2、人为误差&#xff1a;测量结果常因人为因素而有所差异&#xff0c…

Embase生物医学文摘数据库文献全文去哪里查找下载

Embase是生物医学与药理学文摘数据库&#xff0c;是爱思唯尔&#xff08;Elsevier&#xff09;推出的针对生物医学和药理学领域信息所提供的基于网络的数据检索服务。它将1974年以来的生物医学记录与 900 多万条独特的Medline&#xff08;1950 年以来&#xff09;的记录相结合&…

智慧社区管理系统:打造便捷、安全、和谐的新型社区生态

项目背景 在信息化、智能化浪潮席卷全球的今天&#xff0c;人们对于生活品质的需求日益提升&#xff0c;期待居住环境能与科技深度融合&#xff0c;实现高效、舒适、安全的生活体验。在此背景下&#xff0c;智慧社区管理系统应运而生&#xff0c;旨在借助现代信息技术手段&…

go ast语义分析实现指标计算器

什么是AST 首先我们要知道AST是什么&#xff08;Abstract Syntax Tree&#xff0c;AST&#xff09;&#xff0c;简称为语法树&#xff0c;是go语言源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构&#xff0c;树上的每个节点都表示源代码中的一种结构。 …

docker -JDK8安装

文章目录 前言docker -JDK8安装1. 新建一个 Docker 容器2. 在容器中安装和配置 JDK 8 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实…

Python-温故知新

1快速打开.ipynb文件 安装好anaconda后&#xff0c;在需要打开notebook的文件夹中&#xff0c; shift键右键——打开powershell窗口——输入jupyter notebook 即可在该文件夹中打开notebook的页面&#xff1a; 2 快速查看函数用法 光标放在函数上——shift键tab 3...