【汇编】其他转移指令、call指令和ret指令

文章目录

  • 前言
  • 一、其他转义指令
    • 1.1 jcxz指令
      • 怎么使用jcxz
      • 性质
    • 1.2 loop指令
  • 二、call和ret指令
    • 2.1 模块化程序设计
      • 模块化程序设计是什么?
    • 2.2 call和ret
      • call 指令
      • 指令“call far ptr 标号”实现的是段间转移
      • 转移地址在寄存器中的call指令
      • 转移地址在内存中的call指令
      • 返回指令:ret 和 retf
  • 总结


前言

在汇编语言的世界中,转移指令扮演着连接程序执行流程的重要角色。除了之前提到的 JMP 指令外,汇编语言还提供了其他一些转移指令,其中包括 CALL 和 RET 指令。这些指令不仅允许程序跳转到其他位置执行,还支持子程序的调用和返回,为实现模块化、可维护的代码提供了强大的支持。

其他转移指令:

除了 JMP 指令之外,汇编语言还提供了一系列其他转移指令,如 JE(Jump if Equal)、JNE(Jump if Not Equal)、JG(Jump if Greater)、JL(Jump if Less)等。这些指令允许根据特定的条件执行跳转,实现程序中的条件分支,使得程序能够根据不同的情况选择性地执行不同的代码路径。

CALL 指令:

CALL 指令用于调用一个子程序(或称为过程或函数)。它实现了一种跳转到其他代码块执行的机制,但与 JMP 不同,CALL 在执行跳转之前会将当前指令的下一条指令地址入栈,以便在子程序执行完毕后能够返回到调用点。这为程序的模块化和结构化提供了基础,使得代码更易于理解和维护。

RET 指令:

RET 指令与 CALL 相对应,用于从子程序中返回到调用点。它从栈中弹出之前保存的返回地址,将程序的控制流恢复到调用点,实现了子程序的返回操作。RET 的使用使得程序能够方便地从一个子程序切换回到主程序,完成所需的计算和任务。


一、其他转义指令

1.1 jcxz指令

怎么使用jcxz

JCXZ 是汇编语言中的一个指令,它的含义是“Jump if CX is Zero”(如果 CX 寄存器为零则跳转)。让我们来解释一下:

在汇编语言中,CX 是一个通用寄存器,通常用于存储一个计数值。JCXZ 指令检查 CX 寄存器的值,如果它等于零,那么程序会跳转到指定的目标地址执行。如果 CX 不为零,那么程序会继续执行接下来的指令而不跳转。

这个指令通常用于循环控制。假设你有一个循环,CX 寄存器用于计数,当计数器减到零时,你希望退出循环。这时就可以使用 JCXZ 指令来检查 CX 寄存器的值,如果为零就跳出循环。

功能:如果(cx)=0,则转移到标号处执行
当(cx)≠0时,什么也不做(程序向下执行)

当(cx)=0时,(IP)=(IP)+8位位移)
8位位移=“标号”处的地址-jcxz指令后的第一个字节的地址;
8位位移的范围为-128~127,用补码表示;
8位位移由编译程序在编译时算出。

以下是一个简单的伪代码示例:

MOV CX, 5       ; 初始化 CX 寄存器为 5
LoopStart:; 这里放循环的代码DEC CX        ; 每循环一次,减少 CX 的值JCXZ LoopEnd  ; 如果 CX 为零,跳转到 LoopEnd 标签; 这里放循环的代码JMP LoopStart ; 跳转回 LoopStart 标签

LoopEnd:
在这个例子中,JCXZ 指令用于检查 CX 寄存器是否为零,如果是,就跳转到 LoopEnd,结束循环。

性质

jcxz是有条件转移指令
所有的有条件转移指令都是短转移
对IP的修改范围都为-128~127
在对应的机器码中包含转移的位移,而不是目的地址

1.2 loop指令

