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

news2025/1/15 22:55:45

简单条件转移指令

        根据单个标志位的值(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​​​​​​​

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

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

相关文章

【Andoird开发】android获取蓝牙权限,搜索蓝牙设备MAC

<!-- Android 12以下才需要定位权限&#xff0c; Android 9以下官方建议申请ACCESS_COARSE_LOCATION --><uses-permission android:name"android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name"android.permission.ACCES…

参考文献交叉引用两个文献,逗号隔开

1.引用两个参考文献&#xff0c;定位到word正文中需要引用的位置&#xff0c;然后插入-交叉引用&#xff0c;引好文献 2.选中两个参考文献&#xff0c;切换域代码&#xff0c;然后进行修改&#xff1a; 改为 上面的两张图片中的点是空格的含义&#xff0c;word中按ctrlshift8就…

【计算机网络实验】TCP协议的抓包分析:三次握手四次挥手UDP和TCP的区别(超详细教程)

计算机网络实验——TCP协议抓包分析 文章目录 计算机网络实验——TCP协议抓包分析一、基础知识点1、运输层两个重要协议的特点对比&#xff08;TCP和UDP&#xff09;2、TCP报文的格式3、常见的TCP报文标识字段&#xff08;FLAG字段&#xff09;4、TCP连接的建立过程及理解——三…

CTFshow之文件上传web入门151关-161关解密。包教包会!!!!

这段时间一直在搞文件上传相关的知识&#xff0c;正好把ctf的题目做做写写给自字做个总结&#xff01; 不过有一个确定就是所有的测试全部是黑盒测试&#xff0c;无法从代码层面和大家解释&#xff0c;我找个时间把upload-labs靶场做一做给大家讲讲白盒的代码审计 一、实验准…

多台Centos快速区分,让Centos开机自动显示它的IP地址!

背景说明&#xff1a;当公司拥有多台Centos服务器&#xff0c;管理员很容易弄混淆导致不好区分&#xff0c;在这样的情况下我们可以写个简单脚本来实现开机自动显示它的IP地址&#xff0c;从而达到区分开来的结果&#xff01; 首先我们来开下效果&#xff0c;登录之前的 下面是…

调试时JSON库一直提示 PDB找不到 使用需要对象文件来进行调试的 /DEBUG:Fastlink生成的

最近调试时一直提示上面的提示框&#xff0c;很是烦躁。 为什么会出现这个错误呢&#xff0c;我一直使用的是/DEBUG。出现原因没有找出来&#xff0c;理论上市使用了/DEBUG:Fastlink这个模式才会出&#xff0c;但是就是一直在报这个错误。 /DEBUG&#xff08;生成调试信息&am…

Linux进程的地址空间

Linux进程的地址空间 1. 前言 在编写程序语言的代码时&#xff0c;打印输出一个变量的地址时&#xff0c;这个地址在内存中是以什么形式存在的&#xff1f;一个地址可以存储两个不同的值吗&#xff1f; 运行以下代码&#xff1a; #include <stdio.h> #include <un…

云和恩墨海外首秀在吉隆坡召开的2024中国智能科技与文化展览会

作为中马建交50周年官方重点推荐的活动之一&#xff0c;2024中国智能科技与文化展览会&#xff08;第四届&#xff09;于5月20至21日在毗邻吉隆坡双子塔的吉隆坡国际会展中心举办。本次展览会获得马来西亚科学技术创新部、马来西亚通讯部、中国驻马来西亚大使馆和马来西亚中华总…

向郭老师学习研发项目管理

学习研发项目管理思路 通过以下思路来学习研发项目管理&#xff1a; 1、研发项目管理分3级 2、研发项目管理分4类 3、研发项目管理分5大过程组 4、新产品开发项目生命周期分6个阶段 5、研发项目管理分10大知识体系 项目组合、项目集、简单项目3级管理 针对Portfolio组合…

融合基因组序列识别scATAC-seq的细胞类型

利用scATAC-seq技术进行单细胞分析&#xff0c;可以在单细胞分辨率下深入了解基因调控和表观遗传异质性&#xff0c;但由于数据的高维性和极端稀疏性&#xff0c;scATAC-seq的细胞注释仍然具有挑战性。现有的细胞注释方法大多集中在细胞峰矩阵上&#xff0c;没有充分利用潜在的…

列表的创建和删除

目录 使用赋值运算符直接创建列表 创建空列表 创建数值列表 删除列表 自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501\ 对于歌曲列表大家一定很熟悉&#xff0c;在列表中记录着要播放的歌曲名称…

精品UI响应式视频教程知识付费系统源码在线教育网络课程在线点播可二开分销分站功能

这是一款知识付费平台模板&#xff0c;后台可上传本地视频&#xff0c;批量上传视频连接&#xff0c; 视频后台可设计权限观看&#xff0c;免费试看时间时长&#xff0c;会员等级观看&#xff0c;付费观看等功能&#xff0c; 也带软件app权限下载&#xff0c;帮助知识教育和软件…

数据开放最全sql面试合集(leetcode)

关注公众号“大数据领航员"领取PDF版本和大数据面经 https://leetcode-cn.com/problemset/database/ 题目都是leetcode 上了可以点击题目会有相应的链接 由于个人比较喜欢用开窗函数&#xff0c;所以都优先用了开窗 &#xff0c;当然这些并不一定都是最优解&#xff0c…

【C++】多态(多态的原理)

在本篇博客中&#xff0c;作者将会带领你深入理解C中的多态。 声明&#xff01;&#xff01;&#xff01;本代码以及讲解都是在32位机器下进行完成的&#xff0c;64位机器下会有所不同&#xff0c;但大同小异。 一.多态的概念 什么是多态&#xff1f; 多态就是不同的对象去做…

patroni 部分源码阅读

问题1 /usr/local/lib/python3.9/site-packages/patroni/postgresql/init.py 964 contextmanager 965 def get_replication_connection_cursor(self, hostNone, port5432, **kwargs): 966 conn_kwargs self.config.replication.copy() 967 conn_kwar…

【Kubernetes】kubectl详解

陈述式资源管理方法&#xff1a; 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为 apiserver 能识别的…

JavaWeb基础(HTML,CSS,JS)

这些知识用了三四天左右学完&#xff0c;因为是JavaWeb&#xff0c;并不是前端&#xff0c;所以只是够用&#xff0c;不是深入&#xff0c;但是这确实是学校一个学期交的东西&#xff08;JavaWeb课程&#xff09;。 总结一下网页分为三部分&#xff1a;HTML(内容结构),CSS&…

HTML | 在IDEA中配置Tomcat时遇到的一些问题的解决办法

目录 IDEA中没有web文件夹目录 Tomcat在哪里配置服务器 IDEA中没有web文件夹目录 首先说在IDEA中没有web这个文件夹的解决办法 在菜单栏中帮助中点击查找操作搜索添加框架支持&#xff08;因为我的IDEA会出现无法点击这个操作&#xff0c;所以我对该操作添加了快捷键&#xf…

linux系统内存持续飙高的排查方法

目录 前言&#xff1a; 1、查看系统内存的占用情况 2、找出占用内存高的进程 3、解决方法 4、补充&#xff1a;如果物理内存使用完了&#xff0c;会发生的情况 前言&#xff1a; 如果一台服务器内存使用率持续处于一个高峰值&#xff0c;服务器可能会出现响应慢问题。例如s…

03:PostgreSQL逻辑结构(表空间、数据库、模式、表、索引)

环境规划&#xff1a; 操作系统&#xff1a;CentOS 7.9 64bitPostgreSQL 版本&#xff1a;16.x 或 15.x安装用户&#xff1a;postgres软件安装目标路径&#xff1a;/usr/pgsql-<version>数据库数据目录&#xff1a;/pgdata 目录 表空间Tablespace 默认表空间 手动创建…