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

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

前言


在汇编语言的世界中,转移指令扮演着连接程序执行流程的重要角色。除了之前提到的 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 构成了汇编语言中转移操作的基础。这些指令的灵活运用使得程序员能够编写出结构清晰、模块化的代码,提高了代码的可读性和可维护性。深入理解和熟练运用这些转移指令,是汇编语言编程中的重要一环。

相关文章
|
4月前
|
存储 程序员
【汇编】“转移”综述、操作符offset、jmp指令
【汇编】“转移”综述、操作符offset、jmp指令
109 1
|
4月前
汇编指令学习(寻址方式)
汇编指令学习(寻址方式)
20 0
|
4月前
汇编指令学习(LOOP)
汇编指令学习(LOOP)
17 0
|
4月前
汇编指令学习(CALL,JMP,RET)
汇编指令学习(CALL,JMP,RET)
26 0
|
4月前
|
JavaScript
汇编指令学习(JMP、JE、JS、JP,JO,JB)
汇编指令学习(JMP、JE、JS、JP,JO,JB)
133 0
|
4月前
汇编指令学习(CMP,TEST)
汇编指令学习(CMP,TEST)
24 0
|
4月前
汇编指令学习(AND,OR,XOR,NOT)
汇编指令学习(AND,OR,XOR,NOT)
37 0
|
4月前
汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
28 0
|
4月前
汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)
汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)
33 0
|
4月前
|
存储
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间