指令格式:loop 标号
指令操作
(1)(cx)=(cx)-1;
(2)当(cx)≠0时,则转移到标号处执行
当(cx)=0时,程序向下执行
如果(cx)≠0,(IP)=(IP)+8位位移
8位位移=“标号”处的地址-loop指令后的第一个字节的地址
8位位移的范围为-128~127,用补码表示
8位位移由编译程序在编译时算出

二、call和ret指令

2.1 模块化程序设计

模块化程序设计是什么?

模块化程序设计是一种编程方法,它的核心思想是将一个大型的软件系统划分为相互独立、功能清晰的模块或子程序。每个模块都专注于解决特定的问题或执行特定的任务,而且这些模块之间可以相互独立地开发、测试、维护和替换。

用通俗的话来说,就好像在搭积木一样,每个积木块都是一个模块,有自己的形状和功能。你可以将这些积木块组合在一起,构建出一个更大更复杂的结构。同样地,在模块化程序设计中,每个模块就像是一个独立的积木块,可以被单独处理,然后通过定义良好的接口和规则组合在一起,形成一个完整的软件系统。
这种方法有助于提高代码的可读性、可维护性和可重用性。每个模块可以由不同的开发者独立工作,只要它们遵循相同的接口规范,就能够协同工作。当需要修改或更新系统时,只需关注特定的模块而不影响整个程序,这使得程序的开发和维护更加高效。模块化设计也促使了代码重用,因为一个好的模块可以在其他项目中被重复使用,从而减少了开发时间和工作量。

2.2 call和ret

调用子程序:call指令
返回:ret 指令

示例

mov ax, 0
call s
mov ax, 4c00h
int 21h
s: add ax, 1
ret

实质:流程转移指令,它们都
修改IP,或同时修改CS和IP

call 指令

字面意思:调用子程序
实质:流程转移
call指令实现转移的方法和 jmp 指令的原理相似
格式:call 标号
CPU执行call指令,进行两步操作:
(1)将当前的 IP 或 CS和IP 压入栈中;
(2)转移到标号处执行指令。
call 标号
16位位移=“标号”处的地址-call指令后的第一个字节的地址;
16位位移的范围为 -32768~32767,用补码表示;
16位位移由编译程序在编译时算出。

