【汇编】#6 80x86指令系统其二(串处理与控制转移与子函数)

2024-04-28 20:44

本文主要是介绍【汇编】#6 80x86指令系统其二(串处理与控制转移与子函数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、串处理指令
    • 1. 与 REP 协作的 MOVS / STOS / LODS的指令
      • 1.1 重复前缀指令REP
      • 1.2 字符串传送指令(Move String Instruction)
      • 1.2 存串指令(Store String Instruction)
      • 1.3 取字符串指令(Load String Instruction)
    • 2. 与 REPE(REPNE)配合工作的CMPS 和 SCAS指令
      • 2.1 相等重复前缀指令 REPE/REPZ
      • 2.2 串比较指令 CMPS
      • 2.3 串搜索指令 SCAS
    • 3. 串输入输出指令 INS/OUTS
  • 二、转移指令
    • 1. 无条件转移指令JMP
    • 2. 条件转移指令
  • 三、循环指令
    • 1. 循环指令 LOOP
    • 2. (不)相等/(不)为零循环指令 LOOP(N)E/LOOP(BN)Z
  • 四、子程序
    • 1. 子程序调用CALL
      • 1.1 段内直接调用
      • 1.2 段内间接调用
      • 1.3 段间直接调用
      • 1.4 段间间接调用
    • 2. 返回指令RET


一、串处理指令

字符串操作指令的实质是对一片连续存储单元进行处理,这 片存储单元是由隐含指针DS:SIES:DI来指定的。

字符串操作指令可对内存单元按字节或字进行处理,并能根据操作对象的字节数使变址寄存器SI(和DI)增减1或2。具体规定如下:(DF控制方向)

  • 当DF=0时,变址寄存器SI(和DI)增加1或2;
  • 当DF=1时,变址寄存器SI(和DI)减少1或2。

1. 与 REP 协作的 MOVS / STOS / LODS的指令

1.1 重复前缀指令REP

重复前缀指令是重复其后的字符串操作指令,重复的次数由 CX来决定

其一般格式为:
REP MOVS / STOS / LODS
每一次循环CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,CX=0时,停止循环。

1.2 字符串传送指令(Move String Instruction)

功能:将以SI为指针的源串中的一个字节(或字)存储单元中 的数据传送至以DI为指针的目的地址中去,并自动修改指针,
使之指向下一个字节(或字)存储单元

REP MOVS:将数据段中的整串数据传送到附加段中。

  • (DS:[SI])→ES:[DI]。
  • 当DF=0时,(SI)和(DI)增量;当DF=1时,(SI)和(DI)减量。
  • 指令的格式:
    MOVS DST,SRC (需在操作数中表明数据格式)
    MOVSB (字节)
    MOVSW (字)
  • 执行 REP MOVS 之前,应先做好:
    • 源串首地址(末地址)→ SI
    • 目的串首地址(末地址)→ DI
    • 串长度 → CX
    • 建立方向标志

1.2 存串指令(Store String Instruction)

功能:将AL或AX中的数据送入ES:DI所指的目的串中的字节(或 字)存储单元中。

  • 字节操作:(AL)→[DI],字操作:(AX)→[DI]。
  • 修改指针DI,使之指向串中的下一个元素。
    当DF=0时,(DI)增量)。当DF=1时,(DI)减量。
  • 指令的格式:
    STOS DST (需在操作数中表明数据格式)
    STOSB (字节)
    STOSW (字)

1.3 取字符串指令(Load String Instruction)

功能:将SI所指的源串中的一个字节(或字)存储单元中的数据取出来送入**AL(或AX)**中。

  • 字节操作:([SI])→AL,字操作:([SI])→AX。
  • 修改指针SI,使它指向串中的下一个元素。
    当DF=0时,(SI)增量。当DF=1时,(SI)减量。
  • 指令的格式:
    LODS SR(需在操作数中表明数据格式)
    LODSB (字节)
    LODSW (字)

2. 与 REPE(REPNE)配合工作的CMPS 和 SCAS指令

2.1 相等重复前缀指令 REPE/REPZ

