计算机系统基础 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;elseresult = 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.mzph.cn/diannao/13892.shtml

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

相关文章

深度学习500问——Chapter09:图像分割(4)

文章目录 9.10 Mask-RCNN 9.10.1 Mask-RCNN 的网络结构示意图 9.10.2 RCNN行人检测框架 9.10.3 Mask-RCNN 技术要点 9.11 CNN在基于弱监督学习的图像分割中的应用 9.11.1 Scribble 标记 9.11.2 图像级别标记 9.11.3 DeepLabbounding boximage-level labels 9.11.4 统一的框架 9…

作为 App 开发者会推荐安装的 Mac App

Xcode&#xff0c;作为 App 开发者&#xff0c;必须安装的工具。当然&#xff0c;有经验的开发者不会从 Mac App Store 下载&#xff0c;而是从网站下载&#xff0c;除了安装过程更可控&#xff0c;也方便多版本共存。此外&#xff0c;我不信任任何第三方下载方式&#xff1a; …

表面简单实则暗藏玄机的面试题:Java数组适合做队列吗?

Java数组本身是一种线性数据结构&#xff0c;它可以用来存储一系列固定大小的元素。尽管数组可以用于实现队列的一些基本操作&#xff0c;比如入队&#xff08;enqueue&#xff09;和出队&#xff08;dequeue&#xff09;&#xff0c;但由于其固定的大小&#xff0c;它并不适合…

开关电源重点可靠性测试项目与测试方法

为确保开关电源在复杂工作环境下的安全性与稳定性&#xff0c;各种安全性测试成为不可或缺的环节。本文将深入探讨几项关键的安全性测试项目&#xff0c;帮助用户全面了解如何评估开关电源的可靠性和安全性。 一、过压保护测试方法 目的是为了检测当输出电压过高时&#xff0c;…

Unity限制鼠标光标位置