call 标号会指向下面这些:
(1) (sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(2) (IP) = (IP) + 16位位移

相当于:
push IP
jmp near ptr 标号

指令“call far ptr 标号”实现的是段间转移

CPU执行“call far ptr 标号”时的操作
(1) (sp) = (sp) – 2
((ss) ×16+(sp)) = (CS)
(sp) = (sp) – 2
((ss) ×16+(sp)) = (IP)

(2) (CS) = 标号所在的段地址
(IP) = 标号所在的偏移地址
“call far ptr 标号” 相当于

push CS
push IP
jmp far ptr 标号

转移地址在寄存器中的call指令

指令格式:call 16位寄存器
功能:
(sp) = (sp) – 2
((ss)*16+(sp)) = (IP)
(IP) = (16位寄存器)
相当于进行
push IP
jmp 16位寄存器

转移地址在内存中的call指令

call word ptr 内存单元地址
相当于:
push IP
jmp word ptr 内存单元地址

mov sp,10h
mov ax,0123h
mov ds:[0],ax
call word ptr ds:[0]

执行后,(IP)=0123H,(sp)=0EH

call dword ptr 内存单元地址
相当于
push CS
push IP
jmp dword ptr 内存单元地址

mov sp,10h
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
call dword ptr ds:[0]

低地址放偏移地址
高地址放段地址

执行后,(CS)=0,(IP)=0123H,(sp)=0CH

返回指令:ret 和 retf

其实ret和retf返回指令就是返回到call的下一条指令,仅此而已

ret指令
功能 用栈中的数据,修改IP的内容,从而实现近转移;
相当于 pop IP

retf指令
用栈中的数据,修改CS和IP的内容,从而实现远转移;
pop IP
pop CS


总结

在汇编语言中,转移指令是程序控制流程的关键。除了基本的无条件跳转指令 JMP 外,条件跳转指令和子程序调用指令 CALL、RET 构成了汇编语言中转移操作的基础。这些指令的灵活运用使得程序员能够编写出结构清晰、模块化的代码,提高了代码的可读性和可维护性。深入理解和熟练运用这些转移指令,是汇编语言编程中的重要一环。

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

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

相关文章

RESTful API 设计指南——为什么要用(上)

引言 在上一篇中:RESTful API 设计指南——开篇词 我们介绍了几个十分有争议的案例: 所有的接口都使用Post请求不管成功还是失败,HTTP状态码都返回200API命名千奇百怪 本章我们来深入分析一下,为什么不要像案例中所说的那样干…

微信小程序内嵌h5页面,实现动态设置顶部标题的功能

一、需求描述 使用HBuilder X作为开发工具&#xff0c;vue作为开发语言&#xff0c;开发微信小程序。微信小程序页面内嵌h5页面&#xff0c;即<web-view></web-view>标签。通过设置不同url连接地址&#xff0c;设置不同的标题。 二、失败做法 页面A嵌入h5页面&a…

07_面向对象高级_内部类

内部类 1. 认识内部类 它是类中的五大成分之一&#xff08;成员变量、方法、构造器、内部类、代码块&#xff09;如果一个类定义在另一个类的内部&#xff0c;这个类就是内部类。 public class Test {public static void main(String[] args) {// 直接输出: 内部类的静态成员…

python 端口快速扫描

笔记&#xff0c;直接看代码&#xff1a; import socket import threadingdef PortScan(target_ip, start_port40000, end_port65535, num_threads16):open_ports []thread_list []def scan_ports(ip, start, end):local_open_ports []for port in range(start, end 1):tr…

Vscode GDB 查看内存的值

在VSCode的GDB图形界面中&#xff0c;你可以使用"调试控制台(Debug Console)"来查看malloc返回的地址里的值。以下是具体的步骤&#xff1a; 首先&#xff0c;你需要在你的代码中设置一个断点&#xff0c;这个断点应该在malloc函数调用之后&#xff0c;这样你可以获…

JAXB:用XmlElement注解复杂类型的Java属性,来产生多层嵌套的xml元素

例如&#xff0c;下面这段请求的xml代码&#xff0c;在元素body下面又多了一层&#xff0c;嵌套了4个元素&#xff1a; <?xml version"1.0" encoding"UTF-8"?><request><reqtype>04</reqtype><secret>test</secret>…

电机应用开发-编码器的使用

编码器 增量式编码器倍频技术 增量式编码器输出的常见脉冲波形信号形式&#xff1a; 占空比为50%的方波&#xff0c;通道A和通道B相位差为90。 正弦波的模拟信号&#xff0c;通道A和通道B相位差为90。 对于占空比为50%的方波&#xff0c;通道A和通道B相位差为90。先以下图为例…

C++ LibCurl实现Web隐藏目录扫描

LibCurl是一个开源的免费的多协议数据传输开源库&#xff0c;该框架具备跨平台性&#xff0c;开源免费&#xff0c;并提供了包括HTTP、FTP、SMTP、POP3等协议的功能&#xff0c;使用libcurl可以方便地进行网络数据传输操作&#xff0c;如发送HTTP请求、下载文件、发送电子邮件等…

响应体和状态码

后端响应体和状态码设计 主流技术&#xff1a;响应体 和 状态码结合使用 响应体&#xff1a;数据 响应 给前端的 格式 1、为什么要设计统一响应体? 1、系统默认提供许多的状态码&#xff0c;但HTTP的状态码数量有限。 通过修改响应返回的JSON数据&#xff0c;更好的表达业务中…

【docker下安装jenkins】(一)

目的&#xff1a;在Linux操作系统&#xff08;x86_64)下&#xff0c;使用docker部署jenkins&#xff0c;python使用压缩包安装 安装jenkins的步骤 &#xff11;、编排jenkins的docker-compose.yml文件 说明&#xff1a;这里遇到部署jenkins后&#xff0c;占用内存8G,所以重新…

scala解析命令行参数详解

如何用scala解析命令行参数&#xff1a; 首先&#xff0c;需要在项目中添加Apache Commons CLI库的依赖。可以在pom.xml中加&#xff0c; 也可以在build.sbt文件中添加如下行&#xff1a; libraryDependencies "commons-cli" % "commons-cli" % "…

HarmonyOS第一课-对比Kotlin,快速入门TypeScript

编程语言简介 基础类型 1. 布尔值 TypeScript 和 Kotlin: 两者都有 boolean 类型&#xff0c;用于表示 true 或 false。 ts示例&#xff1a; let isDone:boolean falsekotlin示例&#xff1a; val isDone: Boolean false2. 数字 TypeScript: 有 number 类型&#xff0c…

hadoop 配置历史服务器 开启历史服务器查看 hadoop (十)

1. 配置了三台服务器&#xff0c;hadoop22, hadoop23, hadoop24 2. hadoop文件路径: /opt/module/hadoop-3.3.4 3. hadoop22机器配置历史服务器的配置文件&#xff1a; 文件路径&#xff1a;/opt/module/hadoop-3.3.4/etc/hadoop 文件名称&#xff1a;mapred-size.xml 新增历…

帮我想几个关于实人认证API的中文文章标题

引言 随着信息时代的迅速发展&#xff0c;数据变得愈加庞大和复杂。在这个大数据的时代&#xff0c;企业面临着海量信息的管理和利用挑战。为了更有效地获取并利用数据&#xff0c;企业信息模糊搜索API成为了企业数据智能引擎的一部分&#xff0c;为企业提供了精准的企业列表检…

RK3588产测软件介绍

1. 简介 本公司研发的产测软件是用于在量产的过程中快速地甄别产品功能和器件的好坏&#xff0c;即重点 FCT&#xff08;Functional Test&#xff09;测试&#xff0c;进而提高生产效率和检测的准确性。 2. 产测软件介绍 QT开发的ARM平台产测图形化软件&#xff0c;一键开启傻…

【问题处理】WPS提示不能启动此对象的源应用程序如何处理?

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 最近在用WPS打开word文件中&#xff0c;插入的Excel附件时&#xff0c;无法打开&#xff0c;提示&#xff1a;“不能启动此对象的源应用程序”。 经过上网查找处理办法&#xff0c;尝试解决&#xff0c;现将解决过程记…

前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 系列文章目录

系列文章目录 第一章 技术栈简介 (开篇) 第二章 环境部署 (Node等环境安装) 第三章 项目创建 (Vite项目初始化) 第四章 认识项目目录 第五章 Element-Plus组件库安装和使用 第六章 样式格式化 (Sass) 第七章 路由配置 (vue-router路由守卫) 第八章 请求配置 (Axios请求和响应拦…

大模型LLM 在线量化;GPTQ\AWQ量化及推理

1、大模型LLM 在线量化 参考:https://www.cnblogs.com/bruceleely/p/17348782.html ##8bit model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).quantize(8).half(

HDR相关文章收集

一文分清HDR10/HDR10/Dolby Vision 什么是4K HDR&#xff1f;HDR10、HDR10 PRO、杜比视界HDR区别 HDR中显示器标准和视频编码标准 芯片支持HDR解码 HDR详解 HDR技术趋势浅析 BT.2100 HDR 基本规范 图形图像基础知识&#xff08;5&#xff09;---- HDR 基本概念

Linux socket编程(4):服务端fork之僵尸进程的处理

在上一节利用fork实现服务端与多个客户端建立连接中&#xff0c;我们使用fork函数来实现服务端既可以accept新的客户端连接请求&#xff0c;又可以接收已连接上的客户端发来的消息。但在Linux中&#xff0c;在子进程终止后&#xff0c;父进程需要处理该子进程的终止状态&#x…