一般格式为:
REPE/REPZ CMPS/SCAS

  • 判断条件:CX≠0 且 ZF=1;(CX=0或ZF=0则退出)若条件不成立,则结束重复操作,执行程序中的下一条指令;
  • 条件成立时,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,继续对循环条件进行判断。

存在相反指令REPNE/REPNZ,条件判断CX与上相同,ZF与上相反

2.2 串比较指令 CMPS

SI所指的源串中的一个字节(或字)存储单元中的数据与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存。

  • ([SI])-([DI])
  • 修改串指针,使之指向串中的下一个
    元素。当DF=0时,(SI)和(DI)增量。当DF=1时,(SI)和(DI)减量。
  • 格式:
    • CMPSB 字节串比较
    • CMPSW 字串比较

2.3 串搜索指令 SCAS

AL(字节)或AX(字)中的内容与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,根据相减结果设置标志位,结果不保存

  • 字节操作:(AL)-([DI]);字操作:(AX)-([DI])
  • 修改指针使之指向串中的下一个元素。当DF=0时,(DI)增量。当DF=1时,(DI)减量。
  • 格式:
    • SCASB 字节串搜索
    • SCASW 字串搜索

3. 串输入输出指令 INS/OUTS

INS:
将由DX寄存器指定的I/O端口中的字、字节传送到附加段中的目的串中,并根据DF和数据类型来改变目的变址寄存器的方向内容

格式:

  • INSB 字节串输入: ES:[DI] ←((DX)),
    DI←DI±1
  • INSW 字串输入: ES:[DI] ← ((DX)),
    DI←DI±2

OUTS:
将由源串中的字、字节传送到在DX寄存器指定的
I/O端口中,并根据DF和数据类型来改变源变址寄存器的
方向内容

格式:

  • OUTSB 字节串输出: ((DX))←DS:[SI]
    SI←SI±1
  • OUTSW 字串输出: ((DX))←DS:[SI]
    SI←SI±2

二、转移指令

转移指令分无条件转移指令有条件转移指令两大类。

  • 无条件转移指令包括:JMP、子程序的调用和返回指令、中断的调用和返回指令等。
  • 条件转移指令又分三大类:
    • 基于无符号数的条件转移指令
    • 基于有符号数的条件转移指令
    • 基于特殊算术标志位的条件转移指令

1. 无条件转移指令JMP

  • 段内直接短转移:JMP (SHORT) OPR
    (IP)← (IP)+ 8位位移量
  • 段内直接近转移:JMP (NEAR PTR) OPR
    (IP)← (IP)+ 16位位移量

位移量是紧接着JMP指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移。向地址增大方向转移时,位移量为正;反之位移量为负。

  • 段内间接转移: JMP (WORD PTR) OPR
    (IP)← (EA)

将一个寄存器或主存字单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容

  • 段间直接远转移:JMP (FAR PTR) OPR
    (IP)← OPR 的段内偏移地址
    (CS)← OPR 所在段的段地址

将标号所在段的段地址作为新的CS值,标号在该段内的偏移地址作为新的IP值;程序跳转到新的代码段执行

  • 段间间接转移: JMP (DWORD PTR) OPR
    (IP)← (EA)
    (CS)← (EA+2)

用一个存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的字单元中的,低位字送IP寄存器,高位字送CS寄存器


2. 条件转移指令

条件转移指令是一组极其重要的转移指令,它根据标志寄存器中的一个(或多个)标志位来决定是否需要转移,这就为实现多功能程序提供了必要的手段

  • 基本格式:

    • JXX LABEL条件满足,发生转移:IP←IP+位移量
      条件不满足,顺序执行指令
    • 操作数LABEL是采用短转移,称为相对寻址方式
  • 单个条件标志的设置情况转移
    在这里插入图片描述

  • 无符号数的条件转移指令
    在这里插入图片描述

  • 有符号数的条件转移指令
    在这里插入图片描述

  • 测试CX的值为0则转移指令

    • 条件转移指令中还有一条较特殊的指令,因为CX寄存器通常在程序中用做计数器,JCXZ指令就可以用来判断计数是否为0
    • 格式 :JCXZ LABEL CX=0,发生转移:IP←IP+位移量;CX≠0,顺序执行下一指令

三、循环指令

1. 循环指令 LOOP