限制鼠标光标位置 private void Awake() {Cursor.lockState CursorLockMode.Confined;//Cursor.visible false;隐藏鼠标光标 }●Confined&#xff1a;限制光标到游戏窗口。 ●Locked&#xff1a;锁定光标到游戏窗口的中心并隐藏。 ●None&#xff1a;不被修改。

项目9-网页聊天室2(登录)

0.前端知识储备 Ajax请求中的async:false/true的作用 - front-gl - 博客园 (cnblogs.com) 01.前端页面展示 02.后端代码 2.1 CONTROLLER RequestMapping("/login")public Result login(String username, String password, HttpSession httpSession){User user …

乡村振兴与农村社会治理现代化:加强农村社会治理体系和治理能力现代化建设,提升乡村治理效能,为美丽乡村建设提供坚实保障

一、引言 在全面推进乡村振兴的伟大实践中&#xff0c;农村社会治理现代化是不可或缺的重要一环。随着时代的发展&#xff0c;传统的农村社会治理方式已经无法满足现代社会发展的需求。因此&#xff0c;加强农村社会治理体系和治理能力现代化建设&#xff0c;提升乡村治理效能…

2024年电工杯数学建模竞赛思路资料汇总贴

下文包含&#xff1a;2024电工杯&#xff08;电工杯数学建模竞赛&#xff09;思路解析、电工杯参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛 C君将会第一时间发布选题建议、所有题目的思路解析、相关代码、参考文献、参考论文等多项资料&#xff0c;帮助大家…

深度学习(文章链接汇总)

神经网络与深度学习-简要入门 动手学深度学习-pytorch版本&#xff08;一&#xff09;&#xff1a;引言 & 预备知识 动手学深度学习-pytorch版本&#xff08;二&#xff09;&#xff1a;线性神经网络 YOLOv8 学习与环境配置

XSS漏洞

漏洞描述 XSS全名叫Cross Site Scripting(跨站脚本攻击)因为简写和css同名所以改名为XSS&#xff0c;该漏洞主要利用javascript可以控制html&#xff0c;css&#xff0c;浏览器的行为从而恶意利用&#xff0c;当开发人员未对输入的内容进行过滤或编码时&#xff0c;恶意用户在…

苍穹外卖①

1.BeanUtils.copyProperties(orders,orderVO); BeanUtils.copyProperties 是 Java 中 Apache Commons BeanUtils 库的一个方法&#xff0c;它用于将一个 Java Bean 的属性复制到另一个 Java Bean。这个方法非常适合于对象之间的属性复制&#xff0c;尤其是当源对象和目标对象的…

云服务器上部署Kubernetes集群(K8S)

master节点&#xff1a;master node节点&#xff1a;node1 由于是ubuntu系统&#xff0c;参考两个博客配置 安装vmware搭建k8s集群&#xff08;亲试无坑&#xff09;-CSDN博客 该博客是centos系统&#xff0c;所以稍微有点区别结合另一篇博客一起参考 kubernetes集群…

scrapy进阶(豆瓣新书速递)(比亚迪)

scrapy数据建模与请求 学习目标&#xff1a; 应用 在scrapy项目中进行建模应用 构造Request对象&#xff0c;并发送请求应用 利用meta参数在不同的解析函数中传递数据scrapy构造post请求 1. 数据建模 通常在做项目的过程中&#xff0c;在items.py中进行数据建模 1.1 为什么建…

gt.qpa.xcb: could not connect to display : 1

报错解释&#xff1a; 这个错误通常发生在使用X11&#xff08;X Window System&#xff09;的Linux环境中&#xff0c;当尝试启动一个基于Qt平台的应用程序时。错误信息表明程序无法连接到X服务器显示设备&#xff0c;原因可能是没有正确设置DISPLAY环境变量&#xff0c;或者用…

【Spring security】【pig】Note03-pig token令牌解析器过程

&#x1f338;&#x1f338; pig token令牌解析器过程 &#x1f338;&#x1f338; pig后端源码 一、解析请求中的令牌值。 二、验证令牌 内省并验证给定的令牌&#xff0c;返回其属性。返回映射表示令牌有效。 /*** author lengleng* date 2019/2/1 扩展用户信息*/ publi…

Hot100-栈

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; class Solution {public boolean isValid(String s) {//用map的键值对匹配左右括号//按照顺序&#xff0c;先匹配的是左括号&#xff0c;所以栈里面放左括号HashMap<Character, Character> rlationship new Has…

deepinlinuxv23b3用lazarus3.2开发生成2维码

下载&#xff1a; https://sourceforge.net/projects/lazarus/files/ 最新版3.2.2的fpc,3.2的lazarus sourceforge默认下载慢&#xff0c;选择auto-select能够选择近的镜像站点&#xff0c;还不行的话也能够motrix下载会自动更换域名 linux的qrencode安装是 sudo apt…

跨境小白shopee被封号的原因?如何有效预防?

提到跨境电商平台&#xff0c;大家都知道亚马逊、Temu、TikTok shop这些是比较大的电商平台。但最近几年&#xff0c;在东南亚市场上&#xff0c;Shopee虾皮却是颇负盛名的一个跨境电商平台&#xff0c;这也让众多中国跨境小白蜂拥而至。目前shopee的商家正在不断增多&#xff…

[力扣题解] 130. 被围绕的区域

题目&#xff1a;130. 被围绕的区域 思路 代码 Method 1 : 深度优先搜索&#xff0c;自己写的 class Solution { private:int dir[4][2] {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};void dfs(vector<vector<char>>& board, vector<vector<bool>>&am…

vue3第三十四节(TS 之 interface 与 type 的异同)

1、interface 接口只能定义描述对象类型 如&#xff1a; interface PersonIn {name: string;age:number;job:string; }// 定义函数 interface FPerson {(a: number, b:string) > void }2、类型别名 type则可以定义多种类型 如&#xff1a; type userName string type…