汇编语言数据传送指令之堆栈操作指令

  • 堆栈操作指令

处理器通常用硬件支持堆栈 (Stack) 数据结构, 它是一个按“先进后出” (First In LastOut, FILO) 存取原则组织的存储区域, 也可以说是 “后进先出” (Last In First Out, LIFO) 存取原则。 堆栈具有两种基本操作, 对应两条基本指令: 数据压进堆栈操作对应进栈指令PUSH; 数据弹出堆栈操作对应出栈指令 POP。
IA-32处理器的堆栈建立在主存区域中, 使用SS段寄存器指向段基地址。 堆栈段的范围由堆栈指针寄存器 ESP 的初值确定, 这个位置就是堆栈底部 (不再变化)。 堆栈只有一个数据出人口, 即当前栈顶 (不断变化), 由堆栈指针寄存器ESP 的当前值指定栈顶的偏移地址, 随着数据进人堆栈, ESP逐渐减小; 而随着数据依次弹出堆栈,ESP逐渐增大。 随着ESP增大, 弹出的数据不再属于当前堆栈区域, 随后进入堆栈的数据也会占用这个存储空间。 当然, 如果进人堆栈的数据超出了设置的堆栈范围, 或者已无数据可以弹出 (即 ESP增大到栈底), 就会产生堆栈溢出错误。 堆栈溢出, 轻者使程序出错,重者会导致系统崩溃。
IA-32处理器的堆栈是“向下生长的”,也就是说随着数据进栈,ESP指针会逐渐减小

  1. 1、 进栈指针PUSH

进栈指令PUSH先将ESP减小作为当前栈顶,然后可以将立即数,通用寄存器和段寄存器或存储器操作数传送到当前栈顶,由于目的位置是栈顶,所以由 ESP确定push只表达源操作数。 格式是:
PUSHr16/m16/i16/seg:ESP=ESP-2,SS[ESP]=r16/m16/i16/seg
PUSH r32/m32/i32:ESP=ESP-4,SS:[ESP]=r32/m32/i32
IA-32处理器的堆栈只能以字或双字为单位操作. 字量效据进栈时, ESP 向低地址移动两个字节单元指向当前栈顶,双字数据进栈,ESP减4即准备4个字节数据以 “低对低, 高对高” 的小端方式存放到堆栈顶部

  1. 2、 出栈指令POP

出栈指令POP执行与进栈指令相反的功能, 它先将栈顶数据传送到通用寄存器、 存储单元或段寄存器中, 然后ESP增加作为当前栈顶。 由于源操作数在栈顶, 且由 ESP确定, 所以POP指令只表达目的操作数。格式是:
POP r16/m16/seg;D r16/m16/seg=ss:[ESP],2ESP=ESP+2
POP r32/m32/r32/m32=SS:[ESP],2)ESP=ESP+4
字量数据出栈时, ESP 向高地址移动2个字节单元 (即加2)。 双字量数据出栈时, ESP加4。 然后, 数据以 “低对低、 高对高” 原则从栈顶传送到目的位置,
POP指令相当于一条传送指令MOV加上一条对ESP的加法指令ADD

  • 其他传送指令

指令系统中还有一些针对特定需要设计的专用传送指令。

地址传送指令

存储器操作数具有地址属性, 利用地址传送指令可以获取其地址。 其中, 最常用的是获取有效地址指令LEA (Load Effective Address), 格式如下:
LEA r16/r32,mem ;r16/r32 =mem的有效地址EA(不需要类型一致)
LEA指令将存储器操作数的有效地址 (段内偏移地址)传送至16位或32位通用器中它的作用等同于汇编程序 MASM 的地址操作符OFFSET。 但是,LEA指令是在指令执行时计算出的偏移地址, 而OFFSET 操作符是在汇编阶段取得变量的偏移地址,(后者执行速度更快。 不过, 对于在汇编阶段无法确定的偏移地址, 就只能利用LEA指令获取了。
IA-32 处理器指令系统还有指针传送指令LDS, LES, LFS, LGS 和LSS, 它们能将主存连续4个或6个字节内容的前两个依次传送给DS, ES,FS, GS和SS, 后续字节作为偏移地址传送给指令的16位或32位通用寄存器。 另外,MOV指令还可以支持对控制寄存器等系统专用寄存器的数据传送, 不过它们通常不能在应用程序中使用。

  1. 2.换码指令

数据表是常见的数据结构, 编程中经常需要获得数据表中的某个特定数据项, 处理器为此专门设计了换码指令。 换码指令XLAT (Translate) 是一条比较复杂的指令, 但格式却非常简单,
如下所示:
XLAT;AL<-[EBX+AL]
使用XLAT指令前, 需要将EBX指向主存缓冲区 (即数据表首地址) 并给AL赋值距离缓冲区开始的位移量 (即表中数据项的位置), 执行的功能是将缓冲区该位移量位置的数据取出给AL, 可以表达为 “AL<-[EBX+AL]” 由于XLAT指令隐含使用EBX和AL, 所以其助记符后无须写出操作数, 默认该缓冲区在DS数据段; 如果设置的缓冲区在其他段, 则需要写明缓冲区的变量名, 汇编程序就会加上必要的段超越前缀, 也可以在变量名前加上段超越前缀。

标志传送指令

IA-32处理器有可以直接改变CF, DF、 IF标志状态的标志位操作指令, 还有针对标志寄存器低8位,低16位和全部32位传送的指令
《汇编语言数据传送指令之堆栈操作指令》

    原文作者:为祖国健康工作60年
    原文地址: https://blog.csdn.net/Clown_pan/article/details/85049250
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