【x86汇编】第四章:程序设计的基本方法

顺序结构

  • 程序无分支、无循环、无转移, 以直线方式一条指令接着一条指令顺序执行

分支结构

  • 运行时, 让机器根据不同情况自动做出判断, 有选择地执行相应的处理程序
  • 一般根据标志寄存器的某些位作为判断条件

转移指令

  • 转移指令可以改变程序的执行顺序(也就是改变CS:EIP/IP指针的值)
  • 转移指令不改变标志寄存器的值

条件转移

调用格式:操作符 标号

如果满足条件,则转移,否则继续执行
分支条件转移特别需要注意以下几点

  • 选择合适的转移指令,注意有无符号的区别
  • 为每个分支安排好出口
  • 把公共部分尽量放到公共段中

简单条件转移

指令名称 助记符 转移条件 功能说明
相等/等于0转 JE/JZ ZF=1 前次操作结果是否相等或等于0
不相等/不等于0转 JNE/JNZ ZF=0 前次操作结果是否不相等或不等于0
为负转 JS SF=1 前次操作结果是否为负
为正转 JNS SF=0 前次操作结果是否为正
溢出转 JO OF=1 前次操作结果是否溢出
未溢出转 JNO OF=0 前次操作结果是否未溢出
进位位为1转 JC CF=1 前次操作结果是否有进位或借位
进位位为0转 JNC CF=0 前次操作结果是否无进位或借位
偶转移 JP/JPE PF=1 前次操作结果中1的个数是否为偶数
奇转移 JNP/JPO PF=0 前次操作结果中1的个数是否为奇数

无符号数

无符号数的运算结果有三种情况

  • 结果为正:大数-小数,结果为正,无溢出无进位
  • 结果为0
  • 结果为负:小数-大数,结果为负,高位变成1,产生进位

JA / JNBE

  • 大于(above)转移,比较两个无符号数,a>b,则转移
  • 条件:CF=0且ZF=0(未进位或借位,运算结果不为0)

JAE / JNB

  • 大于等于(above equ)转移,比较两个无符号数,a>=b,则转移
  • 条件:CF=0或ZF=1(未进位或借位,或者运算结果为0)

JB / JNAE

  • 小于(below)转移,比较两个无符号数,a>b,则转移
  • 条件:CF=1且ZF=0(产生了进位或借位,运算结果不为0)

JBE / JNA

  • 小于等于(below equ)转移,比较两个无符号数,a>b,则转移
  • 条件:CF=1或ZF=1(产生了进位或借位,或者运算结果为0)

有符号数

有符号数的结果比较复杂,分为下面四种

  • 不进位,不溢出
  • 不进位,溢出
  • 进位,不溢出
  • 进位,溢出

溢出的情况分两种:

  • 负数 - 负数 = 正数
  • 正数 + 正数 = 负数

JG / JNLE

  • 大于(greater)转移,比较两个有符号数,a>b,则转移
  • 条件:SF=OF且ZF=0

JGE / JNL

  • 大于等于(greater equ)转移,比较两个有符号数,a>=b,则转移
  • 条件:SF=OF或ZF=0

JL / JNGE

  • 小于(less)转移,比较两个有符号数,a>b,则转移
  • 条件:SF≠OF且ZF=0

JLE / JNG

  • 小于等于(less equ)转移,比较两个有符号数,a>b,则转移
  • 条件:SF≠OF或ZF=0

无条件转移

无条件转移指令使CPU无条件地转移到指令指明的目的地址处执行,包括JMP、CALL、RET、INT和IRET

  • 段内转移:转移指令和目的地址在同一段,只改变EIP
  • 段间转移:转移指令和目的地址在不同段,改变EIP,同时改变CS寄存器

JMP有直接和间接寻址两种方式

循环结构

按照一定规律, 多次重复执行一串语句

循环程序的结构

循环程序一般由以下 4 部分组成

  • 初值部分:退出条件初值,循环内容初值
  • 重复执行部分:重复执行某些操作
  • 变量部分:利用变量的增或减,按顺序访问存储器
  • 退出条件部分:达到条件时退出循环

循环控制方法

计数控制法

用于循环次数已知的情况,有4种控制循环的指令

一般循环转移指令

LOOP 标号

功能:ECX/CX先减一,然后判断,不为0则跳转到标号处

等于或0循环转移指令

LOOPE/LOOPZ 标号

功能:ECX/CX先减一,然后判断,不为0,并且ZF=1,则跳转到标号处

不等于或0循环转移指令

LOOP 标号

功能:ECX/CX先减一,然后判断,不为0,并且ZF=0,则跳转到标号处

跳转指令

JCXZ/JECXZ 标号

功能:当寄存器ECX/CX的值为0时,跳转到标号
该指令警经常放在循环前,用于跳过循环体

条件控制法

循环次数不确定,但是可以由某些条件确定

子程序设计

子程序的概念

将重复的或者经常用到的功能设计成可供反复调用的独立程序段,在需要的时候调用

子程序的定义

子程序名 PROC NEAR/FAR

子程序名 ENDP

如果主程序与子程序在相同段,则定义为NEAR,NEAR可省略,否则定义为FAR

子程序的调用与返回

调用指令CALL

段内直接调用

CALL 过程名

  • EIP/IP入栈
  • 目的地址 -> EIP/IP

段间直接调用

CALL FAR PTR 过程名

  • CS入栈,目的段首址 -> CS
  • EIP/IP入栈,目的地址 -> EIP/IP

段内间接调用

CALL WORD/DWORD PTR OPD

  • EIP/IP入栈
  • OPD -> EIP/IP

段间间接调用

CALL DWORD/FWORD PTR OPD

  • CS入栈,( OPD + 2/4 ) -> CS
  • EIP/IP入栈,OPD -> EIP/IP

返回指令RET

RET

  • EIP/IP出栈
  • 如果是段间调用,CS出栈

RET n

  • 作用同上,特殊之处在于,在上述操作之后,废除栈顶n/2或者n/4个无用的参数
  • 当利用堆栈法传递参数时,常用此法回收空间
  • CALL指令和RET指令均不影响标志位

子程序现场保护方法

  • 保护现场的工作,一般是在子程序中完成
  • 在子程序开始处保护现场PUSH,在退出时恢复现场POP
  • 栈中保存,先进后出

传递参数的方式

概念:主程序准备入口参数,子程序提供出口结果,这个过程称为参数传递

寄存器法

速度快,但是寄存器个数有限

约定单元法

  • 把入口参数和出口参数都放到事先约定好的内存单元中
  • 优点是不易出错,缺点是占用内存空间

堆栈法

  • 通过堆栈传递参数
  • 优点是不占用寄存器,不占用内存空间,灵活性强
  • 缺点是存取参数时要计算堆栈地址,不能有差错

程序设计注意事项

目标:

  • 首先保证正确性
  • 使程序结构合理,简洁明了,容易阅读和交流
  • 便于使用和扩充,能节省存储空间,提高运行速度

方法:

  • 依操作数的多少,值的大小,正确分配数据存储区
  • 选择合适的指令和寻址方式
  • 选择合适的寻址方式
  • 选用效率高的指令
  • 不要插入不必要的语句
  • 合理安排寄存器的使用

猜你喜欢

转载自blog.csdn.net/whitefish520/article/details/105599068
今日推荐