如果(CX)≠0,转向“标号”所指向的指令,否则,终止循环,执行该指令下面的指令。

语句格式: LOOP 标号

使用LOOP指令可代替两条指令:
    DEC CX
    JNE 标号
转向的范围为-128~+127字节

2. (不)相等/(不)为零循环指令 LOOP(N)E/LOOP(BN)Z

  • 对于LOOPE/LOOPZ:
    • 语句格式: LOOPE/ LOOPZ 短标号
    • 每次循环(CX)=(CX)-1(不改变任何标志位)
      如果CX≠0且ZF=1,则程序转到循环
      体的第一条指令,否则,程序将执行该循
      环指令下面的指令。
  • 对于LOOP(N)E/LOOP(BN)Z:
    • 使用方法相同,判断条件中的ZF条件相反

四、子程序

子程序是完成特定功能的一段程序。如果某程序段在源程序内反复出现,就可把该程序段定义为子程序。这样可以缩短源程序长度、节省目标程序的存储空间,也可提高程序的可维护性和共享性。

1. 子程序调用CALL

类似但不同于JMP指令,CALL指令需要保存返回地址(调用函数时将下一指令的地址压栈)

  • 段内调用——入栈偏移地址IP:
    SP←SP-2,SS:SP←IP
  • 段间调用——入栈偏移地址IP和段地址CS:
    SP←SP-2,SS:SP←IP;
    SP←SP-2,SS:SP←CS。

1.1 段内直接调用

  • 格式:CALL DST
  • 实际步骤:
    • 将子程序的返回地址存入堆栈,以便子程序返回使用。即: (SP)←SP - 2;(SP)+1,(SP)←IP
    • 转移到子程序入口地址去继续执行子程序。指令中的DST在汇编格式指令作为子程序入口地址的符号地址(标号)。在8086机器语言中,它是一个16位的偏移量。即: (IP)←IP+ D16

在这里插入图片描述

1.2 段内间接调用

  • 格式:CALL DST
  • 主要区别是子程序的入口地址DST的寻址方式不同而已。它可以是寄存器操作数和各种寻址方式的存储器操作数,当然不允许是立即数和段寄存器操作数。
    • 例如:
      CALL BX ;BX的内容是子程序的偏移量
      CALL word ptr [BX] ;BX所指内存字单元的值是子程序的偏移量

1.3 段间直接调用

  • 格式:CALL DST
  • 执行操作:
    • SP←SP - 2;
    • (SP)+1,(SP)←CS ;
    • SP←SP - 2;
    • (SP)+1,(SP)←IP ;
    • IP ←偏移地址(指令的第2、3字节);
    • CS ←段地址(指令的第4、5字节);
      在这里插入图片描述

1.4 段间间接调用

  • 格式:CALL DST
  • 执行操作:
    • SP←SP - 2;
    • (SP)+1,(SP)←CS ;
    • SP←SP - 2;
    • (SP)+1,(SP)←IP ;
    • IP ←(EA);
    • CS ←(EA+2);
  • 主要区别是子程序的入口地址DST的寻址方式不同而已。它可以是寄存器操作数和各种寻址方式的存储器操作数,也即由各种寻址方式形成的有效地址EA和EA+1两个单元内容送入IP,EA+2和EA+3两个单元内容送入CS。
    • 例如:
      CALL DWORD PTR [BX];BX所指内存双字单元的值是子程序的偏移量和段值

2. 返回指令RET

  • 段内近返回:RET
    实际操作: (IP )← (SP)+1,(SP)
    (SP)← SP + 2
  • 段内带立即数近返回:RET EXP
    RET 可以带有一个立即数 , 堆栈指针 SP 将增加 , 即
    SP←SP+EXP。这个特点使得程序可以方便地废除若干执行CALL指令以前入栈参数。
  • 段间远返回:RET
    实际操作:(IP) ← (SP)+1,(SP)
    (SP)←(SP) + 2
    (CS)← (SP)+1,(SP)
    (SP)←(SP) + 2
  • 段间带立即数远返回:RET EXP(同段内带立即数返回)

这篇关于【汇编】#6 80x86指令系统其二(串处理与控制转移与子函数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/944220

相关文章

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont